springboot使用jackson序列化报错

文章讲述了在使用SpringBoot开发时遇到的Jackson序列化错误,主要涉及`StandardBeanExpressionResolver`找不到序列化器的问题。提供了两种解决方案:禁用proxyBeanMethods或替换@Configuration为@Component。作者反思了对SpringBoot注解理解的不足。

背景

最近在使用spring boot开发时,遇到jackson序列化的错误,折腾了好一会儿,这里记录一下。

报错信息

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class org.springframework.context.expression.StandardBeanExpressionResolver and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: com.goldwind.ngsp.ps.dto.Test$$EnhancerBySpringCGLIB$$d694239f["$$beanFactory"]->org.springframework.beans.factory.support.DefaultListableBeanFactory["beanExpressionResolver"])

实体类代码

@Configuration
@Component
@Data
public class Test {
  @Value("${test.name:Steven}")
  private String name;
}

Controller接口代码

@Autowired
private Test test;

@GetMapping(value = "/test")
public String test() {
   return JsonUtil.toJsonString(test);
}

配置文件

test.name=test

解决方案一

将@Configuration注解中的属性proxyBeanMethods 设置为 false

@Configuration(proxyBeanMethods=false)
// @Component
@Data
public class Test {
  @Value("${test.name:Steven}")
  private String name;
}

这里需要注意一下,要将@Component注解注释掉

解决方案二

将@Configuration注解替换为@Component注解

@Component
@Data
public class Test {
  @Value("${test.name:Steven}")
  private String name;
}

反思

这里还是对spring boot的注解理解不够导致的啊,少年,继续努力学习吧!

<think>好的,我现在需要解决用户的问题:在Spring Boot中修改了domain后,使用Fastjson时出现报错。首先,我得分析可能的原因。 用户提到修改了domain后出现错误,所以首先想到的是序列化/反序列化问题。Fastjson在处理对象时,依赖getter和setter方法,或者字段名称。如果用户修改了domain类的字段名、类型,或者删除了某些方法,可能导致Fastjson无法正确解析。 比如,假设用户将一个字段从userName改为username,而JSON中仍然使用userName,这时候如果没有正确的注解或者配置,Fastjson会找不到对应的字段,从而抛出异常。或者,如果用户添加了新字段但没有提供默认构造函数,Fastjson在反序列化时可能无法实例化对象。 另外,可能涉及到循环引用的问题。比如domain对象之间存在双向关联,比如User和Order互相引用,Fastjson默认配置可能无法处理,导致栈溢出或者序列化失败。这时候需要配置Fastjson的序列化特性,如SerializerFeature.DisableCircularReferenceDetect。 还可能是因为版本升级带来的问题。如果用户升级了Spring Boot或者Fastjson的版本,某些API可能发生了变化,导致兼容性问题。需要检查版本是否兼容,是否有破坏性变更。 另外,Spring Boot默认使用Jackson,如果用户切换到了Fastjson但没有正确配置,比如未注册Fastjson的HttpMessageConverter,可能导致序列化失败。这时候需要检查配置类是否添加了Fastjson的转换器。 解决方法方面,首先应该检查domain类的改动,确认字段名、方法是否与JSON结构匹配。可以使用@JSONField注解来指定字段别名。其次,检查Fastjson的配置,确保正确配置了序列化特性,比如关闭循环引用检测。然后,确认Spring Boot中是否正确集成了Fastjson的转换器,替换掉默认的Jackson。 可能的示例代码包括在配置类中添加Fastjson的转换器,或者在domain字段上添加注解。此外,处理循环引用可能需要配置Fastjson的全局实例,设置相关特性。 最后,用户可能需要了解如何避免此类问题,比如使用注解明确指定字段名,统一序列化配置,或者进行充分的测试。</think>当Spring Boot项目中修改domain对象后出现Fastjson报错,通常与序列化/反序列化规则变化有关。以下是常见原因及解决方案: 一、常见原因分析: 1. 字段不匹配(最常见): - 删除/重命名字段但未更新@JSONField注解 - 修改字段类型导致类型转换失败 - 新增非空字段但未提供默认值 2. 循环引用问题: - 新增双向关联导致序列化时无限递归 3. 配置不一致: - Fastjson全局配置未适配新的domain结构 - 未正确配置Spring消息转换器 二、解决方案示例: 1. 基础字段映射修正: ```java public class User { // 旧字段:@JSONField(name = "userName") // 新字段: @JSONField(name = "username") // 确保与JSON字段名一致 private String username; // 新增字段需处理默认值 @JSONField(deserializeUsing = MyDefaultValueDeserializer.class) private Integer userType = 0; } ``` 2. 配置HttpMessageConverter: ```java @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter(); FastJsonConfig config = new FastJsonConfig(); config.setSerializerFeatures( SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.WriteMapNullValue ); converter.setFastJsonConfig(config); converters.add(0, converter); } } ``` 3. 处理循环引用: ```java // 在配置类中设置全局参数 FastJsonConfig config = new FastJsonConfig(); config.setSerializerFeatures(SerializerFeature.DisableCircularReferenceDetect); // 或在特定字段使用注解 public class Order { @JSONField(serialize = false) private User owner; } ``` 三、调试建议: 1. 检查序列化结果: ```java String json = JSON.toJSONString(yourObject, SerializerFeature.PrettyFormat); System.out.println(json); ``` 2. 启用Fastjson的类型推导: ```java ParserConfig.getGlobalInstance().setAutoTypeSupport(true); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值