当前位置: 首页 > 知识库问答 >
问题:

带有Jackson的不可变Lombok注释类

楚畅
2023-03-14

创建类的首选方法是什么

  • 不可变
  • 可以使用Jackson进行序列化/反序列化
  • 可读性强,样板文件水平低

最好是,我希望这样的东西能起作用:

@Data(onConstructor = @__(@JsonCreator))

然后将所有字段设置为private final。然而,这甚至不能编译(我不知道为什么)。使用

@AllArgsConstructor(onConstructor = @__(@JsonCreator))

将编译,但仅生成

InvalidDefinitionException: No serializer found for class

共有3个答案

班展
2023-03-14

您可以使用Lombok的@Builder注释为您的不可变POJO类生成构建器。但是让Jackson的反序列化可以使用Lombok生成的构建器有些棘手。

  • 您需要用@JsonDeserialize(builder=…)注释POJO类,以告诉Jackson要使用哪一个构建器类
  • 您需要用@JsonPOJOBuilder(withPrefix=“”)注释构建器类,以告诉Jackson其setter方法不是以开头

例:

不可变的POJO类:

@Data
@Builder(builderClassName = "PointBuilder")
@JsonDeserialize(builder = Point.PointBuilder.class)
public class Point {

    private final int x;

    private final int y;

    @JsonPOJOBuilder(withPrefix = "")
    public static class PointBuilder {
        // Lombok will add constructor, setters, build method
    }
}

这是一个JUnit测试来验证序列化/反序列化:

public class PointTest extends Assert {

    private ObjectMapper objectMapper = new ObjectMapper();

    @Test
    public void testSerialize() throws IOException {
        Point point = new Point(10, 20);
        String json = objectMapper.writeValueAsString(point);
        assertEquals("{\"x\":10,\"y\":20}", json);
    }

    @Test
    public void testDeserialize() throws IOException {
        String json = "{\"x\":10,\"y\":20}";
        Point point = objectMapper.readValue(json, Point.class);
        assertEquals(new Point(10, 20), point);
    }
}
易宏阔
2023-03-14

截至2020年10月15日(Lombok v1.18.16),您应该能够简单地使用< code>@Jacksonized注释。

@Jacksonized @Builder
@JsonIgnoreProperties(ignoreUnknown = true)
public class JacksonExample {
  private List<Foo> foos;
}

如链接文档中所述,此注释:

  • 将杰克逊配置为使用生成器进行反序列化,
  • 将特定于字段的配置从带注释的类向下复制到生成的构建器(例如@JsonIgnoreProperties),以及
  • 将构建器方法(例如构建器().with字段(字段)与构建器字段(字段)中使用的杰克逊前缀与龙目岛中配置的前缀对齐。
仇正豪
2023-03-14

添加构造函数属性:

  • 在适当的位置创建一个龙目岛配置文件,其行为:龙目岛.any结构商.add结构商属性 = true
  • 将龙目岛@Value注释添加到类中以使其不可变

然后,Jackson的序列化和反序列化工作正常。

此方法:

    < li >符合标准 < li >与上一个顶级答案相比,样板内容较少 < li >适用于v 1 . 16 . 20(2018年1月9日)及更高版本

编辑:2020-08-16

    < li >注意:将< code>@Builder与< code>@Value一起使用会导致此解决方案失败。(感谢下面@guilherme-blanco的评论。)但是,如果您还添加了例如< code>@AllArgsConstructor,它仍然会按预期工作。

编辑: 2021-08-19

    < li >注意:当您添加或更改< code>lombok.config文件时,更改不会生效,除非您执行重建(先清理后构建)。我已经被这个抓了好几次了。 < li> @Jacksonized批注解决方案是为批注的特定类实现所需结果的另一种方法。然而,我个人倾向于不需要记住注释每个用于反序列化的类。使用< code>lombok.config可以消除这种开销。
 类似资料:
  • 而且 但这似乎不起作用,因为中没有可用的默认构造函数。我不熟悉龙目岛注释。有什么好的方法可以扩展基类,同时使用lombok注释吗?

  • 我有一把刀: 问题是,当我试图使用DAO进行加载调用时,使用DynamoDBMapper以field d1作为哈希键来获取项目,它会抛出一个DynamoDBExc0019,说:为公共DAO. getField2()找到了空键,但实际上表的值对应于field d2。问题,这是因为Lombok注释而不是手动突变代码,还是一般来说我们一起使用Lombok和DynamoDBAnnotions?

  • 例如: 我知道有jackson注解可以这样做,但是我的字段已经用我的持久性注解进行了注解,所以我想避免重复,因为我已经有了我想忽略的注解的字段

  • 我试图在Ubuntu 16.04 LTS上使用STS 3.9.4创建一个测试项目,Java8和Lombok 1.16.20。 安装了“龙目1.16.20版”跳舞象形文字。“”通常显示在“关于”选项卡上。 我尝试过的程序: 运行龙目岛。jar并通过GUI进行安装 还有其他解决方法吗?

  • 我有一个方法,每隔20分钟运行一次。我只是在Spring boot中使用了@scheduled注释,但是我需要一个在运行时需要延迟时间的调度器。例如。如果我希望能够在运行时改变方法执行的延迟时间/频率,而不停止应用程序,即改变以DB为单位的频率,那么代码应该适应它。 代码中的固定速率应该是可变的,并在运行时取值。有可能实现吗?

  • 我给一个有json主体的aws lambda打电话。因此,json的字段与POJO中的字段具有不同的名称。所以我所做的就是在字段中添加@JsonProperty,告诉jackson json中的名称。但出于某种原因,它似乎无法识别它们,并且所有字段都为空。如果我传递一个与POJO具有相同字段名的json,它就会工作。这是我的课: 如果我通过 所有的字段都是空的,并且有明显的ID、userId、ev