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

移除Lombok的@Getter注解后第三方REST API请求字段为何为空?

问题描述

我正在调用第三方REST端点,预期的请求结构如下:

{
     "body": {
        "accountNumber": "12345"
     },
     "header": {
        "username": "someusername",
        "password": "somepassword"
     }
}

我创建了3个Bean类:

MyRequest.java

@Builder
@JsonDeserialize(builder =  MyRequest.MyRequestBuilder.class)
public class MyRequest {
    @JsonProperty("header")
    private MyHeader header;
    @JsonProperty("body")
    private MyBody body;
}

MyBody.java

@Getter
@Builder
public class MyBody {
    private String accountNumber;
}

MyHeader.java

@Getter
@Builder
public class MyHeader {
    private String username;
    private String password;
}

我通过以下代码构建请求对象:

MyBody body = MyBody.builder().accountNumber("12345").build();
MyHeader header = MyHeader.builder().username("someusername").password("somepassword").build();
MyRequest request = MyRequest.builder().body(body).header(header).build();

调用第三方接口的代码如下:

HttpEntity<MyRequest> httpEntity = new HttpEntity<>(myRequest, httpHeaders);
String url = "someurl";

someResponse = this.restTemplate.postForObject(url, httpEntity,
        SomeResponse.class);

原本接口能正常返回响应,但移除MyHeader和MyBody上的@Getter注解后,第三方收到的请求字段全为null。请问:

  1. 为什么@Getter是必需的?
  2. 如何在不使用@Getter的情况下解决这个问题?

解答

一、为什么@Getter是必需的?

你用的RestTemplate默认依赖Jackson来把Java对象序列化成JSON。Jackson序列化私有字段的默认逻辑是:

  • 优先找对应字段的Getter方法(比如getAccountNumber()对应accountNumber字段),通过Getter读取字段值;
  • 如果没有Getter,Jackson会尝试直接访问私有字段,但这个权限默认是关闭的。

你的MyHeader和MyBody里的字段都是private修饰的,移除@Getter后,Jackson找不到读取字段的途径,又没权限直接访问私有字段,所以序列化出来的JSON里这些字段都是null,第三方自然收到空值。

另外要注意:Lombok的@Builder只会生成构建器和全参构造方法,不会自动生成Getter,所以去掉@Getter后,类里完全没有能让Jackson获取字段值的入口。

二、不使用@Getter的解决办法

有几种可行的替代方案:

1. 配置Jackson允许直接访问私有字段

在你的Spring配置类里,给ObjectMapper添加允许访问私有字段的配置:

@Bean
public ObjectMapper objectMapper() {
    ObjectMapper objectMapper = new ObjectMapper();
    // 让Jackson可以直接读取任意访问权限的字段
    objectMapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
    return objectMapper;
}

这样Jackson会跳过Getter检查,直接读取私有字段的值。

2. 给私有字段添加@JsonProperty注解

在MyHeader和MyBody的字段上加上@JsonProperty,明确告诉Jackson这个字段需要被序列化:

@Builder
public class MyBody {
    @JsonProperty
    private String accountNumber;
}
@Builder
public class MyHeader {
    @JsonProperty
    private String username;
    @JsonProperty
    private String password;
}

这个注解会让Jackson忽略Getter的存在,直接处理标注的字段。

3. 使用Lombok的@Jacksonized配合@Builder

如果你的Lombok版本在1.18.14及以上,可以用@Jacksonized注解配合@Builder,它会自动生成适配Jackson序列化的构建器逻辑,不需要额外的@Getter:

@Jacksonized
@Builder
public class MyBody {
    private String accountNumber;
}
@Jacksonized
@Builder
public class MyHeader {
    private String username;
    private String password;
}

这个注解会帮你配置Jackson识别Lombok生成的类,自动处理私有字段的序列化。

4. 将字段改为public(不推荐)

直接把accountNumber、username、password的修饰符改成public,Jackson可以直接读取字段值。但这种做法会破坏类的封装性,生产环境不建议使用。


内容的提问来源于stack exchange,提问作者Thiagarajan Ramanathan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 15:25:19