【问题标题】:Lombok with Jackson Deserializer from camelCase龙目岛与来自camelCase的Jackson Deserializer
【发布时间】:2018-12-13 23:29:44
【问题描述】:

这是一个简单的对象

@Builder
@Value
@JsonDeserialize(builder = User.UserBuilder.class)
class User {
    @NotNull
    @JsonProperty("user_name")
    private final string userName;

    @JsonPOJOBuilder(withPrefix = "")
    public static final class UserBuilder {}
}

现在,如果我想使用 ObjectMapper 来读取一个字符串,我会这样做

final User user = MAPPER.readValue("{\"user_name\":\"my-name\"}", User.class);

但这不会读取user_name,因为当我查看生成的生成器源代码时,我看到了

public static final class UserBuilder {
    private String userName;
}

所以camelCase 与snake_case 不匹配。通常,如果我要手动生成 Builder 类,我也会将 @JsonProperty("user_name") 放在 builder 属性上。

我该如何解决这个问题?

【问题讨论】:

  • Lombok 支持使用配置参数lombok.copyableAnnotations 将注释复制到构建器方法。但是,这会将注释复制到方法的参数(而不是方法),这在这里没有帮助。不幸的是,没有简单的解决方案,因为某些注释仅适用于参数。有关此主题的讨论,请参阅 github.com/rzwitserloot/lombok/issues/1961
  • @JanRieke 等等。但我确实希望注释在参数上,而不是方法上;即我希望UserBuilder 中的参数private String userName; 也能获得@JsonProperty("user_name") 注释。
  • 也不支持将注释复制到构建器的内部字段(而且 IMO 无论如何都不是一个好的解决方案,即使它适用于 Jackson)。

标签: java jackson lombok


【解决方案1】:

您可以配置 ObjectMapper 以将驼峰式大小写转换为带下划线的名称:

objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);

【讨论】:

  • 我不想让我的对象映射器担心这个。我希望反序列化器为我处理这个问题。
【解决方案2】:

Builder 创建您自己的构造函数,以便与下划线参数名称一起使用:

@Value
@JsonDeserialize(builder = User.UserBuilder.class)
class User {
    @NotNull
    @JsonProperty("user_name")
    private final String userName;

    @Builder
    public User(String user_name) {
      this.userName = user_name;
    }

    @JsonPOJOBuilder(withPrefix = "")
    public static final class UserBuilder {}

}

【讨论】:

  • 这违背了使用Lombok的目的!我不想创建构建器或构造器!
  • 还有 10 种不同的元素让它与 jackson 一起工作不会破坏它的目的吗?此外,您现在有没有验证的公共构造函数?
猜你喜欢
  • 2021-03-27
  • 2011-06-19
  • 1970-01-01
  • 2020-03-13
  • 1970-01-01
  • 2018-03-29
  • 1970-01-01
  • 2021-10-02
  • 2015-10-18
相关资源
最近更新 更多