实际工作中,我们经常对接口调用进行封装,利用泛型返回结果值。
1. 封装函数,统一的返回结果值
所有的调用接口封装成一个公共函数,函数返回一个泛型类。如:
public class ListResultDto<T> extends Dto
{
private static final long serialVersionUID = -7187882293150693618L;
private static final long serialVersionUID = -557141271464869806L;
//返回状态标识
private int rtnCode;
//返回话术
private String rtnMsg = RespConstants.SUCCESS_MSG;
//数据结果
private List<T> result;
}
//提供泛型方法
/**
* 将字符串转化成bean对象
*/
protected <T> T changeJSON2Bean(Class className, String jsonString)
{
if (StringUtil.isNotNullEmpty(jsonString))
{
return (T) JSON.parseObject(jsonString, className);
}
return null;
}
//调用封装函数赋值
public ListResultDto<GlobalNewGoods> getGlobalNewGoodsRecommend(ModuleRequest req)
{
String apiUrl = RestConstants.App.Controller + RestConstants.App.GlobalNewGoodsRecommend;
//封装函数,返回泛型
return requestApi(req, apiUrl, ListResultDto.class);
}
2. 容易出错的地方
泛型取值的过程中,比较容易犯错的的地方是json字符串转换对象,一定要按类型转换。使用fastJson的时候对于泛型的反序列化很多场景下都会使用到TypeReference
错误的做法:
public static ResultDto<JbOrderStatus> getJbOrderStatus(GlobalOrder tbOrder)
{
JSONObject json = new JSONObject();
String url = "getOrderStatus";
ResultDto<JbOrderStatus> dto = requestThird(JSON.toJSONString(tbOrder), url, ResultDto.class);
return dto;
}
正确的做法:
//返回json字符串
String result =requestThird(jsonObject.toJSONString(), url);
//ResultDto泛型类,指定按类型转换
ResultDto<JbOrderStatus> dto = JSONObject.parseObject(result, new TypeReference<ResultDto<JbOrderStatus>>(){});
//ResultDto泛型类,指定按类型转换
ListResultDto<TbGoodsSku> dto = JSONObject.parseObject(result, new TypeReference<ListResultDto<TbGoodsSku>>(){});
类似map,List等泛型,也是如此:
public static void main(String[] args) {
Map<String, Person> map = new HashMap<>(16);
map.put("one", new Person("zhangsan"));
map.put("two", new Person("lisi"));
String jsonStr = JSON.toJSONString(map);
byte[] bytes = jsonStr.getBytes();
String json = new String(bytes);
Map<String, Person> res = JSON.parseObject(json, Map.class);
System.out.println(res.get("one"));
System.out.println(res.get("one").getName());
}
执行时异常:
Exception in thread "main" java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.CommandLineWrapper.main(CommandLineWrapper.java:67)
Caused by: java.lang.ClassCastException: com.alibaba.fastjson.JSONObject cannot be cast to subtitle.io.Person
反序列化时候,虽然添加Map.class,但是没有办法指定Person类型,导致反序列化后的对象为Map<String, Map<String, String>>,而不是Map<String, Person>,所以针对泛型的反序列化,需要使用TypeReference。
Map<String, Person> res = JSON.parseObject(json, new TypeReference<Map<String, Person>>(){});
System.out.println(res.get("one"));
System.out.println(res.get("one").getName());
网友评论