文档章节

Jackson异常情况处理

BKC
 BKC
发布于 2016/09/29 17:05
字数 1599
阅读 321
收藏 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
朝阳
程序员
私信 提问
mica 0.0.1-RC4 发布,完善对 spring boot webflux 的支持

mica 0.0.1-RC4 发布,Spring cloud微服务开发核心组件集 mica 云母 —— 微服务核心 mica 云母,寓意为云服务的核心,使得云服务开发更加方便快捷。mica 的前身是 lutool,lutool在内部孵化...

如梦技术
03/14
0
0
jackson常用注解和spring中的配置

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

肥肥小浣熊
2017/12/01
0
0
mica 微服务核心组件 1.0.0 正式版发布

mica(云母) mica 云母,寓意为云服务的核心,使得云服务开发更加方便快捷。mica 的前身是 lutool,lutool在内部孵化了小两年,已经被多个朋友运用到企业。由于 lutool 对微服务不够友好,故...

如梦技术
03/21
0
0
mica 0.0.1-RC3 发布,微服务开发核心组件集

mica 云母 —— 微服务核心 mica 云母,寓意为云服务的核心,使得云服务开发更加方便快捷。mica 的前身是 lutool,lutool在内部孵化了小两年,已经被多个朋友运用到企业。由于 lutool 对微服...

如梦技术
03/05
0
0
自定义jackson解析时间格式yyy-MM-dd HH:mm:ss

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

落叶清风
2018/08/08
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Python中判断字符串是否包含中文

Python import reRE = re.compile(u'[\u4e00-\u9fa5]', re.UNICODE)match = re.search(RE, str)if match is None:# 没有包含中文字符 参考 Python regular expressions return true/f......

亚林瓜子
13分钟前
0
0
《CNCF × Alibaba 云原生技术公开课》正式首播

《CNCF × Alibaba 云原生技术公开课》立即观看:点击立即观看 云原生最初来描述云上应用的典型架构与特性,随着容器、Kubernetes、Serverless、FaaS技术的演进,CNCF(云原生计算基金会)把...

mcy0425
14分钟前
0
0
网站漏洞如何修复网站程序问题

jeecms 最近被爆出高危网站漏洞,可以导致网站被上传webshell木马文件,受影响的版本是jeecms V6.0版本到jeecmsV7.0版本。该网站系统采用的是JAVA语言开发,数据库使用的是oracle,mysql,sql数...

网站安全
17分钟前
1
0
git 中“warning: CRLF will be replaced by LF in”解决方案

https://stackoverflow.com/questions/5834014/lf-will-be-replaced-by-crlf-in-git-what-is-that-and-is-it-important...

qwfys
21分钟前
0
0
Spring Boot配置ssl证书启用HTTPS协议

一 、点睛 SSL是为网络通信提供安全及数据完整性的一种安全协议,SSL在网络传输层对网络连接进行加密。SSL协议位于TCP/IP协议和各种应用层协议之间,为数据通信提供安全支持。 SSL协议分为两...

故久呵呵
23分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部