JAVA——json序列化错误[hibernateLazyInitializer,handler,fieldHandler]解决方案
問題描述
?(to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: com.zstu.metrocity.entity.User_$$_jvstba5_0["handler"])
或者?
(to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: com.example.demo.Boy$HibernateProxy$CfQZBtEe["hibernateLazyInitializer"])?
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class org.apache.ibatis.executor.loader.javassist.JavassistProxyFactory$EnhancedResultObjectProxyImpl and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: com.zstu.metrocity.entity.User_$$_jvstba5_0["handler"])at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77) ~[jackson-databind-2.10.2.jar:2.10.2]at com.fasterxml.jackson.databind.SerializerProvider.reportBadDefinition(SerializerProvider.java:1191) ~[jackson-databind-2.10.2.jar:2.10.2]at com.fasterxml.jackson.databind.DatabindContext.reportBadDefinition(DatabindContext.java:404) ~[jackson-databind-2.10.2.jar:2.10.2]at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.failForEmpty(UnknownSerializer.java:71) ~[jackson-databind-2.10.2.jar:2.10.2]at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.serialize(UnknownSerializer.java:33) ~[jackson-databind-2.10.2.jar:2.10.2]at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:727) ~[jackson-databind-2.10.2.jar:2.10.2]at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:722) ~[jackson-databind-2.10.2.jar:2.10.2]at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:166) ~[jackson-databind-2.10.2.jar:2.10.2]at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480) ~[jackson-databind-2.10.2.jar:2.10.2]at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319) ~[jackson-databind-2.10.2.jar:2.10.2]at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1433) ~[jackson-databind-2.10.2.jar:2.10.2]at com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:921) ~[jackson-databind-2.10.2.jar:2.10.2]at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:287) ~[spring-web-5.2.3.RELEASE.jar:5.2.3.RELEASE]at org.springframework.http.converter.AbstractGenericHttpMessageConverter.write(AbstractGenericHttpMessageConverter.java:104) ~[spring-web-5.2.3.RELEASE.jar:5.2.3.RELEASE]at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:295) ~[spring-webmvc-5.2.3.RELEASE.jar:5.2.3.RELEASE]at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:181) ~[spring-webmvc-5.2.3.RELEASE.jar:5.2.3.RELEASE]at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:82) ~[spring-web-5.2.3.RELEASE.jar:5.2.3.RELEASE]at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:124) ~[spring-webmvc-5.2.3.RELEASE.jar:5.2.3.RELEASE]at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:888) ~[spring-webmvc-5.2.3.RELEASE.jar:5.2.3.RELEASE]at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793) ~[spring-webmvc-5.2.3.RELEASE.jar:5.2.3.RELEASE]at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.2.3.RELEASE.jar:5.2.3.RELEASE]at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) ~[spring-webmvc-5.2.3.RELEASE.jar:5.2.3.RELEASE]at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc-5.2.3.RELEASE.jar:5.2.3.RELEASE]at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.2.3.RELEASE.jar:5.2.3.RELEASE]at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.2.3.RELEASE.jar:5.2.3.RELEASE]at javax.servlet.http.HttpServlet.service(HttpServlet.java:634) ~[tomcat-embed-core-9.0.30.jar:9.0.30]at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.2.3.RELEASE.jar:5.2.3.RELEASE]at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) ~[tomcat-embed-core-9.0.30.jar:9.0.30]at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.30.jar:9.0.30]at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.30.jar:9.0.30]at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.30.jar:9.0.30]at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.30.jar:9.0.30]at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.30.jar:9.0.30]at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.2.3.RELEASE.jar:5.2.3.RELEASE]at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.3.RELEASE.jar:5.2.3.RELEASE]at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.30.jar:9.0.30]at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.30.jar:9.0.30]at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.30.jar:9.0.30]at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-9.0.30.jar:9.0.30]at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) [tomcat-embed-core-9.0.30.jar:9.0.30]at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) [tomcat-embed-core-9.0.30.jar:9.0.30]at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [tomcat-embed-core-9.0.30.jar:9.0.30]at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) [tomcat-embed-core-9.0.30.jar:9.0.30]at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [tomcat-embed-core-9.0.30.jar:9.0.30]at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:367) [tomcat-embed-core-9.0.30.jar:9.0.30]at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) [tomcat-embed-core-9.0.30.jar:9.0.30]at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:860) [tomcat-embed-core-9.0.30.jar:9.0.30]at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1598) [tomcat-embed-core-9.0.30.jar:9.0.30]at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.30.jar:9.0.30]at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_181]at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_181]at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.30.jar:9.0.30]at java.lang.Thread.run(Thread.java:748) [na:1.8.0_181]問題分析
MyBatis級聯查詢,配置了懶加載模式,通過Spring MVC返回json序列化時報錯。?
通過java的反射機制將pojo轉換成json的。
因為json plugin用的是java的內審機制.被管理的pojo會加入["hibernateLazyInitializer","handler","fieldHandler"]等屬性,json plugin會對這些屬性拿出來操作,并讀取里面一個不能被反射操作的屬性就產生了異常。
實體類中有的字段值為null,所以在json化的時候,fasterxml.jackson將對象轉換為json報錯。
問題關鍵
在MappingJackson2HttpMessageConverter通過aop轉化為json的時候不處理相關屬性
API
@JsonIgnoreProperties
此注解用于類類,作用是json序列化時將java bean中的一些屬性忽略掉,序列化和反序列化都受影響。
@JsonIgnore
此注解用于屬性或者方法上(最好是屬性上),作用和上面的@JsonIgnoreProperties一樣。
解決方案?
方法一:@JsonIgnoreProperties
在實體類上面加上注解
@JsonIgnoreProperties(value = { "hibernateLazyInitializer", "handler" }) package cn.edu.aynu.Bean;import com.fasterxml.jackson.annotation.JsonIgnoreProperties;import java.io.Serializable; @JsonIgnoreProperties(value = { "hibernateLazyInitializer", "handler" }) public class Book implements Serializable {private String bookName;private String author;public Book(){}public Book(String bookName, String author) {this.bookName = bookName;this.author = author;} }@JsonIgnoreProperties(value={"hibernateLazyInitializer"}) (此時只是忽略hibernateLazyInitializer屬性)要加載被lazy的,也就是many-to-one的one端的pojo上
這行代碼的作用在于告訴你的json plugin組件,在將你的代理對象轉換為json對象時,忽略value對應的數組中的屬性.
如果你想在轉換的時候繼續忽略其他屬性,可以在數組中繼續加入
例如:"hibernateLazyInitializer","handler","fieldHandler"
方法二:@JsonIgnore
對象的屬性上面增加 @JsonIgnore 注解?
@JsonIgnore public Set<User> getUsers() { return this.users; }注意:引入的類是 com.fasterxml.jackson.annotation.JsonIgnore,如果使用 org.codehaus.jackson.annotate.JsonIgnore 則不能生效,見?Spring @JsonIgnore not working?。?
方法三:關閉LAZY加載
fetch?= FetchType.LAZY?改為?fetch?= FetchType.EAGER
但這樣會導致每次查詢數據庫都要立即提取 OneToMany 的所有對象,所以非常不推薦。?
方法四:OpenSessionInViewFilter
通過 Hibernate 的 OpenSessionInViewFilter 使得 FetchType 為 LAZY 的屬性在序列化時為空,在 web.xml 中添加代碼如下:
<filter> <filter-name>openSession</filter-name> <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class> <init-param> <param-name>singleSession</param-name> <param-value>false</param-value> </init-param> </filter> <filter-mapping> <filter-name>openSession</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>?
Spring MVC配置詳情
https://www.cnblogs.com/blogonfly/articles/3991782.html
Spring Boot?配置詳情
https://my.oschina.net/wangxinxx/blog/864336
盡管 users 為空,但字段依然保留,對應輸出:
{...,"users":[],...}
參考文章?
https://blog.csdn.net/wgp15732622312/article/details/79951977
https://www.cnblogs.com/gugia/p/5117735.html
https://blog.csdn.net/u014086054/article/details/89046847
https://www.cnblogs.com/xuwenjin/p/8832522.html
https://www.cnblogs.com/zhulina-917/p/10557487.html
https://ask.csdn.net/questions/344738
https://www.cnblogs.com/cbread/p/4017987.html
https://www.cnblogs.com/softidea/p/5668697.html
總結
以上是生活随笔為你收集整理的JAVA——json序列化错误[hibernateLazyInitializer,handler,fieldHandler]解决方案的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Visual C++——《可视化编程技术
- 下一篇: MyBatis Plus——忽略某个实体