fastjson與多級泛型(一)

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章