fastjson与多级泛型(一)

霸气de小男生 提交于 2019-12-28 14:38:55

1.问题背景

知道方法的Method和方法的响应字符串,将字符串转换为returnType。Method可能包含多级泛型

2.核心内容

method.getGenericReturnType  获取方法返回类型泛型类
ParameterizedTypeImpl  记录泛型嵌套关系

3.基本思路

先利用getGenericReturnType 获取方法返回类型泛型类,然后对返回的Type做判断,分两部分进行处理。核心代码如下:


 
    public static Object transfer1(String req,String className,String methodName ) throws  Exception{
        Class clazz=Class.forName(className);
        Method method=clazz.getDeclaredMethod(methodName);
        Type type=method.getGenericReturnType();
        if(type instanceof ParameterizedType){
            ParameterizedType type1=(ParameterizedType) type;
            ParameterizedTypeImpl beforeType = new ParameterizedTypeImpl(type1.getActualTypeArguments(), type1.getOwnerType(),type1.getRawType());
            return JSON.parseObject(req,beforeType);
        }else{  //没有泛型
            return JSON.parseObject(req,(Class)type);
        }
    }

4.测试

泛型类Result ,使用了lombok插件

package com.design.pattern.generic;

import lombok.Data;

@Data
public class Result<T> {
    private int ret;
    private String msg;
    private T data;
    // 此处省略getter和setter方法
}

泛型类 Item

package com.design.pattern.generic;

import lombok.Data;

@Data
public class Item<T> {
    private String name;
    private String value;
    T t;
    // 此处省略getter和setter方法
}

测试类:Test

package com.design.pattern.generic;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.fastjson.util.ParameterizedTypeImpl;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*;

@Slf4j
public class Test {
    public Result<Item<String>> getRoushan(){
        return null;
    }

    public Result<List<String>> getRoushan1(){
        return null;
    }
    public Result getRoushan2(){
        return null;
    }

    private  <T> ResponseEntity<Map<String, T>> getRoushan3() {
        String json = "{\"code\":\"1\",\"msg\":\"Success\",\"data\":{\"orderid1\":{\"address\":\"street 1\",\"pay\":\"111.0\",\"productId\":\"1342546\"}}}";
        return null;
        //return JSONObject.parseObject(json, new TypeReference<ResponseEntity<Map<String, T>>>(){});
    }


    public static void main(String[] args) throws  Exception{
        //getRoushan
        Item<String> item=new Item<>();
        item.setName("dddd");
        item.setValue("ddd");
        item.setT("bbb");
        log.info(JSON.toJSONString(item));
        Result<Item<String>> result=new Result<>();
        result.setMsg("111");
        result.setRet(00);
        result.setData(item);
        log.info(JSON.toJSONString(result));
        String resultStr=JSON.toJSONString(result);
        //getRoushan1
        List<String> list=new ArrayList<>();
        list.add("1111");
        list.add("2222");
        list.add("3333");
        Result<List<String>> result2=new Result<>();
        result2.setMsg("111");
        result2.setRet(00);
        result2.setData(list);

        Result<List<String>> ret1=
                (Result<List<String>>) transfer1(JSON.toJSONString(result2),"com.design.pattern.generic.Test","getRoushan1");
        log.info("hold");
        //getRoushan1 end

        ////getRoushan3
        Result result3=new Result<>();
        result3.setMsg("111");
        result3.setRet(00);
        Result ret2=
                (Result) transfer1(JSON.toJSONString(result3),"com.design.pattern.generic.Test","getRoushan2");
        log.info("hold");

        //
        String json = "{\"code\":\"1\",\"msg\":\"Success\",\"data\":{\"orderid1\":{\"address\":\"street 1\",\"pay\":\"111.0\",\"productId\":\"1342546\"}}}";
        ResponseEntity<Map<String, Map>> ret=(ResponseEntity<Map<String, Map>>)transfer1(json,"com.design.pattern.generic.Test","getRoushan3");
        log.info("hold");
    }

    //不能直接拿来用
    //Exception in thread "main" java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl cannot be cast to com.alibaba.fastjson.util.ParameterizedTypeImpl
    public static Object transfer1(String req,String className,String methodName ) throws  Exception{
        Class clazz=Class.forName(className);
        Method method=clazz.getDeclaredMethod(methodName);
        Type type=method.getGenericReturnType();
        if(type instanceof ParameterizedType){
            ParameterizedType type1=(ParameterizedType) type;
            ParameterizedTypeImpl beforeType = new ParameterizedTypeImpl(type1.getActualTypeArguments(), type1.getOwnerType(),type1.getRawType());
            return JSON.parseObject(req,beforeType);
        }else{  //没有泛型
            return JSON.parseObject(req,(Class)type);
        }
    }
}

5.可能的遗留问题

如果不停的new ParameterizedTypeImpl 可能会造成内存泄露,基本解决思路就是把Type用ConcurrentHashMap缓存起来

具体可参考下面两篇文章:

https://www1350.github.io/hexo/post/bc931ae8.html

https://www.jianshu.com/p/adfde1a318b0

6.相关的源码已经传至git 

https://github.com/hbulitong/pattern

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!