在Java項(xiàng)目中經(jīng)常能看到fastjson和jackson這兩個(gè)庫同時(shí)出現(xiàn),因?yàn)閟pring mvc默認(rèn)使用jackson作為restful接口的序列化和反序列化庫锰瘸,在restful接口、feign調(diào)用中不可避免在框架層面就引入了jackson;而fastjson則提供了很多JSON操作的靜態(tài)方法,很適合日常編碼拿來就用偿衰。
混用兩個(gè)庫大多數(shù)時(shí)候沒什么問題,在少數(shù)情況下,如開發(fā)過程中序列化異常的時(shí)候會(huì)出現(xiàn)兩種風(fēng)格的異常信息下翎,讓人一下子懵圈缤言,這個(gè)問題其實(shí)習(xí)慣了也還好。
但是如果某些dto需要json注解的時(shí)候视事,就需要同時(shí)使用兩套注解來作兼容胆萧,這個(gè)問題會(huì)讓編碼工作更繁瑣,使項(xiàng)目不容易維護(hù)俐东,這是無法接受的跌穗,我們來看一個(gè)例子
在微信網(wǎng)頁授權(quán)登陸的api中使用code換取access_token的返回結(jié)果如下
{
"access_token":"ACCESS_TOKEN",
"expires_in":7200,
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID",
"scope":"SCOPE"
}
這個(gè)返回結(jié)果中,三個(gè)字段使用下劃線分割單詞虏辫,一個(gè)字段忽略了大小寫蚌吸,這種命名方式在我們轉(zhuǎn)成dto類的時(shí)候就需要指定json屬性名以滿足我們對(duì)Java項(xiàng)目的命名規(guī)范。fastjson使用@JSONField實(shí)現(xiàn)砌庄,而jackson則是使用@ JsonProperty注解來實(shí)現(xiàn)羹唠,我們可以看到多了一份注解
@Data
class TokenResp {
@JSONField(name = "access_token")
@JsonProperty("access_token")
private String accessToken;
@JSONField(name = "expires_in")
@JsonProperty("expires_in")
private Integer expiresIn;
@JSONField(name = "refresh_token")
@JsonProperty("refresh_token")
private String refreshToken;
@JSONField(name = "openid")
@JsonProperty("openid")
private String openId;
private String scope;
}
因此使用同一個(gè)庫可以簡化這些代碼,讓項(xiàng)目更好維護(hù)娄昆。推薦使用jackson來作為全項(xiàng)目json序列化的庫肉迫,因?yàn)閟pring全家桶方便的進(jìn)行整合,開箱即用稿黄。
從自動(dòng)配置類MappingJackson2HttpMessageConverterConfiguration的注解 @ConditionalOnBean({ObjectMapper.class})可以看到spring mvc加載的是jackson的ObjectMapper類,因此我們可以在需要使用到j(luò)son庫的地方注入ObjectMapper這個(gè)bean跌造,即可使用到跟spring mvc框架一樣的jackson配置信息杆怕,如:
@Slf4j
@RestController
public class HelloController {
@Autowired
private ObjectMapper objectMapper;
@PostMapping("/hello")
public String hello(@RequestBody HelloReq req) {
log.info("got request data {}", objectMapper.writeValueAsString(req));
return "hello world";
}
}