起因
??寫這篇文章的起因是源于一次前端JavaScript對于Long類型數據處理的精度丟失問題。這個問題導致我在做刪除操作的時候始終無法成功
問題
??很多時候后臺會把主鍵ID
的類型設置成Long
類型,這樣做雖然有很多好處,但是也存在一個問題,如果Long
類型的數據過長的話(比如{id:122000083049775104}
)就會導致前端JavaScript在處理ID
的時候丟失精度,它會將id
處理成122000083049775100
,很明顯,原ID
貌似被四舍五入了一樣。
方案
??既然前端無法精確處理Long
類型數據,那我們可以將Long
類型數據轉換成String
類型后再交給前臺。例如我們將FastJSON
作為默認JSON
工具,根據不同的RESTFUL
實現方式的不同可以分為兩類,基于Jersey
和基于Spring
一、修改Jersey的默認JSON工具
例如我們的User對象中的id
屬性是Long
類型,我們只需要指定id
字段的序列化方式即可
@Data
public class User implements Serializable {
private static final long serialVersionUID = -6308055729212523806L;
// 將Long類型轉換成String,防止前臺出現精度丟失的問題
@JSONField(serializeUsing = ToStringSerializer.class)
@FormParam("id")
private Long id;
/**
* 姓名
*/
@FormParam("name")
private String name;
/**
* 昵稱
*/
@FormParam("nickname")
private String nickname;
...
}
??本以為這樣就可以大功告成,但是事與愿違,前端得到的id
的值還是122000083049775100
。問題的原因是因為雖然我們指定了@JSONField(serializeUsing = ToStringSerializer.class)
,但是這是FastJson
的注解,而我們的RESTFUL
使用的是Jersey
,它默認的JSON
框架的jackson
,并非FastJSON
。有關于Jersey
中JSON
的資料可以點擊這里查看
根據官網的解釋,只需要注冊FastJson
即可。編輯JerseyConfig.java
文件
/**
* Jersey配置類
* @author Walter Wong
*/
@Component
public class JerseyConfig extends ResourceConfig {
/**
* 注冊服務,使其識別JAX-RS注解
*/
public JerseyConfig() {
register(RequestContextFilter.class);
//注冊跨域過濾器
register(CorsFilter.class);
//注冊fastJson作為Json序列化工具
register(FastJsonFeature.class);
...
}
}
二、修改Spring Boot默認的JSON
如果使用的Spring
的REST
實現,我們需要在入口類中做如下改變即可
-
方案一
啟動類繼承WebMvcConfigurerAdapter,覆蓋方法configureMessageConverters
...
@SpringBootApplication
public class UserApplication extends WebMvcConfigurerAdapter{
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
super.configureMessageConverters(converters);
// 初始化轉換器
FastJsonHttpMessageConverter fastConvert = new FastJsonHttpMessageConverter();
// 初始化一個轉換器配置
FastJsonConfig fastJsonConfig = new FastJsonConfig();
fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);
// 將配置設置給轉換器并添加到HttpMessageConverter轉換器列表中
fastConvert.setFastJsonConfig(fastJsonConfig);
converters.add(fastConvert);
}
public static void main(String[] args) {
SpringApplication.run(UserApplication.class, args);
}
}
- 方案二
在啟動類中注入 HttpMessageConverters
...
@SpringBootApplication
public class UserApplication {
/**
* 配置FastJson為Spring Boot默認JSON解析框架
* @return HttpMessageConverters
*/
@Bean
public HttpMessageConverters fastJsonHttpMessageConverters() {
// 1.定義一個converters轉換消息的對象
FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
// 2.添加fastjson的配置信息,比如: 是否需要格式化返回的json數據
FastJsonConfig fastJsonConfig = new FastJsonConfig();
fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);
// 3.在converter中添加配置信息
fastConverter.setFastJsonConfig(fastJsonConfig);
// 4.將converter賦值給HttpMessageConverter
HttpMessageConverter<?> converter = fastConverter;
// 5.返回HttpMessageConverters對象
return new HttpMessageConverters(converter);
}
public static void main(String[] args) {
SpringApplication.run(UserApplication.class, args);
}
}