一、过程
在对接第三的接口使,发现对方使用的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>