Fastjson解析多級泛型的幾種方式—使用class文件來解析多級泛型


Fastjson解析多級泛型

前言

現在網上大多數是使用TypeReference 方式來解析JSON數據,這里我提供另外一種方式來解析,使用類文件進行解析,兩種方式我都會給出實際代碼

實例

TypeReference方式
    @GET
@Path("getUserCourse")
@Produces(MediaType.APPLICATION_JSON)
public Result<List<UserCourseDto>> getUserCourse(){
return externalBiz.getUserCourse();
}
public Result<List<UserCourseDto>> getUserCourse(){
String result = restTemplate.getForObject(MOCK_JSON_URL, String.class);
return JSONObject.parseObject(result, new TypeReference<Result<List<UserCourseDto>>>() {});
}

這里使用的基於jsr-339標准的resteasy開發demo

瀏覽器訪問: http://localhost:8080/v1/province/getUserCourse

可以得到json返回的結果

{
status: 0,
message: "1",
data: [
{
openType: "兌換 ",
userID: 30014,
classID: 10376,
className: "趣味職場俚語課程【11月班】",
chargeFee: 106,
classStudyTime: null,
openRMB: 0,
rechargeFee: 0,
awardFee: 0,
openFee: 0,
dateAdded: 1312175789393,
expiredDate: 1323964800000
}
]
}

介紹:

這里使用了提供的TypeReference進行包裝,能夠清晰明了進行解析多級泛型,但是有時候,我們做一些通用的解析框架的時候,可能會用T類型,T類型拿到的是字節碼文件,或者class對象,又該怎么處理呢?請看下面介紹。

class類方式

接口:

接口之類用了一個注解來處理的,沒有直接傳class對象過去,因為在實際項目中,基本都是注解,沒有誰會直接傳class對象。所以我傳的Annotation數組過去啦

    @GET
@Reader(extParamClass = {Result.class,List.class,UserCourseDto.class})
@Path("getUserCourseV2")
@Produces(MediaType.APPLICATION_JSON)
public Result<List<UserCourseDto>> getUserCourseV2(){
Annotation[] annotations = new Annotation[0];
for (Method method : this.getClass().getMethods()) {
if (method.getName().equals("getUserCourseV2")){
annotations = method.getAnnotations();
}
}
return externalBiz.getUserCourseV2(annotations);
}

處理:

public Result<List<UserCourseDto>> getUserCourseV2(Annotation[] annotations) {
final Reader[] readers = {null};
if(annotations != null) {
Arrays
.stream(annotations)
.filter(annotation -> annotation.annotationType().equals(Reader.class))
.findFirst().ifPresent(x -> readers[0] = (Reader) x);
}
Class[] classes = readers[0].extParamClass();
String result = restTemplate.getForObject(MOCK_JSON_URL, String.class);
//這里不用TypeReference方式,直接用class對象來處理

ParameterizedTypeImpl beforeType = null;
if (classes.length!=0){
//支持多級泛型的解析
for (int i = classes.length-1; i >0 ; i--) {
beforeType = new ParameterizedTypeImpl(new Type[]{beforeType == null? classes[i]:beforeType}, null, classes[i - 1]);
}
}
return JSON.parseObject(result,beforeType);
}

代碼評析:

主要起作用的還是這兩行代碼

for (int i = classes.length-1; i >0 ; i--) {
beforeType = new ParameterizedTypeImpl(new Type[]{beforeType == null? classes[i]:beforeType}, null, classes[i - 1]);
}

主要意思是將你的class對象包裝成一個ParameterizedTypeImpl,使用ParameterizedTypeImpl來解析多級泛型,但是要注意的是,每層泛型,都需要用一個ParameterizedTypeImpl對象進行包裝起來才會起作用,因為他會有一個actualTypeArguments 和一個 rawType ,在多級泛型中,用我這里的例子說明,第一層的時候rawType 會是一個Result對象,而actualTypeArguments 會是一個包裝過后的ParameterizedTypeImpl對象,第二層的時候,rawType 會是一個List對象,而actualTypeArguments 會是包裝上一層的對象。后同。PS : 如果這里不知道我說的是什么,請調試的時候結合來看哈

最后也可以正確解析哈~

END


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM