[英]Java: How to write a generic that deserializes a list/collection?
我正在尝试重构我的反序列化方法以使用泛型来反序列化任何类型。 对于不在集合中的对象,我可以很好地执行此操作,如下所示:
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;
}
这是我要重构的方法:
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 List<T> T parseJsonComponentFromString(String fileContents, Class<T> typeClass){
try {
ObjectMapper mapper = new ObjectMapper()
.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
List<T> component = mapper.readValue(fileContents, new TypeReference<List<T>>() {});
return component;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
但是,此代码无法编译,因为它没有正确使用 Java 泛型。 如何将我的 JSON 对象反序列化为通用列表/集合/类似类型?
这是我反序列化到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;
}
您的代码有几个问题。 使此代码按我想的方式工作的最快方法是用以下方法替换该方法:
public LinkedHashMap<String,T> parseJsonComponentFromString(String fileContents){
try {
ObjectMapper mapper = new ObjectMapper()
.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
return mapper.readValue(fileContents, new TypeReference<T>() {});
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
因为ObjectMapper.readValue
返回一个LinkedHashMap<String,T>
(我不知道为什么它在 javadocs 中只说 T)
然后,如果您知道键,则使用get(key_name)
查找解析后的字符串,如果不知道也不想假设它们,则forEach
查找。 最后一个更好,但需要您使用 java 8+ 并了解 lambda 表达式和函数式接口。 这里有一个教程。 这是另一个。
顺便说一句,我再次借机指出这段代码有很多错误,您可能需要重新设计整个系统。 如果您真的真的必须使用列表,那么您会遇到不同的问题:“如何将 LinkedHashMap 转换为列表? ”。 猜猜最快捷的方法是实现前面提到的 forEach 并将每个元素推送到 List 上。
也就是说,像这样:
LinkedHashMap<String,Integer> linkedHashMap = XXX.parseJsonComponentFromString(yyy);
LinkedList<T> list = new LinkedList<T>();
linkedHashMap.forEach((k,i) -> list.add(i));
希望我有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.