1. Springboot默認的json解析方案
Springboot中已經集成JackJson
springboot在Controller層加上@RestController注解后,就可以接收、返回 json數據的原因是:
HttpMessageConverter,這是一個消息轉換工具,有兩個功能:
- 將服務端返回的對象序列化成JSON字符串
- 將前端傳來的JSON字符串反序列化為Java對象。
SpringMVC自動配置了JackJson和Gson的HttpMessageConterver,所以如果用的是這兩個json框架,不需要額外配置,只需要把依賴添加上。
JackJson由SpringBoot已經集成了,若想使用Gson,需要將SpringBoot-starer-web中引入的JackJson的依賴排除掉,再引入Gson的依賴
2. 自定義JackJson-httpMessageConverter
- 從JacksonHttpMessageConvertersConfiguration中可以看到,若沒有自己提供MappingJacjson2HttpMessageConverter,則自動注入一個,我們想自己定義一些轉換規則的話,可以自己定義一個Mappingjackson2HttpMessageConverter,如下:
@Configuration
public class JsonConfig {
@Bean
MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter( ) {
MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setDateFormat(new SimpleDateFormat("yyyy/MM/dd"));
mappingJackson2HttpMessageConverter.setObjectMapper(objectMapper);
return mappingJackson2HttpMessageConverter;
}
}
-
除了上面的這種方式,我們能看到主要規定轉換方式的類是ObjectMapper實現的,而ObjcetMapper是在
JackSonAutoConfiger
中注入的,能發現ObjectMapper同MappintJack2HttpMessageConverter一樣,如果沒有自己注入,則自動注入一個。我們也可以通過只實現ObjectMapper的方式,在自定義轉換方法,如下:
@Configuration public class JacksonConfig { @Bean @Primary @ConditionalOnMissingBean(ObjectMapper.class) ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder){ ObjectMapper objectMapper = builder.createXmlMapper(false).build(); objectMapper.setDateFormat(new SimpleDateFormat("yyyy/MM/dd")); return objectMapper; } }
3. 自定義Gson-httpMessageConverter
- 從GsonHttpMessageConvertersConfiguration中可以看到,這里注入了一個GsonHttpMessageConverter,同上面JsckJson一樣,我們有兩種方式自定義轉換方式:
- 通過自定義GsonHttpMessageConverter
- 通過自定義Gson
@Configuration
public class JacksonConfig {
@Bean
GsonHttpMessageConverter gsonHttpMessageConverter(){
GsonHttpMessageConverter converter = new GsonHttpMessageConverter();
converter.setGson(new GonBuilder().setDateFormart("yyyy/MM/dd").create())
return converter;
}
}
@Configuration
public class JacksonConfig {
@Bean
Gson gsonHttpMessageConverter(){
return new GonBuilder().setDateFormart("yyyy/MM/dd").create();
}
}
3. 使用FastJson
如果想使用FastJson的話,需要手動的注入FastJsonHttpMessageConverter
@Configuration
public class JacksonConfig {
@Bean
FastJsonHttpMessageConverter fastJsonHttpMessageConverter(){
FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
FastJsonConfig config = new FastJsonConfig();
config.setDateFormart("yyyy/MM/dd");
converter.setFastJsonConfig(config);
return converter;
}
}
4. 自定義HttpMesageConverter的真實使用場景
在使用雪花算法生成的id的時候發現,后端使用Long類型存儲到前端js接收的時候,因為js使用Number類型接口,Number類型的長度是16位,而雪花算法生成的id是19位,會出現精度損失的問題。
解決方法:
后端的ID(Long) ==> Jackson(Long轉String) ==> 前端使用String類型的ID,前端使用js string精度就不會丟失了。
后端(Long)接收前端數據(String)的時候,不用額外做處理,這是Spring反序列化參數接收默認支持的行為。
/**
* 這里使用的是JackJson,使用其他json框架的,可以以此類推
*/
@Configuration
public class JacksonConfig {
@Bean
@Primary
@ConditionalOnMissingBean(ObjectMapper.class)
public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder)
{
ObjectMapper objectMapper = builder.createXmlMapper(false).build();
// 全局配置序列化返回 JSON 處理
SimpleModule simpleModule = new SimpleModule();
//JSON Long ==> String
simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
objectMapper.registerModule(simpleModule);
return objectMapper;
}
}
實際使用場景引用:https://www.cnblogs.com/zimug/archive/2020/08/25/13557662.html