在項目開發過程中,遇到如下問題,具體表現現象,調用接口查詢第一頁不報錯,第二頁就報錯,詳見報錯信息:
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值,去除掉就好。