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

Fastjson解析多级泛型的几种方式—使用class文件来解析多级泛型的更多相关文章

  1. JDBC 创建连接对象的三种方式 、 properties文件的建立、编辑和信息获取

    创建连接对象的三种方式 //第一种方式 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/ ...

  2. egg.js 通过 form 和 ajax 两种方式上传文件并自定义目录和文件名

    egg.js 通过 form 和 ajax 两种方式上传文件并自定义目录和文件名 评论:10 · 阅读:8437· 喜欢:0 一.需求 二.CSRF 校验 三.通过 form 表单上传文件 四.通过 ...

  3. JDBC 创建连接对象的三种方式 、 properties文件的建立、编辑和信息获取

    创建连接对象的三种方式 //第一种方式 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/ ...

  4. Java解析Json数据的两种方式

    JSON数据解析的有点在于他的体积小,在网络上传输的时候可以更省流量,所以使用越来越广泛,下面介绍使用JsonObject和JsonArray的两种方式解析Json数据. 使用以上两种方式解析json ...

  5. springMVC两种方式实现多文件上传及效率比较

    springMVC实现 多文件上传的方式有两种,一种是我们经常使用的以字节流的方式进行文件上传,另外一种是使用springMVC包装好的解析器进行上传.这两种方式对于实 现多文件上传效率上却有着很大的 ...

  6. java 20 -10 字节流四种方式复制mp3文件,测试效率

    电脑太渣,好慢..反正速率是: 高效字节流一次读写一个字节数组 > 基本字节流一次读写一个字节数组 > 高效字节流一次读写一个字节 > 基本字节流一次读写一个字节 前两个远远快过后面 ...

  7. 三种方式上传文件-Java

    前言:负责,因为该项目他(jetty嵌入式开始SpringMvc)实现文件上传的必要性,并拥有java文件上传这一块还没有被曝光.并 Http 更多晦涩协议.因此,这种渐进的方式来学习和实践上载文件的 ...

  8. java后台处理解析json字符串的两种方式

    简单说一下背景 上次后端通过模拟http请求百度地图接口,得到的是一个json字符串,而我只需要其中的某个key对应的value. 当时我是通过截取字符串取的,后来觉得不太合理,今天整理出了两种处理解 ...

  9. python爬虫解析页面数据的三种方式

    re模块 re.S表示匹配单行 re.M表示匹配多行 使用re模块提取图片url,下载所有糗事百科中的图片 普通版 import requests import re import os if not ...

随机推荐

  1. Spring源码研究:数据绑定

    在做Spring MVC时,我们只需用@Controllor来标记Controllor的bean,再用@RequestMapping("标记")来标记需要接受请求的方法,方法中第一 ...

  2. vitamio MediaController总是显示在底部的问题

    前面一直用腾讯的x5 tas来播放视频,但是体验效果不好,不能设置播放页,无法获取用户对视频的学习情况,百度了下,发现好多人在使用vitamio,最新版本是5.0的,下载可能要花费点时间,官网上竟然没 ...

  3. Dapper ORM

    参考地址:https://www.cnblogs.com/lunawzh/p/6607116.html 1.连接语句 var conn = new SqlConnection(Configuratio ...

  4. EFCore扩展Select方法(根据实体定制查询语句)

    EFCore扩展Select方法(根据实体定制查询语句)  通常用操作数据库的时候查询返回的字段是跟 我们的定义的实体是不一致的,所以往往针对UI或者接口层创建大量的Model, 而且需要手动对应字段 ...

  5. HTML4.0 需要掌握的主要内容

    常用标签: <html></html> 创建一个HTML文档 <head></head> 设置文档标题和其它在网页中不显示的信息 <title&g ...

  6. 内联函数背景、例子、与普通函数的区别及要注意的地方 ------新标准c++程序设计

    背景: 使用函数能够避免将相同代码重些多次的烦恼,还能减少可执行程序的体积,但也会带来程序运行时间上的开销.函数调用在执行时,首先在栈中为形参和局部变量分配存储空间,然后还要将实参的值复制给形参,接下 ...

  7. NSProcessInfo系统进程信息

    前言 NSProcessInfo 类中包含一些方法,允许你设置或检索正在运行的应用程序(即进程)的各种类型的信息. 1.获取系统进程信息 // 创建系统进程信息对象 NSProcessInfo *pr ...

  8. 协程《三》gevent模块

    一 gevent模块 安装 pip3 install gevent Gevent 是一个第三方库,可以轻松通过gevent实现并发同步或异步编程,在gevent中用到的主要模式是Greenlet, 它 ...

  9. Weekly Contest 118

    970. Powerful Integers Given two non-negative integers x and y, an integer is powerful if it is equa ...

  10. 洛谷P4724 【模板】三维凸包

    题面 传送门 题解 先理一下关于立体几何的基本芝士好了--顺便全都是从\(xzy\)巨巨的博客上抄来的 加减 三维向量加减和二维向量一样 模长 \(|a|=\sqrt{x^2+y^2+z^2}\) 点 ...