Wil*_*ver 7 java json jersey jackson
使用Jersey我正在定义一项服务:
@Path("/studentIds")
public void writeList(JsonArray<Long> studentIds){
//iterate over studentIds and save them
}
Run Code Online (Sandbox Code Playgroud)
JsonArray的位置是:
public class JsonArray<T> extends ArrayList<T> {
public JsonArray(String v) throws IOException {
ObjectMapper objectMapper = new ObjectMapper(new MappingJsonFactory());
TypeReference<ArrayList<T>> typeRef = new TypeReference<ArrayList<T>>() {};
ArrayList<T> list = objectMapper.readValue(v, typeRef);
for (T x : list) {
this.add((T) x);
}
}
}
Run Code Online (Sandbox Code Playgroud)
这很好用,但是当我做一些更复杂的事情时:
@Path("/studentIds")
public void writeList(JsonArray<TypeIdentifier> studentIds){
//iterate over studentIds and save them by type
}
Run Code Online (Sandbox Code Playgroud)
Bean是一个简单的POJO,如
public class TypeIdentifier {
private String type;
private Long id;
//getters/setters
}
Run Code Online (Sandbox Code Playgroud)
整件事情可怕地打破了.它将所有内容转换为LinkedHashMap而不是实际对象.如果我手动创建一个类,我可以让它工作:
public class JsonArrayTypeIdentifier extends ArrayList<TypeIdentifier> {
public JsonArrayTypeIdentifier(String v) throws IOException {
ObjectMapper objectMapper = new ObjectMapper(new MappingJsonFactory());
TypeReference<ArrayList<TypeIdentifier>> typeRef = new TypeReference<ArrayList<TypeIdentifier>>(){};
ArrayList<TypeIdentifier> list = objectMapper.readValue(v, typeRef);
for(TypeIdentifier x : list){
this.add((TypeIdentifier) x);
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是我试图保持这个漂亮和通用,而不是添加额外的类.有关为什么只发生通用版本的任何线索?
首先,它适用于 Long,因为它是一种本机类型,因此是 JSON 整数的默认绑定。
但至于为什么泛型类型信息没有正确传递:这很可能是由于 JAX-RS API 将类型传递给MessageBodyReaders 和MessageBodyWriters 的方式存在问题——传递java.lang.reflect.Type不足以(不幸的是!)足以传递实际的泛型声明(更多信息)有关这方面的信息,请阅读此博客文章)。
一种简单的解决方法是创建辅助类型,例如:
class MyTypeIdentifierArray extends JsonArray<TypeIdentifier> { }
Run Code Online (Sandbox Code Playgroud)
并使用该类型——事情会“正常工作”,因为超类型的通用信息总是被保留。
| 归档时间: |
|
| 查看次数: |
6660 次 |
| 最近记录: |