一、过程
在对接第三的接口使,发现对方使用的json是net.sf.json.JSONObject。接口在返回值的时候就没有对其进行处理,直接返回了但是,后台也不报错,后端也没有收到响应值,只显示500的报错状态码。仔仔细细的看后台的日志发现:
2024-03-28 10:57:14.514 WARN 34128 --- [nio-8022-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver :
Resolved [org.springframework.http.converter.HttpMessageNotWritableException:
Could not write JSON: Object is null; nested exception is
com.fasterxml.jackson.databind.JsonMappingException:
Object is null (through reference chain: com.at21.sign2.util.ResultUtils["data"]-
>net.sf.json.JSONObject["dd"]->net.sf.json.JSONArray[1]->net.sf.json.JSONNull["empty"])]
这尼玛,报错就好好报错,你打个warn 是什么鬼,就不会error么!!!屮
二、复现bug
接口的部分代码
@RequestMapping("test")
public Object test() {
JSONArray ja = new JSONArray();
ja.add("aaa");
ja.add(null);
JSONObject js = new JSONObject();
js.put("aa", 141);
js.put("bb", null);
js.put("cc", "");
js.put("dd", ja);
System.out.println(js.toString());
return ResultUtils.success(js);
}
打印的json数据是: {"aa":141,"cc":"","dd":["aaa",null]}
问题1:bb是null,你™的吃了啊!!
问题2:数组里面有null spring boot响应就直接500了
三、解决
方法1:遍历去除数组中的null
JSONObject json2 = new JSONObject();
JSONObject xxxxxx = (JSONObject) json.get("xxxxxx");
Iterator<Map.Entry<String, Object>> it = xxxxxx.entrySet().iterator();
while (it.hasNext()){
Map.Entry<String, Object> next = it.next();
if(!(next.getValue() instanceof JSONNull)) {
json2.put(next.getKey(),next.getValue());
}
}
json.put("xxxxxx", json2);
方法2:配置spring boot 的json格式的序列化
@Bean
public ObjectMapper objectMapper(){
return new ObjectMapper().setSerializationInclusion(JsonInclude.Include.NON_NULL);
}
方法3:不要使用 net.sf.json.JSONObject (垃圾)
建议使用阿里的 com.alibaba.fastjson.JSONObject
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>