建设监理杂志网站,wordpress html5 登录,wordpress登入后台,网页设计好就业吗根据泛型动态构造jackson的TypeReference引出问题使用TypeReference反序列化的例子根据泛型动态构造TypeReference带泛型的类如何表示#xff1f;完成HttpClient的实现引出问题
将json字符串反序列化为带泛型的类的对象怎么操作#xff1f;怎么根据TypeReferenceList完成HttpClient的实现引出问题
将json字符串反序列化为带泛型的类的对象怎么操作怎么根据TypeReferenceListPeople对象动态构造TypeReferenceResultListPeople对象
使用TypeReference反序列化的例子
有以下类定义
class ResultT {private long code;private T data;
}class People {private String name;
}实例化以下对象
ResultListPeople result new Result();
ListPeople peopleList new ArrayList();
People xiaoHong new People(小红);
People xiaoMing new People(小明);
peopleList.add(xiaoHong);
peopleList.add(xiaoMing);
result.setData(peopleList);其对应的JSON字符串为:
{code:0,data:[{name:小红},{name:小明}]}下面使用jackson的TypeReference来反序列化字符串为以上的对象
String jsonStr {\code\:0,\data\:[{\name\:\小红\},{\name\:\小明\}]};
TypeReferenceResultListPeople typeReference new TypeReferenceResultListPeople() {};
ObjectMapper objectMapper new ObjectMapper();
ResultListPeople listResult objectMapper.readValue(jsonStr, typeReference);当我们构造http客户端的时候有时候不想让用户看到类似ResultListPeople这样的返回只想给用户ListPeople这样的数据那怎么动态构造TypeReference呢
根据泛型动态构造TypeReference
假设我们提供了一个http客户端工具它的定义是这样的。
class HttpClient {public T T get(String url, MapString,Object params, TypeReferenceT typeR) {//获取jsonStr, 假设这里获取到的是{code:0,data:[{name:小红},{name:小明}]}String jsonStr execute(url, params);//todo 解析为枚举类型下面会讲解如何实现}
}假设我们这样调用HttpClient
HttpClient client new HttpClient();
//注意这里的TypeReference的泛型
ListPeople result client.get(http://xxxx, params, new TypeReferenceListPeople());额额额为啥不是TypeReferenceResultListPeople 这就是我们要达到的目的即用户不关注外层包裹的Result只需要指定实际想要的类型即可。下面我们来看下如何实现。
带泛型的类如何表示
首先我们实现一个ParameterizedType的子类至于这个类的作用请往下看
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;public class ParameterizedTypeImpl implements ParameterizedType, Serializable {private final Type[] actualTypeArguments;private final Type ownerType;private final Type rawType;public ParameterizedTypeImpl(Type[] actualTypeArguments, Type ownerType, Type rawType) {this.actualTypeArguments actualTypeArguments;this.ownerType ownerType;this.rawType rawType;}Overridepublic Type[] getActualTypeArguments() {return this.actualTypeArguments;}Overridepublic Type getRawType() {return this.rawType;}Overridepublic Type getOwnerType() {return this.ownerType;}
}我们来解释一下这个类先看一下这个类的继承链
ParameterizedTypeImpl implements ParameterizedType extends TypeType接口的语义是指类型标识java里的所有类。注意Class类也是Type的实现类下面会用到ParameterizedType接口的语义是带泛型的类。
在java9之前jdk是包含了ParameterizedTypeImpl的实现的但在jdk9及以后就没了所以保险起见我们自己需要实现一下。
我们再看一下TypeReference的定义
public abstract class TypeReferenceT implements ComparableTypeReferenceT {protected final Type _type;protected TypeReference() {Type superClass this.getClass().getGenericSuperclass();if (superClass instanceof Class) {throw new IllegalArgumentException(Internal error: TypeReference constructed without actual type information);} else {this._type ((ParameterizedType)superClass).getActualTypeArguments()[0];}}public Type getType() {return this._type;}public int compareTo(TypeReferenceT o) {return 0;}
}这里的_type成员变量即ParameterizedTypeImpl类型。
我们继续看ParameterizedTypeImpl几个成员变量的意思此处以new TypeReferenceResultListPeople为例
rawType 此处的rowTypeResult.class即原始的类是什么actualTypeArguments 此处的actualTypeArgumentsnew Type[]{ListPeople.class},为什么是数组类型是因为泛型里面可以放多个类型我可以这么放ResultListPeople,SetPeople,那么这里的actualTypeArgumentsnew Type[]{ListPeople.class,SetPeople.class}因为是一个Type数组而每个Type又是一个ParameterizedType所以可以向下继续查看嵌套。ownerType 所谓的ownerType只在嵌套类中会出现其他情况为空。举个例子IT.SE则SE的ownerTypeIT
完成HttpClient的实现
class HttpClient {public T T get(String url, MapString,Object params, TypeReferenceT typeR) {//获取jsonStr, 假设这里获取到的是{code:0,data:[{name:小红},{name:小明}]}String jsonStr execute(url, params);ObjectMapper objectMapper new ObjectMapper();//在此处偷梁换柱TypeReferenceResultT resultType new TypeReferenceResultT() {Overridepublic Type getType() {//在外层再包一层Result就是所谓的动态构造是不是很简单return new ParameterizedTypeImpl(new Type[]{typeR.getType()},null, Result.class);}};ResultT listResult objectMapper.readValue(jsonStr, resultType);//此处省略了一下异常判断不可直接这么使用return listResult.getData();}
}然后我们就可以这么调用了
HttpClient client new HttpClient();
//注意这里的TypeReference的泛型
ListPeople result client.get(http://xxxx, params, new TypeReferenceListPeople());OK完结