• Bug记录:【com.fasterxml.jackson.databind.exc.InvalidDefinitionException】


    bug记录

    序列化错误

    异常com.fasterxml.jackson.databind.exc.InvalidDefinitionException:
    在这里插入图片描述

    完整错误(主要是FAIL_ON_EMPTY_BEANS)

        00:15:20.250  [http-nio-3000-exec-1] ERROR org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/].[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.http.converter.HttpMessageConversionException: Type definition error: [simple type, class com.jingdianjichi.subject.common.entity.PageResult]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class com.jingdianjichi.subject.common.entity.PageResult and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: com.jingdianjichi.subject.common.entity.Result["data"])] with root cause
        com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class com.jingdianjichi.subject.common.entity.PageResult and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: com.jingdianjichi.subject.common.entity.Result["data"])
        	at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77) ~[jackson-databind-2.11.4.jar:2.11.4]
        	at com.fasterxml.jackson.databind.SerializerProvider.reportBadDefinition(SerializerProvider.java:1277) ~[jackson-databind-2.11.4.jar:2.11.4]
        	at com.fasterxml.jackson.databind.DatabindContext.reportBadDefinition(DatabindContext.java:400) ~[jackson-databind-2.11.4.jar:2.11.4]
        	at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.failForEmpty(UnknownSerializer.java:71) ~[jackson-databind-2.11.4.jar:2.11.4]
        	at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.serialize(UnknownSerializer.java:33) ~[jackson-databind-2.11.4.jar:2.11.4]
        	at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728) ~[jackson-databind-2.11.4.jar:2.11.4]
        	at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:755) ~[jackson-databind-2.11.4.jar:2.11.4]
        	at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178) ~[jackson-databind-2.11.4.jar:2.11.4]
        	at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480) ~[jackson-databind-2.11.4.jar:2.11.4]
        	at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319) ~[jackson-databind-2.11.4.jar:2.11.4]
        	at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1516) ~[jackson-databind-2.11.4.jar:2.11.4]
        	at com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:1006) ~[jackson-databind-2.11.4.jar:2.11.4]
        	at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:345) ~[spring-web-5.3.3.jar:5.3.3]
        	at org.springframework.http.converter.AbstractGenericHttpMessageConverter.write(AbstractGenericHttpMessageConverter.java:104) ~[spring-web-5.3.3.jar:5.3.3]
        	at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:277) ~[spring-webmvc-5.3.3.jar:5.3.3]
        	at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:181) ~[spring-webmvc-5.3.3.jar:5.3.3]
        	at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:78) ~[spring-web-5.3.3.jar:5.3.3]
        	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:124) ~[spring-webmvc-5.3.3.jar:5.3.3]
        	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894) ~[spring-webmvc-5.3.3.jar:5.3.3]
        	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.3.jar:5.3.3]
        	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.3.jar:5.3.3]
        	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1060) ~[spring-webmvc-5.3.3.jar:5.3.3]
        	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:962) ~[spring-webmvc-5.3.3.jar:5.3.3]
        	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.3.jar:5.3.3]
        	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) ~[spring-webmvc-5.3.3.jar:5.3.3]
        	at javax.servlet.http.HttpServlet.service(HttpServlet.java:652) ~[tomcat-embed-core-9.0.41.jar:4.0.FR]
        	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.3.jar:5.3.3]
        	at javax.servlet.http.HttpServlet.service(HttpServlet.java:733) ~[tomcat-embed-core-9.0.41.jar:4.0.FR]
        	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
        	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
        	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.41.jar:9.0.41]
        	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
        	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
        	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.3.jar:5.3.3]
        	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.3.jar:5.3.3]
        	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
        	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
        	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.3.jar:5.3.3]
        	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.3.jar:5.3.3]
        	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
        	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
        	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.3.jar:5.3.3]
        	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.3.jar:5.3.3]
        	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
        	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
        	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) [tomcat-embed-core-9.0.41.jar:9.0.41]
        	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) [tomcat-embed-core-9.0.41.jar:9.0.41]
        	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) [tomcat-embed-core-9.0.41.jar:9.0.41]
        	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143) [tomcat-embed-core-9.0.41.jar:9.0.41]
        	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [tomcat-embed-core-9.0.41.jar:9.0.41]
        	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) [tomcat-embed-core-9.0.41.jar:9.0.41]
        	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [tomcat-embed-core-9.0.41.jar:9.0.41]
        	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374) [tomcat-embed-core-9.0.41.jar:9.0.41]
        	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) [tomcat-embed-core-9.0.41.jar:9.0.41]
        	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:888) [tomcat-embed-core-9.0.41.jar:9.0.41]
        	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1597) [tomcat-embed-core-9.0.41.jar:9.0.41]
        	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.41.jar:9.0.41]
        	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?]
        	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?]
        	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.41.jar:9.0.41]
        	at java.lang.Thread.run(Thread.java:834) [?:?]
    

    这个错误是由于Jackson库在尝试序列化com.jingdianjichi.subject.common.entity.PageResult类时遇到问题,因为它没有找到可以序列化的属性。具体来说,PageResult类可能是一个空类,或者它的所有属性都被标记为不可序列化

    要解决这个问题,可以采取以下几种方法:

    1. 确保PageResult类中有可以序列化的属性:检查PageResult类,确保它包含至少一个公开的字段或带有@JsonProperty注解的getter方法。
    2. 使用@JsonSerialize注解:如果你不想或不能修改PageResult类,你可以创建一个自定义的序列化器来处理这个类的序列化。
    3. 禁用FAIL_ON_EMPTY_BEANS特性:这是错误消息中提到的另一种方法。你可以在你的Jackson ObjectMapper配置中禁用这个特性,这样即使一个类没有任何属性,Jackson也不会抛出异常。

    FAIL_ON_EMPTY_BEANS特性

    FAIL_ON_EMPTY_BEANSJackson库中的一个序列化特性,它决定了当Jackson尝试序列化一个没有任何可识别属性(即没有getter方法、字段或@JsonProperty注解的属性)的Java Bean时应该采取的行为。

    具体来说,如果FAIL_ON_EMPTY_BEANS特性被启用(这是默认值),当Jackson遇到一个没有属性的Bean时,它会抛出一个异常,因为这样的Bean在序列化后不会产生任何有用的JSON数据。异常信息通常会提示开发者可能需要检查Bean的定义,或者考虑是否应该禁用FAIL_ON_EMPTY_BEANS特性。

    然而,如果FAIL_ON_EMPTY_BEANS特性被禁用,Jackson会允许序列化这样的空Bean,尽管结果可能是一个空的JSON对象({})。这可以用于某些场景,其中即使Bean没有属性,客户端或接收方也期望得到一个JSON对象而不是异常。

    要配置FAIL_ON_EMPTY_BEANS特性,你可以在创建ObjectMapper实例时调用其configure方法,并传递SerializationFeature.FAIL_ON_EMPTY_BEANS枚举值和false(禁用)或true(启用)作为参数。例如:

        
        ObjectMapper mapper = new ObjectMapper();  
        mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); // 禁用FAIL_ON_EMPTY_BEANS
    

    或者,在Spring Boot应用中,你可以通过自定义Jackson2ObjectMapperBuilderCustomizer来实现全局配置:

        
        @Configuration  
        public class JacksonConfig implements WebMvcConfigurer {  
          
            @Override  
            public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {  
                ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().build();  
                objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);  
                converters.add(new MappingJackson2HttpMessageConverter(objectMapper));  
            }  
        }
    

    请注意,虽然禁用FAIL_ON_EMPTY_BEANS特性可以解决序列化空Bean时抛出异常的问题,但它也可能隐藏潜在的问题,因为空Bean通常意味着代码中存在某种逻辑错误或遗漏。

    或者如下配置

        @Configuration
        public class GlobalConfig extends WebMvcConfigurationSupport {
            /**
             * 配置消息转换器
             * @param converters
             */
            @Override
            protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
                // 添加jackson转换器
                converters.add(mappingJackson2HttpMessageConverter());
                // 调用父类方法, 加入转换器
                super.configureMessageConverters(converters);
            }
        
            /**
             * 配置jackson转换器, 禁止序列化空对象, 防止出现500错误
             * @return
             */
            @Bean
            public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter(){
                // 创建MappingJackson2HttpMessageConverter转换器
            MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
            // 设置ObjectMapper
            ObjectMapper mapper = new ObjectMapper();
            // 禁止序列化空对象, 防止出现500错误, 否则会出现500错误,
            // 原因是序列化时, 空对象会被忽略掉, 导致前端无法正常显示,
            // 所以需要禁止, 让前端显示空对象, 前端自己判断是否显示, 而不是直接报错, 影响用户体验,
            mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
            // 设置JsonInclude.Include.NON_NULL, 序列化时, 仅序列化非null属性, 防止出现null值属性, 导致json数据过大, 影响性能,
            // 所以需要设置, 仅序列化非null属性, 减少json数据大小, 提升性能.
            // 注意: 仅序列化非null属性, 并不意味着丢弃null值属性, 而是仅序列化非null属性.
            mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
            converter.setObjectMapper(mapper);
            return converter;
            }
        }
    
  • 相关阅读:
    传输层协议(TCP/UDP协议)
    基于量子粒子群算法(QPSO)优化LSTM的风电、负荷等时间序列预测算法(Matlab代码实现)
    Image does NOT change color when selecting it in tiptap
    记录牛客js刷题的输入输出以及如何在一行输出多个结果
    [Rust笔记] 我也谈 Box<T>智能指针·实践领悟
    Android Media Framework(一)OpenMAX 框架简介
    使用归一化盒过滤器对图像进行平滑处理
    渗透测试-最全Web 渗透测试信息搜集-CheckList
    R语言绘制不同颜色的带观测次数的条形图
    C#的基于.net framework的Winform编程 - 编程手把手系列文章
  • 原文地址:https://blog.csdn.net/m0_65013257/article/details/140254587