Java 8 Jackson 不可变类反序列化

3
我将尝试将一个JSON字符串反序列化为一个Java POJO类,该类只有一个全参数构造函数和getter方法。所有字段都是final的,这个类是不可变的。以下是我的Java POJO对象:
``` Foo.java ```
public class Foo {
    private final int id;
    private final int cId;
    private final String cName;
    private final String code;
    private final String display;

    public Foo(final int id, 
               final int cId,
               final String cName,
               final String code,
               final String display) {
        this.id = id;
        this.cId = cId;
        this.cName = cName;
        this.code = code;
        this.display = display;
    }

    //Some copy constructor
    public Foo(final FooB fooB) {
        this.id = fooB.getId();
        this.cId = fooB.getCId();
        this.cName = fooB.getContractorCName();
        this.code = fooB.getCode();
        this.display = fooB.getDisplay();
    }

    public int getId() {
        return id;
    }

    public int getCId() {
        return cId;
    }

    public String getCName() {
        return cName;
    }

    public String getCode() {
        return code;
    }

    public String getDisplay() {
        return display;
    }
}

以下是我的测试:

public static void main(String[] args) {
    ParameterNamesModule pnm = new ParameterNamesModule(JsonCreator.Mode.PROPERTIES);
    ObjectMapper mapper = new ObjectMapper().enable(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES).registerModule(pnm);
    String json = "{\"id\":19,\"cId\":13234,\"cName\":\"SOME NAME\",\"code\":\"8EJ4\",\"display\":\"SOME DISPLAY NAME\"}";
    try {
        mapper.readValue(json, Foo.class);
    } catch (JsonProcessingException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

然而,当我运行它时,我收到以下错误:

objc[58537]: Class JavaLaunchHelper is implemented in both /Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/bin/java (0x109dbf4c0) and /Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/libinstrument.dylib (0x109e874e0). One of the two will be used. Which one is undefined.
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.test.Foo` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
 at [Source: (String)"{"id":19,"cId":13234,"cName":"SOME NAME","code":"8EJ4","display":"SOME DISPLAY NAME"}"; line: 1, column: 2]
    at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:67)
    at com.fasterxml.jackson.databind.DeserializationContext.reportBadDefinition(DeserializationContext.java:1451)
    at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1027)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1290)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:326)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:159)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4001)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2992)
    at JacksonCreator.main(JacksonCreator.java:18)

我做错了什么?我正在使用Jackson的版本2.9.4

1
看起来它需要一个默认构造函数和设置器。是建造者的好选择吗? - Joe C
你是否使用了“-parameters”进行编译? - Sotirios Delimanolis
@SotiriosDelimanolis 我想那就是问题所在。我没有将其作为命令运行。难道没有任何方法可以在不使用该运行时参数的情况下使此模块工作吗? - Richard
7
如果您可以更改类,则使用 @JsonProperty 注释参数,并使用 @JsonCreator 注释构造函数。否则,请按照此处所述使用 mixin(链接:https://dev59.com/tlYN5IYBdhLWcg3wV3BX)。 - Sotirios Delimanolis
@SotiriosDelimanolis,是的,我一直在尝试使用参数模块作为一种避免在POJO中使用注释的方法,而且我不想为每个单独的POJO创建一个额外的类。但是添加编译器参数会更糟糕,所以我会坚持使用注释。 - Richard
我建议两件事。首先 - 使用lombok,因为有太多的样板代码。其次 - 配置@JsonDeserialize(builder = Foo.Builder.class)和@JsonPOJOBuilder(withPrefix = "")。这是我发现与不可变对象和jackson一起工作最干净的方式。 - Daniel Hajduk
1个回答

1

试试这个

@JsonCreator(mode = JsonCreator.Mode.PROPERTIES) public Foo(@JsonProperty ("id") final int id, @JsonProperty ("cId") final int cId, ...) { this.id = id; this.cId = cId; ... }


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接