文档章节

Jackson异常情况处理

BKC
 BKC
发布于 2016/09/29 17:05
字数 1599
阅读 215
收藏 6

1、空值转换-异常情况:

      Can not instantiate value of type [map type; class java.util.HashMap, [simple type, class java.lang.String] -> [simple type, class java.lang.String]] from JSON String; no single-String constructor/factory method  

解决方法,在ObjectMapper配置中增加:   ```  mapper.configure(DeserializationConfig.Feature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true) ;


2、转义字符-异常情况:
        org.codehaus.jackson.JsonParseException: Illegal unquoted character ((CTRL-    CHAR, code 9)): has to be escaped using backslash to be included in string value  at [Source: java.io.StringReader@10cfc2e3; line: 1, column: 2461]   
        解决办法,在ObjectMapper配置中增加:
 ```
mapper.configure(Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true) ;  

3、定义针对日期类型的反序列化时的数据格式    ``` mapper.getDeserializationConfig().setDateFormat(new SimpleDateFormat("yyyy-MM-dd  HH:mm:ss"));


   jackson在http接口测试环境中的应用

        这里先简单的做下jackson的介绍:jackson可以很方便并且高效的将json对象转化成Java对象,也可以将Java对象转换成json对象和xml文档。Jackson有几个显著的特点:性能高,对于复杂对象和大数据量对象的序列化和反序列化,表现出比同类工具包(如gson,json-lib等)更优的性能;功能强,绑定所有JDK中的通用类以及Java Bean Class,Collection,Map和Enum;无依赖,除了JDK外无任何他依赖;完全开源,并且有丰富的文档和用户群体,便于自学。

        在进行http请求的接口测试的过程中,我们需要灵活方便的处理http请求返回数据,使json串反序列化成为java对象,这样我们才能方便地对返回数据进行校验。如何试用jackson进行反序列化,网上内容很多,所以在此补赘述。我想重点说下在接口测试过程中需要注意的点和可能会遇到的问题的解决办法。

【注意点1】: 尽可能使用开发人员使用的数据对象类作为反序列化时的mapper类。
        通常情况下,浏览器在发送http请求向服务端应用请求数据的时候,客户端应用都会依赖一个服务端的client包,以便于反序列化json数据后,形成用于vm模板的渲染所需要的java对象。这样就为我们测试http接口提供了便利,我们只需要在我们测试应用中依赖这个client的jar包,就可以方便的运用这些对象去组装我们的mapper。

【注意点2】: 当开发人员提供的数据对象类“不好用”的时候,需要自行创建pojo类,或者使用JDK的原生数据对象。
    ObjectMapper初始化配置的代码:

ObjectMapper objectMapper = newObjectMapper(); //配置为true表示mapper接受只有一个元素的数组的反序列化 objectMapper.configure(Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY,true); //配置为false表示mapper在遇到mapper对象中存在json对象中没有的数据变量时不报错,可以进行反序列化 objectMapper.configure(Feature.FAIL_ON_UNKNOWN_PROPERTIES,false); //新版的jackson设置mapper的方法,功能同上 objectMapper.getDeserializationConfig().without(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES); //定义针对日期类型的反序列化时的数据格式 objectMapper.getDeserializationConfig().setDateFormat(newSimpleDateFormat("yyyy-MM-dd HH:mm:ss")); 下面是处理json的工具类代码: public static <T> T getObjectFromJsonString(String jsonString, TypeReference<T> tr) { if(jsonString == null||"".equals(jsonString)){ returnnull; } else { try { return (T)objectMapper.readValue(jsonString, tr); }catch(Exception e) { e.printStackTrace(); } } return null; }

此方法采用了泛型,是为了抽象json返回对象的数据类型,以便后续开发通用的测试验证类

   下面是调用类的方法的代码:

actDO = JsonUtils.getObjectFromJsonString(jsonStr, new TypeReference<BaseResponseModel<PublishCommentResultMapper>>(){});

或者

actDO = JsonUtils.getObjectFromJsonString(jsonStr, new TypeReference<BaseResponseModel<Map<String,String>>>() {});

   下面是BaseResponseModel的代码:

public class BaseResponseModel<T> implements Serializable{ private static final long serialVersionUID = 5393610697317077173L; private List<T> result; private boolean isSuccess; private String errorMsg; private int errorCode; private Integer total; //getter/setter省略 }


   BaseResponseModel封装了http请求返回的通用成员变量,例如:ErrorCode,IsSuccess,Total等
Mapper对象实例:

public class InfoAndRateMapper implements Serializable{ private static final long serialVersionUID = 1L; private List<BrandContentInfoDO> info; private List<Rate> rate; //getter/setter省略 }

   经常碰到的问题及解决办法:

Exception1:
 Unrecognized field “INFO” (Class com.tmall.brand.api.test.model.InfoAndRateMapper), not marked as ignorable
【异常解释】:当反序列化的json对象中有“INFO”,但mapper对象中没有该字段时报错。
    【解决办法】:在mapper中增加此变量
    
Exception2:

 Unrecognized field “typeString”

   【异常解释】:反序列化过程中出现不可识别的成员变量

   【解决办法】:增加mapper的属性配置:objectMapper .configure(Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);此参数默认是true,即检查映射关系,当设置为false以后,objectMapper将忽略需解析的json串中“不认识”的字段

   例如:mapper对象中有private String name;的对象,当json对象中并没有此变量,那当这个属性值设置为false时,可成功反序列化。

   Exception3:

   org.codehaus.jackson.map.JsonMappingException : Can not instantiate value of type [collection type; class java.util.ArrayList, contains [simple type, class java.lang.Long]] from JSON String; no single-String constructor/factory method (through reference chain: com.tmall.brand.api.test.model.GetInfoAndRateRespModel["result"]->com.tmall.brand.api.test.model.InfoAndRateMapper["INFO"]->com.tmall.brand.service.domain.ratenews.BrandNewsQuery["typeList"])

   【异常解释】:jackson无法实例化json对象中变量类型的值

   【解决办法】:@JsonIgnoreProperties({ “typeList”})

   在mapper类之前加此标签忽略这个字段的反序列化

   Exception4:

   Can not deserialize instance of java.util.ArrayList out of START_OBJECT token

   【异常解释】:无法反序列化没有START_OBJECT token的ArrayList

   【解决办法】:增加mapper的属性配置:

objectMapper.configure(Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);

  Exception5:
    org.codehaus.jackson.map.JsonMappingException : No suitable constructor found for type [simple type, class com.taobao.matrix.snsplugin.common.enumconstants.EnumResultStatus]: can not instantiate from JSON object (need to add/enable type information?)
     at [Source: java.io.StringReader@98350a; line: 1, column: 89] (through reference chain: com.tmall.brand.api.test.model.BaseResponseModel["result"]->com.tmall.brand.api.test.model.PublishCommentResultMapper["status"])
    【异常解释】:jackson无法实例化json对象,没有找到适合的构造函数。
    【解决办法】:jackson在进行反序列号的时候,需要Mapper类是普通的pojo类,并且类中的变量都需要有setXXX的set方法,如果没有set方法或者没有“正确”的set方法,就会报无法实例化JSON对象的异常
    例如:
    1、json对象的一个变量为

private boolean isSuccess;

   自动生成代码后的set方法为:(根据你自己的eclipse 的autogen来决定自动生成的代码模板)

public void setSuccess(boolean isSuccess) { this.isSuccess = isSuccess; }

   如果是这样,jackson在反序列化的时候就会报此异常,应改为:

public void setIsSuccess( boolean isSuccess) { this.isSuccess = isSuccess; }

   2、当JSON对象为:

public class XXXStatus extends XXXResultStatus<XXXStatus>{ private static final long serialVersionUID = 2385584133823877965L;

public static final Map<Integer, XXXStatus> codeMap = newHashMap<Integer,XXXStatus>();

public static final XXXStatus SUCCESS = newXXXStatus(0,"xxx","xxx");

private XXXStatus(intcode,Stringmsg,StringfrontMsg){

    super(code, msg, frontMsg);

    codeMap.put(code,this);

}

public static final XXXStatus getRelationStatus(intcode){

    XXXStatus satus = codeMap.get(code);

    if(satus== null){

        returnSYSTEM_ERROR;

    }

    returnsatus;

}

}
同样没有set方法,所以这样的JSON对象都需要重新创建一个自定义的mapper对象,用于jackson反序列化

© 著作权归作者所有

共有 人打赏支持
BKC

BKC

粉丝 2
博文 32
码字总数 35753
作品 0
朝阳
程序员
jackson常用注解和spring中的配置

spring默认使用的是jackson处理json的序列化和反序列化,有一些细节和小坑,基于spring4和jackson2.8做一些说明 @JsonIgnore @JsonIgnore是jackson的注解,jackson1版本和2版本没有区别,通常...

肥肥小浣熊
2017/12/01
0
0
自定义jackson解析时间格式yyy-MM-dd HH:mm:ss

1、问题排查 出现的场景: 服务端通过springmvc写了一个对外的接口,返回一个json字符串,其中该json带有日期,格式为yyyy-MM-dd HH:mm:ss 客户端通过feign调用该http接口,指定返回值为一个...

落叶清风
08/08
0
0
使用CXF开发RestFul WebService问题解决方案

最近在项目中,因为几个系统自己需要数据交换,所以采用进来都比较流行的RestFul风格WebService,实现框架采用apache的cxf,apache的东西一直以来都是比较的好用,回话少说,进入正题。 首先...

xdev
2013/05/18
0
3
Spring Boot搭建Web项目常用功能

搭建WEB项目过程中,哪些点需要注意: 1、技术选型: 前端:freemarker、vue 后端:spring boot、spring mvc 2、如何包装返回统一结构结果数据? 首先要弄清楚为什么要包装统一结构结果数据,...

幕三少
07/11
0
0
Spring Boot搭建Web项目要点

搭建WEB项目过程中,哪些点需要注意: 1、技术选型: 前端:freemarker、vue 后端:spring boot、spring mvc 2、如何包装返回统一结构结果数据? 首先要弄清楚为什么要包装统一结构结果数据,...

woter
07/09
0
0

没有更多内容

加载失败,请刷新页面

加载更多

20180920 rzsz传输文件、用户和用户组相关配置文件与管理

利用rz、sz实现Linux与Windows互传文件 [root@centos01 ~]# yum install -y lrzsz # 安装工具sz test.txt # 弹出对话框,传递到选择的路径下rz # 回车后,会从对话框中选择对应的文件传递...

野雪球
今天
1
0
OSChina 周四乱弹 —— 毒蛇当辣条

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @ 达尔文:分享花澤香菜/前野智昭/小野大輔/井上喜久子的单曲《ミッション! 健?康?第?イチ》 《ミッション! 健?康?第?イチ》- 花澤香菜/前野智...

小小编辑
今天
6
2
java -jar运行内存设置

java -Xms64m #JVM启动时的初始堆大小 -Xmx128m #最大堆大小 -Xmn64m #年轻代的大小,其余的空间是老年代 -XX:MaxMetaspaceSize=128m # -XX:CompressedClassSpaceSize=6...

李玉长
今天
1
0
Spring | 手把手教你SSM最优雅的整合方式

HEY 本节主要内容为:基于Spring从0到1搭建一个web工程,适合初学者,Java初级开发者。欢迎与我交流。 MODULE 新建一个Maven工程。 不论你是什么工具,选这个就可以了,然后next,直至finis...

冯文议
今天
1
0
RxJS的另外四种实现方式(四)——性能最高的库(续)

接上一篇RxJS的另外四种实现方式(三)——性能最高的库 上一篇文章我展示了这个最高性能库的实现方法。下面我介绍一下这个性能提升的秘密。 首先,为了弄清楚Most库究竟为何如此快,我必须借...

一个灰
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部