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-使用不带注释的生成器反序列化_Java_Json_Jackson_Lombok - Fatal编程技术网

Java Jackson-使用不带注释的生成器反序列化

Java Jackson-使用不带注释的生成器反序列化,java,json,jackson,lombok,Java,Json,Jackson,Lombok,是否可以使用Jackson来反序列化只有all args构造函数和生成器的值类(final,no setters)?我无法使用JsonDeserialize和JsonPOJOBuilder,因为我正在尝试反序列化客户端库中定义的模型,因此无法添加注释。我可以指定生成器使用其他方式吗?您可以尝试使用MixIn 我为您的用例创建了一个示例: 原始类别: final class Sample { final int id; Sample(int id) { this

是否可以使用Jackson来反序列化只有all args构造函数和生成器的值类(final,no setters)?我无法使用
JsonDeserialize
JsonPOJOBuilder
,因为我正在尝试反序列化客户端库中定义的模型,因此无法添加注释。我可以指定生成器使用其他方式吗?

您可以尝试使用MixIn

我为您的用例创建了一个示例:

原始类别:

final class Sample {

    final int id;

    Sample(int id) {
        this.id = id;
    }
}
MixIn(提供具有相同参数的非参数构造函数):

反序列化:

ObjectMapper mapper = new ObjectMapper();
mapper.addMixIn(Sample.class, SampleMixin.class);
Sample sample = mapper.readValue(json, Sample.class);

你可以。建造商必须满足某些要求。例如,它的字段方法必须有特定的前缀,如“with”或“set”

下面是不带任何注释的DTO类及其生成器:

public class DtoBuilderWithFinalFieldsWithoutJackson {

  public final String stringValue;

  private DtoBuilderWithFinalFieldsWithoutJackson(final String stringValue){
    this.stringValue = stringValue;
  }

  public static Builder builder(){
    return new Builder();
  }

  public static class Builder {
    private String stringValue;

    public Builder withStringValue(String stringValue) {
      this.stringValue = stringValue;
      return this;
    }
    public DtoBuilderWithFinalFieldsWithoutJackson build() {
      return new DtoBuilderWithFinalFieldsWithoutJackson(stringValue);
    }
  }
}
无需对默认自定义对象进行任何额外操作,即可序列化此dto对象。您负责创建实例。Jackson只需要访问字段。在我们的例子中,这是一个公共领域

如果DTO用于反序列化,则需要自定义自定义对象:

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector(){
  @Override
  public Class<?> findPOJOBuilder(AnnotatedClass ac) {
    //set analogue of: @JsonDeserialize(builder = DtoBuilderWithFinalFieldsWithoutJackson.Builder.class)
    if (DtoBuilderWithFinalFieldsWithoutJackson.class.equals(ac.getRawType())) {
      return DtoBuilderWithFinalFieldsWithoutJackson.Builder.class;
    } else {
      return super.findPOJOBuilder(ac);
    }
  }
  @Override
  public JsonPOJOBuilder.Value findPOJOBuilderConfig(AnnotatedClass ac) {
    if (DtoBuilderWithFinalFieldsWithoutJackson.class.equals(ac.getRawType())) {
      //both build and with - are default in this case:
      //set analogue of @JsonPOJOBuilder(buildMethodName = "build", withPrefix = "with")
      return new JsonPOJOBuilder.Value("build", "with");
    } else {
      return super.findPOJOBuilderConfig(ac);
    }
  }
});
ObjectMapper ObjectMapper=new ObjectMapper();
objectMapper.setAnnotationIntrospector(新的JacksonAnnotationIntrospector(){
@凌驾
公共类findPOJOBuilder(注释类ac){
//设置类似于:@JsonDeserialize(builder=dtobuilderWithFinalFieldWithOutJackson.builder.class)
if(dtobuilderWithFinalFieldWithOutJackson.class.equals(ac.getRawType())){
返回DtoBuilderWithFinalFieldsWithoutJackson.Builder.class的数据;
}否则{
返回super.findPOJOBuilder(ac);
}
}
@凌驾
public JsonPOJOBuilder.Value findPOJOBuilderConfig(AnnotatedClass ac){
if(dtobuilderWithFinalFieldWithOutJackson.class.equals(ac.getRawType())){
//在这种情况下,build和with都是默认值:
//设置@JsonPOJOBuilder(buildMethodName=“build”,withPrefix=“with”)的模拟值
返回新的JsonPOJOBuilder.Value(“build”,“with”);
}否则{
返回super.findPOJOBuilderConfig(ac);
}
}
});

并在实现中使用此自定义CustomObject。这里有一个测试,可以在这里找到完整的示例:

只需实现您自己的
JsonDeserializer
@rkosegi我猜,如果不基本上枚举所有字段名并手动调用生成器,没有更简单的方法可以做到这一点?您有多种类型的对象需要反序列化还是只有一种?我有3种不同的方法我需要反序列化类型,然后创建3个不同的JsonDeserializer实现,或者使用更健壮的反射方法。实际上,我更进一步,在MixIn上使用了
@JsonDeserialize(builder=…)
,效果很好!这样我就不必画出所有的区域。谢谢
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector(){
  @Override
  public Class<?> findPOJOBuilder(AnnotatedClass ac) {
    //set analogue of: @JsonDeserialize(builder = DtoBuilderWithFinalFieldsWithoutJackson.Builder.class)
    if (DtoBuilderWithFinalFieldsWithoutJackson.class.equals(ac.getRawType())) {
      return DtoBuilderWithFinalFieldsWithoutJackson.Builder.class;
    } else {
      return super.findPOJOBuilder(ac);
    }
  }
  @Override
  public JsonPOJOBuilder.Value findPOJOBuilderConfig(AnnotatedClass ac) {
    if (DtoBuilderWithFinalFieldsWithoutJackson.class.equals(ac.getRawType())) {
      //both build and with - are default in this case:
      //set analogue of @JsonPOJOBuilder(buildMethodName = "build", withPrefix = "with")
      return new JsonPOJOBuilder.Value("build", "with");
    } else {
      return super.findPOJOBuilderConfig(ac);
    }
  }
});