zoukankan      html  css  js  c++  java
  • 复杂JSON反序列化为类对象

    有3种常用的反序列化库,gson和fastjson都很棒,json-lib有很大的局限性不推荐使用!

    1. net.sf.json(json-lib)

    只能用于解析简单的JSON,稍微复杂点的例如,类里面有含有List属性,这个没有问题(在0.9这个版本不行,但2.3可以,应该是bug修复了),但是List属性中类中再含有List就不支持了,言外之意,类中含有List只能一层,再深就会报如下错误:

    net.sf.json.JSONException: java.lang.NoSuchMethodException: Unknown property 

    代码如下:

    Object object = restTemplate.getForObject(interfaceUrl, Object.class);
    net.sf.json.JSONObject json = net.sf.json.JSONObject.fromObject(object);
    Map<String, Class> classMap = new HashMap<String, Class>();
    classMap.put("productInfoList", ProductInfoList.class);
    CobraProductInfoListDto j = (CobraProductInfoListDto) net.sf.json.JSONObject.toBean(json,
    CobraProductInfoListDto.class, classMap);

    2.gson

    String interfaceUrl = globalSettingsMapper.getValueByKey(Constant.Product.interfaceUrl);
    RestTemplate restTemplate = new RestTemplate();
    Object object = restTemplate.getForObject(interfaceUrl, Object.class);
    Gson gs= new Gson();
    String json = gs.toJson(object);
    CobraProductInfoListDto j = gs.fromJson(json, CobraProductInfoListDto.class);
    System.out.println(j.getProductInfoList().get(0).getPLogo().getLogoName());

    3.fastjson

    String interfaceUrl = globalSettingsMapper.getValueByKey(Constant.Product.interfaceUrl);
    RestTemplate restTemplate = new RestTemplate();
    Object object = restTemplate.getForObject(interfaceUrl, Object.class);
    Gson gs = new Gson();
    String json = gs.toJson(object);
    CobraProductInfoListDto j =JSON.parseObject(json, CobraProductInfoListDto.class);
    String rateType = j.getProductInfoList().get(1).getPInterest().getCurrency();

    另外推荐一个非常棒的根据Json生成Java/C#实体类的工具:http://tool.chinaz.com/tools/json2entity.aspx,很是方便!但是注意生成的代码可能需要优化,比如有些重复的类可以合为一个,数据类型上需要把DateTime改为String,因为转换时存在数据的特例,可能某些字段需要由int改为double

    在反序列化时,在如何定义类文件方式上,如下2种都可以,根据实际情况选取

    CobraProductInfoListDto j = JSON.parseObject(json, CobraProductInfoListDto.class);  //优势:访问方便,所有的全封装在一个类中,缺点是可能会多定义一些类

    Map<String, List<ProductInfoList>> k = JSON.parseObject(json,
    new TypeReference<Map<String, List<ProductInfoList>>>() {
    }); //优势:和上面的方式比较起来可以少定义一些类文件

    --------------------------------------------------------------

    Json转换的时候切记:收尾不能包含引号,否则会报错,例子:

    正确: {"name":"yuanyuan","description":"Randy chinese name"}

    错误: "{"name":"yuanyuan","description":"Randy chinese name"}"

    JSON字符串前面用引号包含,fastjson/gson所报错误的区别,感觉阿里的更易懂,google也不不能算错,但是理解起来费劲
    com.alibaba.fastjson.JSONException: syntax error, expect {, actual string, pos 0
    com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 2 path $

    截取字符串收尾字符,例如去引号:.substring(1,json.length()-1 )

    转义工具类:从StringEscapeUtils.escapeJava/unescapeJava

    -----------------------------------------

    发现google的gson在转换日期类型的时候会报错,但用阿里的fastjson就没有问题

    Failed to parse date ["1454032939000']: Invalid time zone indicator '3'

    期待的结果是://CST是中国标准时

    Fri Jan 29 10:02:19 CST 2016

    ---------------------------------------------

    反序列化json报错如下:

    com.alibaba.fastjson.JSONException: illegal identifier : pos 1, json : {"appStatus":"MADELOAN|MADELOANCOMPLETED","category":"CREDIT_LOAN","changedTime":1454032939000,"cobraAppStatus":"MADELOAN","createdTime":1454032581000,"id":64}

    解决办法是把下面多余的转义字符给去掉:StringEscapeUtils.unescapeJava(String str)

    {"appStatus":"MADELOAN|MADELOANCOMPLETED","category":"CREDIT_LOAN","changedTime":1454032939000,"cobraAppStatus":"MADELOAN","createdTime":1454032581000,"id":64}

  • 相关阅读:
    没有 Lambda 演算何来匿名函数——匿名函数(匿名方法和Lambda)、委托、LINQ
    HTML 4.01 符号实体
    利用 IHttpModule 自定义 HTTP 处理模块
    数据结构单链表
    Ext.Net 1.2.0_Ext.Net.RendererFormat 常用数据格式转换呈现格式
    ASP.NET 以 Request.Querystring、Request.Form 或 Request.Params 获取客户端的数据
    Flex>连接WebService
    java.sql.SQLException: 关闭的连接
    jsp>SmartUpload相关类说明
    flex>样式和主题
  • 原文地址:https://www.cnblogs.com/researcher/p/7298579.html
Copyright © 2011-2022 走看看