重构方法以使用泛型进行反序列化

时间:2019-09-17 13:54:29

标签: java generics jackson deserialization

这是我要重构的方法:

public static List<ComponentPOCO> parseJsonComponentFromString(String fileContents){

        try {
            ObjectMapper mapper = new ObjectMapper()
                    .enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
                    .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            List<ComponentPOCO> component = mapper.readValue(fileContents, new TypeReference<List<ComponentPOCO>>() {});
            return component;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

我正在尝试重构反序列化方法,以使用泛型来使我能够反序列化任何类型。对于不在集合中的对象,我可以做到这一点,就像这样:

public static <T> T parseProductData(String jsonData, Class<T> typeClass) throws IOException, IllegalAccessException {
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    T inputMessage = objectMapper.readValue(jsonData, typeClass);
    return inputMessage;
}

以下是我要反序列化到ComponentPOCO类中的数据的示例:

[
      {   "artifactPathOrUrl": "http://www.java2s.com/Code/JarDownload/sample/sample.jar.zip",
        "namespace": "exampleNamespace1",
        "name": "exampleName1",
        "tenant": "exampleTenant1"
      },

      {   
        "artifactPathOrUrl": "http://www.java2s.com/Code/JarDownload/sample-calculator/sample-calculator-bundle-2.0.jar.zip",
        "namespace": "exampleNamespace1",
        "name": "exampleName2",
        "tenant": "exampleTenant1"
      },
      {   
        "artifactPathOrUrl": "http://www.java2s.com/Code/JarDownload/helloworld/helloworld.jar.zip",
        "namespace": "exampleNamespace1",
        "name": "exampleName3",
        "tenant": "exampleTenant1"
      },
      {   
        "artifactPathOrUrl": "http://www.java2s.com/Code/JarDownload/fabric-activemq/fabric-activemq-demo-7.0.2.fuse-097.jar.zip",
        "namespace": "exampleNamespace1",
        "name": "exampleName4",
        "tenant": "exampleTenant1"
      }
]

这是ComponentPOCO类型的代码:

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.*;
import lombok.experimental.Accessors;
import org.apache.pulsar.common.io.SinkConfig;
import org.apache.pulsar.common.io.SourceConfig;

import java.util.List;
import java.util.Map;

@Setter
@Getter
@EqualsAndHashCode
@ToString
@Accessors(chain = true)
@Data
public class ComponentPOCO {
    @JsonProperty
    private String namespace;
    @JsonProperty
    private String tenant;
    @JsonProperty
    private String name;
    @JsonProperty
    private String type;
    @JsonProperty
    private String destinationTopicName;
    @JsonProperty
    private String artifactPathOrUrl;
    @JsonProperty
    private String className;
    @JsonProperty
    private List<String> inputs;
    @JsonProperty
    private String output;
    @JsonProperty
    private Map<String, Object> userConfig;
    @JsonProperty
    private String logTopic;
    @JsonProperty
    private Map<String, Object> configs;
    @JsonProperty
    private Integer parallelism;
    @JsonProperty
    public String sinkType;
    @JsonProperty
    private String sourceType;
    @JsonProperty
    public String runtimeFlags;
}

有没有办法让我使用像这样的泛型反序列化整个列表?

1 个答案:

答案 0 :(得分:0)

您可以提取与Jackson的所有互动,以进行额外的授课,并在其中隐藏所有困难。 ObjectMapper可以创建和配置一次。对于单个对象,您可以使用readValue(String content, Class<T> valueType)方法,对于集合,您需要构建TypeReference并使用readValue(String content, TypeReference valueTypeRef)方法。简单的实现可能如下所示:

class JsonMapper {

  private final ObjectMapper mapper = new ObjectMapper();

  public JsonMapper() {
    // configure mapper instance if required
    mapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
    mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
    // etc...
  }

  public String serialise(Object value) {
    try {
      return mapper.writeValueAsString(value);
    } catch (JsonProcessingException e) {
      throw new IllegalStateException("Could not generate JSON!", e);
    }
  }

  public <T> T deserialise(String payload, Class<T> expectedClass) {
    Objects.requireNonNull(payload);
    Objects.requireNonNull(expectedClass);

    try {
      return mapper.readValue(payload, expectedClass);
    } catch (IOException e) {
      throw new IllegalStateException("JSON is not valid!", e);
    }
  }

  public <T> List<T> deserialiseList(String payload, Class<T> expectedClass) {
    Objects.requireNonNull(payload);
    Objects.requireNonNull(expectedClass);

    try {
      return mapper.readValue(payload, constructListTypeOf(expectedClass));
    } catch (IOException e) {
      throw new IllegalStateException("JSON is not valid!", e);
    }
  }

  private <T> CollectionType constructListTypeOf(Class<T> expectedClass) {
    return mapper.getTypeFactory().constructCollectionType(List.class, expectedClass);
  }
}

和用法:

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.CollectionType;
import java.io.IOException;
import java.util.List;
import java.util.Objects;

public class JsonApp {

  public static void main(String[] args) {
    JsonMapper mapper = new JsonMapper();
    System.out.println(mapper.deserialise("{\"id\":1233}", A.class));
    System.out.println(mapper.deserialiseList("[{\"id\":4567}]", A.class));
  }
}

class A {
  private int id;

  public int getId() {
    return id;
  }

  public void setId(int id) {
    this.id = id;
  }

  @Override
  public String toString() {
    return "A{" + "id=" + id + '}';
  }
}

上面的代码显示:

A{id=1233}
[A{id=4567}]

另请参阅:

相关问题