在项目开发过程中,遇到如下问题,具体表现现象,调用接口查询第一页不报错,第二页就报错,详见报错信息:
org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: Null key for a Map not allowed in JSON (use a converting NullKeySerializer?);
nested exception is com.fasterxml.jackson.databind.JsonMappingException: Null key for a Map not allowed in JSON (use a converting NullKeySerializer?)
(through reference chain: java.util.LinkedHashMap["results"]->java.util.HashMap["rowsList"]->java.util.ArrayList[0]) org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:293) org.springframework.http.converter.AbstractGenericHttpMessageConverter.write(AbstractGenericHttpMessageConverter.java:106) org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:231) org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:174) org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:81) org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:113) org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967) org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901) org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872) javax.servlet.http.HttpServlet.service(HttpServlet.java:644) org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) javax.servlet.http.HttpServlet.service(HttpServlet.java:725) org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291) org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
分析过程:后端代码没有任何错误,数据也都查询得到,但是只要分页就报错。
分析上面的错误,我们发现这是Spring最后将对象json化的时候报错,这是第一步,发现Could not write JSON: Null key for a Map not allowed in JSON
大概意思就是说map中有null的key值存在,不能json化,但是我能确认肯定没有这样的key值存在,然后一步步排查,发现了罪魁祸首,查询的结果多了【ROWNUM_】这样一个字段。
而这个字段在我们自己的处理中没有映射(数据库查询到的是英文,业务需求返回中文,做了一个方法来映射),最后返回了null,导致了错误。
我们继续分析为什么出现了这个字段,原来在使用Query的setFirstResult,setMaxResults作为分页的时候,会自动生成一个ROWNUM_,自此所有分析结束。
导致这个错误的原因就是:我们需要json化的map中存在null。
解决方法:排查在哪个过程存入的key值,去除掉就好。