Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 带Jackson的不可变Lombok注释类_Java_Json_Jackson_Lombok_Jackson Databind - Fatal编程技术网

Java 带Jackson的不可变Lombok注释类

Java 带Jackson的不可变Lombok注释类,java,json,jackson,lombok,jackson-databind,Java,Json,Jackson,Lombok,Jackson Databind,创建类的首选方法是什么 不变的 可以使用Jackson进行序列化/反序列化 可读性强,样板文件水平低 最好是,我希望这样的工作: @Data(onConstructor = @__(@JsonCreator)) 然后将所有字段设置为private final。然而,这甚至没有编译(我不知道为什么)。使用 将编译,但只生成 InvalidDefinitionException: No serializer found for class 可以使用Lombok注释为不可变的POJO类生成生成

创建类的首选方法是什么

  • 不变的
  • 可以使用Jackson进行序列化/反序列化
  • 可读性强,样板文件水平低
最好是,我希望这样的工作:

@Data(onConstructor = @__(@JsonCreator))
然后将所有字段设置为
private final
。然而,这甚至没有编译(我不知道为什么)。使用

将编译,但只生成

InvalidDefinitionException: No serializer found for class
可以使用Lombok注释为不可变的POJO类生成生成器。 但是通过Jackson的反序列化使Lombok生成的生成器可用有些棘手

  • 您需要使用 告诉Jackson要使用哪个生成器类
  • 您需要使用 要告诉Jackson它的setter方法确实是而不是,请从
    with
    开始
例如:

不可变的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);
    }
}

另一个不那么冗长的选择:

@Data
@Setter(AccessLevel.NONE)
public class Clazz {
    private String field;
} 
当然,您仍然可以有一些直接修改字段的私有方法,但在@datapojo中甚至不太可能有任何实际代码,因此希望不会发生这种情况

免责声明: 这将产生一个副作用(可能是有益的),即不让常规Java代码创建对象,因为只有一个默认构造函数,没有任何变体。为了允许正常构造,您还需要另外两个注释:

@Data
@AllArgsConstructor
@NoArgsConstructor
@Setter(AccessLevel.NONE)
public class Clazz {
    private String field;
} 
添加构造函数属性:

  • 使用以下行创建
    lombok.config
    文件:
    lombok.anyConstructor.addConstructorProperties=true
  • 将lombok
    @Value
    注释添加到类中以使其不可变
然后,Jackson的序列化和反序列化工作正常

此方法:

  • 符合标准
  • 与上一个顶级答案相比,具有更少的样板文件位置
  • 工作日及以后
编辑:2020-08-16

  • 注意:将
    @Builder
    @Value
    一起使用会导致此解决方案失败。(感谢下面@guilherme blanco的评论。) 但是,如果您还添加了例如
    @allargsconstuctor
    ,它仍能按预期工作
通过参考,我提出了以下解决方案

对于我来说,简单的龙目山注释是这样的。以下注释为您提供了具有生成器的不可变类,这些类可以由Jackson序列化和反序列化

    @Data
    @Setter(AccessLevel.NONE)
    @Builder(toBuilder = true)
    @AllArgsConstructor
    @NoArgsConstructor(access = AccessLevel.PRIVATE)
    public class Clazz {
        private String field;
    } 

我更喜欢这个解决方案,因为它不需要额外的,也不需要额外的

托马斯·弗里奇(Thomas Fritsch)的答案在pom中添加Jackson Dataformat依赖项后,与Spring Boot完美结合

@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
    }
}

<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.dataformat/jackson-dataformat-xml -->
<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
</dependency>
@数据
@生成器(builderClassName=“PointBuilder”)
@JsonDeserialize(builder=Point.PointBuilder.class)
公共课点{
私人最终int x;
私人终审法院;
@JsonPOJOBuilder(前缀为“”)
公共静态类PointBuilder{
//Lombok将添加构造函数、设置器和构建方法
}
}
com.fasterxml.jackson.dataformat
jackson数据格式xml

尝试以下pojo注释集:

@Value
@NoArgsConstructor(force = true, access = AccessLevel.PRIVATE)
@AllArgsConstructor

我刚刚用这种方法解决了这个问题:

@Value
@Builder(setterPrefix = "with")
@JsonDeserialize(builder = Clazz.ClazzBuilder.class)
public class Clazz {
    private String field;
}
在这种情况下,您必须使用构建器方法,如
withField(…)
,这是jackson使用的默认行为。

从2020年10月15日起(),您应该能够简单地使用注释

@Jacksonized@Builder
@JsonIgnoreProperties(ignoreUnknown=true)
公共类Jacksone示例{
私人名单;
}
如链接文档中所述,此注释:

  • 将Jackson配置为使用生成器进行反序列化
  • 将特定于字段的配置从注释类向下复制到生成的生成器(例如
    @JsonIgnoreProperties
    ),以及
  • 将生成器方法(例如
    builder().withField(field)
    vs
    builder.field(field)
    上使用的Jackson前缀与Lombok中配置的前缀对齐

为Jackson配置不可变类的最简单方法是使用lombok注释:和:

@Jacksonized
@建筑商
@价值观
福班{
}

我使用这种方法已经有一段时间了,而且非常非常有效。一个非常小的改进是,我总是给我的构建器类命名\u builder。这样,当我复制粘贴以创建新类等时……我不必记得更改builderClassName中的字符串。我以前调用过类构建器(不带下划线),但在处理内部静态类时,这与@Builder注释类有奇怪的冲突。注意:这种方法不能与@Builder结合使用。谢谢。但是看起来:我们能把这个答案排在第一位吗?它的效果很好:)
@Value
@Builder(setterPrefix = "with")
@JsonDeserialize(builder = Clazz.ClazzBuilder.class)
public class Clazz {
    private String field;
}
@Jacksonized @Builder
@JsonIgnoreProperties(ignoreUnknown = true)
public class JacksonExample {
  private List<Foo> foos;
}