一:前言
經過測試,Jackson有很多不合人意的地方,因此建議用Fastjson來替換;
二:Jackson的坑
先定義實體類:
@Data @AllArgsConstructor @NoArgsConstructor @Accessors(chain = true) public class MockModel { private String fUid; private String fName; private String fGender; }
坑1:這里我是用lombok的注解來自動生成構造方法和getter、setter;經過測試SpringBoot中默認的Jackson是不支持將JSON字符串序列化為@Data注解的MockModel對象的(沒有手動定義getter和setter);
測試方式@RequestBody MockModel body;然后POST請求體參數就是對應的JSON字符串(完全對應),但是jackson卻無法轉換;(自定義getter和setter方法jackson可以反序列化為MockModel對象,而Fastjson是兩種都可以)
坑2:mapping方法返回MockModel對象,jackson是可以將MockModel對象轉換為JSON字符串,但是屬性名卻轉換的很坑爹,原本我需要的是{"fUid":xxx...}但是經過jackson轉換后key都變成了小寫,即fuid而非fUid;
三:用Fastjson替換Jackson的方式
直接聲明一個Bean即可:(注意,這個並不會覆蓋掉Jackson,只不過添加了一個比默認的更優先的HttpMessageConverter)
@Bean public HttpMessageConverters fastJsonHttpMessageConverters(){ //1.需要定義一個convert轉換消息的對象; FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter(); //2:添加fastJson的配置信息; FastJsonConfig fastJsonConfig = new FastJsonConfig(); /** * TODO 第一個SerializerFeature.PrettyFormat可以省略,畢竟這會造成額外的內存消耗和流量,第二個是用來指定當屬性值為null是是否輸出:pro:null
* SerializerFeature.SkipTransientField */ fastJsonConfig.setSerializerFeatures(SerializerFeature.WriteMapNullValue); //3處理中文亂碼問題 List<MediaType> fastMediaTypes = new ArrayList<>(); fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8); //4.在convert中添加配置信息. fastJsonHttpMessageConverter.setSupportedMediaTypes(fastMediaTypes); fastJsonHttpMessageConverter.setFastJsonConfig(fastJsonConfig); HttpMessageConverter<?> converter = fastJsonHttpMessageConverter; return new HttpMessageConverters(converter); }
測試有沒有替換成可以通過設置SerializerFeature.PrettyFormat來看序列化的JSON字符串的格式就可以看出;
也可以通過下面的寫法來測試(下面的方式將會令序列化為JSON字符串時變成{"f_uid":xx},原本是{"fUid":xx},但是input還是可以兩種都行)
通過這種形式可以實現和某些接口對接JSON參數格式的特殊化,即定義專門和A系統對接的AModel然后用@JSONField(name = "xx_bb"),那么和A系統傳的JSON字符串就會是特殊化的(以來對應的AModel),而其他系統的則還是默認的格式;
@JSONField(name = "f_uid") private String fUid; // TODO Fastjson是直接通過字段來匹配的,因此可以用@Data,沒有getter和setter @JSONField也一樣會生效,如果希望某個字段不要序列化為JSON字符串可以加transient;
Fastjson沒有jackson中的坑1和坑2,且支持將如{"aa_bb":33}轉換為屬性名aaBb為其賦值33(且還支持部分屬性是aa_bb部分卻是uuMm的形式的轉換)
三:JSON格式的一些注意事項
1.key-value的分隔符只能是:號而不能是=號
2.數值字符串可以轉換為數值屬性,數值也可以轉換為字符串屬性(如fUid:33可以轉換為MockModel中String的fUid),至少Fastjson支持;
3.key部分最好都用""包裹,經過測試有一些JSON包是不支持如{fUid:33}的,只支持{"fUid":33}
4.主流的JSON包都支持如{"fName":null}的寫法;
四:其他
SpringBoot里GET方法可以不設置Content-Type(因為都不會用到);但是POST必須設置這個屬性,而且貌似還不能是*/*;xx的類型??,比如上面的json參數就要Content-Type:application/json;charset=utf8(charset可以不要,但是最好寫上)