zoukankan      html  css  js  c++  java
  • 使用GSON和泛型解析约定格式的JSON串(转)

    时间紧张,先记一笔,后续优化与完善。

    解决的问题:

          使用GSON和泛型解析约定格式的JSON串。

    背景介绍:

           1.使用GSON来进行JSON串与java代码的互相转换。

           2.JSON的格式如下三种:

             

    写道
    #第一种:
    {"success":true,"data":{"averageStarLevel":4.7,"remarkCount":10}}
    #第二种:
    {"success":true,"data":{"page":10,"pageCount":29,"list":[{"starLevel":4,"remarkCotnent":"评价方未及时做出评价,系统默认满意!","remarkTime":"2013-02-27 07:21:48","explainContent":"","postMemberId":"y**f","tpLogoURL":"http://i04.c.aliimg.com/cms/upload/2012/186/684/486681_1232736939.png"},{"starLevel":4,"remarkCotnent":"评价方未及时做出评价,系统默认满意!","remarkTime":"2013-02-27 07:21:48","explainContent":"","postMemberId":"y**f","tpLogoURL":"http://i04.c.aliimg.com/cms/upload/2012/186/684/486681_1232736939.png"}],"statistics":{"star5":20,"star4":40,"star3":30,"star2":10,"star1":0}}}
    #第三种:{"success":true,"data":[{"starLevel":4,"remarkCotnent":"评价方未及时做出评价,系统默认满意!","remarkTime":"2013-02-27 07:21:48","explainContent":"","postMemberId":"y**f","tpLogoURL":"http://i04.c.aliimg.com/cms/upload/2012/186/684/486681_1232736939.png"},{"starLevel":4,"remarkCotnent":"评价方未及时做出评价,系统默认满意!","remarkTime":"2013-02-27 07:21:48","explainContent":"","postMemberId":"y**f","tpLogoURL":"http://i04.c.aliimg.com/cms/upload/2012/186/684/486681_1232736939.png"}]}

    分析:

         在工作时间中,遇到一种场景,就是在应用中调用多个JSON接口,各接口返回的数据内容不一样,如果逐一解析代码会比较臃肿。JSON串如上所列有三种基本格式。经过分析,发现三种JSON串有一个共同的特点。JSON结构一致:

    写道
    {"success":true,"data":##} 

    success:代表是否访问成功

        data:后面跟着所需信息.

       

        基本相同的JSON结构,所以想定义一种通用模型对应到此结构。但是,data中的数据类型不一致。如第一种是简单对象,第二种是对象中嵌套数组,第三种是List。针对data数据类型不一致的情况,使用泛型来解决。

    import java.io.Serializable;
    import java.lang.reflect.ParameterizedType;
    import java.lang.reflect.Type;
    
    import com.google.gson.Gson;
    
    public class CommonJson<T> implements Serializable {
    
        /**
         *
         */
        private static final long serialVersionUID = -3440061414071692254L;
    
        /**
         * 是否成功
         */
        private Boolean success;
    
        /**
         * 数据
         */
        private T data;
    
        public Boolean getSuccess() {
            return success;
        }
    
        public void setSuccess(Boolean success) {
            this.success = success;
        }
    
        public T getData() {
            return data;
        }
    
        public void setData(T data) {
            this.data = data;
        }
    }

     GSON对于泛型的支持不足,为了使GSON对于泛型进行解析,JSON解析与组装代码如下:

           public static CommonJson fromJson(String json, Class clazz) {
            Gson gson = new Gson();
            Type objectType = type(CommonJson.class, clazz);
            return gson.fromJson(json, objectType);
        }
    
        public String toJson(Class<T> clazz) {
            Gson gson = new Gson();
            Type objectType = type(CommonJson.class, clazz);
            return gson.toJson(this, objectType);
        }
    
        static ParameterizedType type(final Class raw, final Type... args) {
            return new ParameterizedType() {
                public Type getRawType() {
                    return raw;
                }
    
                public Type[] getActualTypeArguments() {
                    return args;
                }
    
                public Type getOwnerType() {
                    return null;
                }
            };
        }

     以上两段代码可以满足第一种和第二种JSON的解析,对于第三种,data是List类型的,无法得到List<>的class,所以,针对第三种格式,实现代码如下:

    import java.io.Serializable;
    import java.lang.reflect.ParameterizedType;
    import java.lang.reflect.Type;
    import java.util.List;
    
    import com.google.gson.Gson;
    
    public class CommonJson4List<T> implements Serializable {
    
        /**
         *
         */
        private static final long serialVersionUID = -369558847578246550L;
    
        /**
         * 是否成功
         */
        private Boolean success;
    
        /**
         * 数据
         */
        private List<T> data;
    
        public Boolean getSuccess() {
            return success;
        }
    
        public void setSuccess(Boolean success) {
            this.success = success;
        }
    
        public List<T> getData() {
            return data;
        }
    
        public void setData(List<T> data) {
            this.data = data;
        }
    
        public static CommonJson4List fromJson(String json, Class clazz) {
            Gson gson = new Gson();
            Type objectType = type(CommonJson4List.class, clazz);
            return gson.fromJson(json, objectType);
        }
    
        public String toJson(Class<T> clazz) {
            Gson gson = new Gson();
            Type objectType = type(CommonJson4List.class, clazz);
            return gson.toJson(this, objectType);
        }
    
        static ParameterizedType type(final Class raw, final Type... args) {
            return new ParameterizedType() {
                public Type getRawType() {
                    return raw;
                }
    
                public Type[] getActualTypeArguments() {
                    return args;
                }
    
                public Type getOwnerType() {
                    return null;
                }
            };
        }
    
    }

    测试代码如下:

    import java.util.ArrayList;
    import java.util.List;
    
    import com.alibaba.asc.sharewood.common.http.CommonJson;
    import com.alibaba.asc.sharewood.common.http.CommonJson4List;
    import com.alibaba.asc.sharewood.external.service.model.AverageStarLevelAndCount;
    import com.alibaba.asc.sharewood.external.service.model.Evalution;
    import com.alibaba.asc.sharewood.external.service.model.EvalutionProfile;
    import com.alibaba.asc.sharewood.external.service.model.StarLevelStatistics;
    
    public class Test {
    
        @SuppressWarnings("unchecked")
        public static void main(String[] args) {
    
            CommonJson<AverageStarLevelAndCount> cj = new CommonJson<AverageStarLevelAndCount>();
            AverageStarLevelAndCount data = new AverageStarLevelAndCount();
            data.setAverageStarLevel(4.7f);
            data.setRemarkCount(10);
    
            cj.setSuccess(Boolean.TRUE);
            cj.setData(data);
    
            String res1 = cj.toJson(AverageStarLevelAndCount.class);
    
            System.out.println(res1);
    
            CommonJson<AverageStarLevelAndCount> cj2 = CommonJson.fromJson(res1,
                    AverageStarLevelAndCount.class);
    
            System.out.println(cj2.getSuccess());
            System.out.println(cj2.getData().getAverageStarLevel());
    
            EvalutionProfile p = new EvalutionProfile();
            p.setPage(10);
            p.setPageCount(29);
    
            StarLevelStatistics s = new StarLevelStatistics();
            s.setStar1(0);
            s.setStar2(10);
            s.setStar3(30);
            s.setStar4(40);
            s.setStar5(20);
    
            p.setStatistics(s);
    
            Evalution e1 = new Evalution();
    
            e1.setStarLevel(4);
            e1.setRemarkTime("2013-02-27 07:21:48");
            e1.setRemarkCotnent("评价方未及时做出评价,系统默认满意!");
            e1.setTpLogoURL("http://i04.c.aliimg.com/cms/upload/2012/186/684/486681_1232736939.png");
            e1.setExplainContent("");
            e1.setPostMemberId("y**f");
    
            Evalution e2 = new Evalution();
    
            e2.setStarLevel(4);
            e2.setRemarkTime("2013-02-27 07:21:48");
            e2.setRemarkCotnent("评价方未及时做出评价,系统默认满意!");
            e2.setTpLogoURL("http://i04.c.aliimg.com/cms/upload/2012/186/684/486681_1232736939.png");
            e2.setExplainContent("");
            e2.setPostMemberId("y**f");
    
            List<Evalution> le = new ArrayList<Evalution>();
            le.add(e1);
            le.add(e2);
    
            p.setList(le);
    
            CommonJson<EvalutionProfile> ce = new CommonJson<EvalutionProfile>();
    
            ce.setSuccess(Boolean.TRUE);
            ce.setData(p);
    
            String res2 = ce.toJson(EvalutionProfile.class);
    
            System.out.println(res2);
    
            String ps = "{"data":{"pageCount":29,"page":"1","list":[{"starLevel":4,"remarkTime":"2013-04-10 05:17:42","explainTime":"","remarkContent":"评价方未及时做出评价,系统默认满意!","tpLogoURL":"","explainContent":"","postMemberId":"b**6"},{"starLevel":4,"remarkTime":"2013-04-05 04:42:40","explainTime":"","remarkContent":"评价方未及时做出评价,系统默认满意!","tpLogoURL":"","explainContent":"","postMemberId":"b**8"},{"starLevel":4,"remarkTime":"2013-03-20 00:52:18","explainTime":"","remarkContent":"评价方未及时做出评价,系统默认满意!","tpLogoURL":"","explainContent":"","postMemberId":"b**5"},{"starLevel":4,"remarkTime":"2013-03-07 01:51:01","explainTime":"","remarkContent":"评价方未及时做出评价,系统默认满意!","tpLogoURL":"","explainContent":"","postMemberId":"b**7"},{"starLevel":4,"remarkTime":"2013-03-06 03:38:57","explainTime":"","remarkContent":"评价方未及时做出评价,系统默认满意!","tpLogoURL":"","explainContent":"","postMemberId":"z**2"},{"starLevel":4,"remarkTime":"2013-03-06 03:17:33","explainTime":"","remarkContent":"评价方未及时做出评价,系统默认满意!","tpLogoURL":"","explainContent":"","postMemberId":"b**2"},{"starLevel":4,"remarkTime":"2013-03-03 01:40:17","explainTime":"","remarkContent":"评价方未及时做出评价,系统默认满意!","tpLogoURL":"","explainContent":"","postMemberId":"a**6"},{"starLevel":4,"remarkTime":"2013-03-01 02:41:31","explainTime":"","remarkContent":"评价方未及时做出评价,系统默认满意!","tpLogoURL":"","explainContent":"","postMemberId":"b**4"},{"starLevel":4,"remarkTime":"2013-02-28 03:20:45","explainTime":"","remarkContent":"评价方未及时做出评价,系统默认满意!","tpLogoURL":"","explainContent":"","postMemberId":"t**y"},{"starLevel":4,"remarkTime":"2013-02-27 07:21:48","explainTime":"","remarkContent":"评价方未及时做出评价,系统默认满意!","
                    + ""tpLogoURL":""
                    + "http://i04.c.aliimg.com/cms/upload/2012/186/684/486681_1232736939.png","explainContent":"","postMemberId":"y**f"}],"
                    + ""statistics":{"star5":59,"star4":38,"star3":2,"star2":1,"star1":0}},"success":true}";
    
            CommonJson<EvalutionProfile> re = CommonJson.fromJson(ps,
                    EvalutionProfile.class);
    
            System.out.println(re.getData().getStatistics().getStar5());
    
            System.out.println(re.getData().getPageCount());
    
            System.out.println(re.getData().getList().get(0).getPostMemberId());
    
            CommonJson4List<Evalution> cjl = new CommonJson4List<Evalution>();
    
            cjl.setSuccess(Boolean.TRUE);
            cjl.setData(le);
    
            System.out.println("###" + cjl.toJson(Evalution.class));
    
            String sList = "{"data":[{"starLevel":4,"remarkCotnent":"评价方未及时做出评价,系统默认满意!","remarkTime":"2013-02-27 07:21:48","explainContent":"","postMemberId":"y**f","tpLogoURL":"http://i04.c.aliimg.com/cms/upload/2012/186/684/486681_1232736939.png"},{"starLevel":4,"remarkCotnent":"评价方未及时做出评价,系统默认满意!","remarkTime":"2013-02-27 07:21:48","explainContent":"","postMemberId":"y**f","tpLogoURL":"http://i04.c.aliimg.com/cms/upload/2012/186/684/486681_1232736939.png"}],"success":true}";
    
            CommonJson4List<Evalution> cjle = CommonJson4List.fromJson(sList,
                    Evalution.class);
    
            System.out.println("***"
                    + cjle.getData().get(0).getPostMemberId());
    
        }
    }

    执行结果如下:

    {"success":true,"data":{"averageStarLevel":4.7,"remarkCount":10}}
    true
    4.7
    {"success":true,"data":{"page":10,"pageCount":29,"list":[{"starLevel":4,"remarkCotnent":"评价方未及时做出评价,系统默认满意!","remarkTime":"2013-02-27 07:21:48","explainContent":"","postMemberId":"y**f","tpLogoURL":"http://i04.c.aliimg.com/cms/upload/2012/186/684/486681_1232736939.png"},{"starLevel":4,"remarkCotnent":"评价方未及时做出评价,系统默认满意!","remarkTime":"2013-02-27 07:21:48","explainContent":"","postMemberId":"y**f","tpLogoURL":"http://i04.c.aliimg.com/cms/upload/2012/186/684/486681_1232736939.png"}],"statistics":{"star5":20,"star4":40,"star3":30,"star2":10,"star1":0}}}
    59
    29
    b**6
    {"success":true,"data":[{"starLevel":4,"remarkCotnent":"评价方未及时做出评价,系统默认满意!","remarkTime":"2013-02-27 07:21:48","explainContent":"","postMemberId":"y**f","tpLogoURL":"http://i04.c.aliimg.com/cms/upload/2012/186/684/486681_1232736939.png"},{"starLevel":4,"remarkCotnent":"评价方未及时做出评价,系统默认满意!","remarkTime":"2013-02-27 07:21:48","explainContent":"","postMemberId":"y**f","tpLogoURL":"http://i04.c.aliimg.com/cms/upload/2012/186/684/486681_1232736939.png"}]}
    y**f

    Ps:文中说到Gson对泛型的支持不足,其实是不正确的,Gson对泛型做了以下支持:

    public static CommonJson4List fromJson(String json, Class clazz) {  
            Gson gson = new Gson();  
            Type objectType = new TypeToken<CommonJson4List<clazz>>() {}.getType();  
            return gson.fromJson(json, objectType);  
        }  

    只需将获取类型的泛型类作为TypeToken的泛型参数构造一个匿名的子类,就可以通过getType方法获取一个parameterized类型,结果与type方法一致。

  • 相关阅读:
    java OA系统 自定义表单 流程审批 电子印章 手写文字识别 电子签名 即时通讯
    flowable 获取当前任务流程图片的输入流
    最新 接口api插件 Swagger3 更新配置详解
    springboot 集成 activiti 流程引擎
    java 在线考试系统源码 springboot 在线教育 视频直播功能 支持手机端
    阿里 Nacos 注册中心 配置启动说明
    springboot 集成外部tomcat war包部署方式
    java 监听 redis 过期事件
    springcloudalibaba 组件版本关系
    java WebSocket 即时通讯配置使用说明
  • 原文地址:https://www.cnblogs.com/qq78292959/p/3781808.html
Copyright © 2011-2022 走看看