You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot中WebClient序列化配置Bean作为REST请求体报错解决

解决Spring配置Bean序列化JSON报错问题

错误原因

你遇到的序列化错误,本质是因为给ConfigDetails加了@Configuration注解,Spring会为这个类生成CGLIB代理对象,代理对象中包含$$beanFactory这类Spring内部框架属性。Jackson序列化时会递归处理这些属性,但StandardBeanExpressionResolver这类Spring内部类没有对应的序列化器,因此抛出异常。

解决方案

方案1:修正配置Bean的注解(推荐)

@Configuration是用来定义配置类(比如注册Bean的类)的,而@ConfigurationProperties是用来绑定配置属性的,二者不应该混用。正确的做法是移除@Configuration,改用@Component让Spring扫描为Bean,或者通过@EnableConfigurationProperties来注册:

修改ConfigDetails类:

@ConfigurationProperties(prefix = "myprefix")
@Component // 让Spring扫描并实例化
@Getter
@Setter
public class ConfigDetails {
    private String c1;
    private String c2;
    private String c3;
}

然后在Spring Boot启动类添加@ConfigurationPropertiesScan,确保配置属性类被扫描到:

@SpringBootApplication
@ConfigurationPropertiesScan
public class YourApplication {
    public static void main(String[] args) {
        SpringApplication.run(YourApplication.class, args);
    }
}

或者,如果你不想用@Component,可以在启动类用@EnableConfigurationProperties注册:

@SpringBootApplication
@EnableConfigurationProperties(ConfigDetails.class)
public class YourApplication {
    public static void main(String[] args) {
        SpringApplication.run(YourApplication.class, args);
    }
}

此时ConfigDetails类可以去掉@Component,保留@ConfigurationProperties(prefix = "myprefix")即可。

这种方式从根源上避免了生成代理对象,是最规范的解决方法。

方案2:让Jackson忽略代理类的内部属性

如果因为某些原因必须保留@Configuration注解,可以在ConfigDetails类上添加@JsonIgnoreProperties,指定忽略Spring代理生成的特殊属性:

@ConfigurationProperties(prefix = "myprefix")
@Configuration("configname")
@Getter
@Setter
@JsonIgnoreProperties(value = {"$$beanFactory", "$$classLoader", "$$springConfigured"})
public class ConfigDetails {
    private String c1;
    private String c2;
    private String c3;
}

或者更宽松地忽略所有未知属性(不推荐,可能会隐藏其他问题):

@JsonIgnoreProperties(ignoreUnknown = true)

方案3:使用DTO中转序列化

创建一个纯数据传输对象(DTO),将配置Bean的属性复制到DTO后再序列化,避免直接序列化Spring代理对象:

  1. 定义DTO类:
@Getter
@Setter
public class ConfigDetailsDto {
    private String c1;
    private String c2;
    private String c3;
}
  1. 在调用WebClient时复制属性:
// 手动复制属性
ConfigDetailsDto dto = new ConfigDetailsDto();
dto.setC1(configDetails.getC1());
dto.setC2(configDetails.getC2());
dto.setC3(configDetails.getC3());

// 或者用Spring的BeanUtils简化复制
// BeanUtils.copyProperties(configDetails, dto);

webClient.post().body(Mono.just(dto), ConfigDetailsDto.class)...

这种方式适合需要将配置Bean和请求体解耦的场景,避免后续配置Bean修改影响请求结构。

内容的提问来源于stack exchange,提问作者ashish.g

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 21:21:00