Jackson异常情况处理

转载 2014年06月17日 15:41:29
 

Jackson异常情况处理

分类: J2EE 486人阅读 评论(0) 收藏 举报

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

[html] view plaincopy在CODE上查看代码片派生到我的代码片
  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配置中增加

[html] view plaincopy在CODE上查看代码片派生到我的代码片
  1. mapper.configure(DeserializationConfig.Feature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true) ;   

 

2、转义字符-异常情况:

[html] view plaincopy在CODE上查看代码片派生到我的代码片
  1. org.codehaus.jackson.JsonParseException: Illegal unquoted character ((CTRL-CHAR, code 9)): has to be escaped using backslash to be included in string value  
  2.  at [Source: java.io.StringReader@10cfc2e3; line: 1, column: 2461]   

解决办法,在ObjectMapper配置中增加:

[html] view plaincopy在CODE上查看代码片派生到我的代码片
  1. mapper.configure(Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true) ;  

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

蒋壮
  发布:2013-04-05 22:04   分类:接口测试文章分类框架分享   阅读:1,614 views   3条评论  

这里先简单的做下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初始化配置的代码:

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
ObjectMapper objectMapper = new ObjectMapper();
 
//配置为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(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));

 

下面是处理json的工具类代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public static <T> T getObjectFromJsonString(String jsonString, TypeReference<T> tr) {
 
        if (jsonString == null || "".equals(jsonString)) {
 
            return null;
 
        } else {
 
            try {
 
                return (T) objectMapper.readValue(jsonString, tr);
 
            } catch (Exception e) {
 
                e.printStackTrace();
 
            }
 
        }
 
        return null;
 
}

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

 

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

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

或者

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

下面是BaseResponseModel的代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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;
 
    public boolean isSuccess() {
 
       return isSuccess;
 
    }
 
    public void setIsSuccess(boolean isSuccess) {
 
       this.isSuccess = isSuccess;
 
    }
 
    //其余getter/setter省略
}
BaseResponseModel封装了http请求返回的通用成员变量,例如:ErrorCode,IsSuccess,Total等

Mapper对象实例:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class InfoAndRateMapper implements Serializable{
 
    private static final long serialVersionUID = 1L;
 
    private List<BrandContentInfoDO> info;
 
    private List<Rate> rate;
 
    public List<BrandContentInfoDO> getInfo() {
 
       return info;
 
    }
 
    public void setInfo(List<BrandContentInfoDO> info) {
 
       this.info = info;
 
    }
 
    public List<Rate> getRate() {
 
       return rate;
 
    }
 
    public void setRate(List<Rate> rate) {
 
       this.rate = rate;
 
    }
 
}

 

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

  • 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的属性配置:

?
1
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对象的一个变量为

?
1
private boolean isSuccess;

 

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

?
1
2
3
4
5
public void setSuccess( boolean isSuccess) {
 
       this. isSuccess = isSuccess;
 
}

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

?
1
2
3
4
5
public void setIsSuccess( boolean isSuccess) {
 
             this. isSuccess = isSuccess;
 
}

2、当JSON对象为:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class XXXStatus extends XXXResultStatus<XXXStatus> {
 
private static final long serialVersionUID = 2385584133823877965L;
 
public static final Map<Integer, XXXStatus> codeMap = new HashMap<Integer, XXXStatus>();
 
public static final XXXStatus SUCCESS = new XXXStatus(0, "xxx", "xxx");
....
 
private XXXStatus(int code, String msg, String frontMsg) {
    super(code, msg, frontMsg);
    codeMap.put(code, this);
}
 
public static final XXXStatus getRelationStatus(int code) {
    XXXStatus satus = codeMap.get(code);
    if (satus == null) {
        return SYSTEM_ERROR;
    }
    return satus;
}
}

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

 


关于fasterxml-jackson发生Can not deserialize instance of异常原因验证

关于fasterxml-jackson发生Can not deserialize instance of异常原因验证 这两天线上有大量的java.lang.IllegalArgumentEx...
  • li396864285
  • li396864285
  • 2017年01月09日 12:53
  • 18337

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

错误原因:不能范序列化java.util.ArrayList对象 解决方案:改成List
  • jiangguixin673969023
  • jiangguixin673969023
  • 2014年04月14日 20:38
  • 1666

Could not read JSON: Can not deserialize instance of java.lang.String[] out of VALUE_STRING token

Could not read JSON: Can not deserialize instance of java.lang.String[] out of VALUE_STRING token如果服...
  • u013041642
  • u013041642
  • 2017年09月11日 09:47
  • 845

Spring Jackson 反序列化Date时遇到的问题

Spring Jackson 反序列化Date时遇到的问题
  • chenjian0415
  • chenjian0415
  • 2015年11月25日 21:24
  • 7893

关于jackson中时间字符串的转换

"yyyy-MM-dd'T'HH:mm:ss.SSSZ" "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" "EEE, dd MMM yyyy HH:mm:ss zzz" "yyyy...
  • masquelo
  • masquelo
  • 2013年08月29日 22:13
  • 10484

SpringMVC json处理 (Jackson)

package com.e6.ztest; public class AccountBean {    private int id;    private String name;    pri...
  • zhujtbl0505
  • zhujtbl0505
  • 2014年03月25日 00:37
  • 3783

Jackson 工具类使用及配置指南

目录 前言Jackson使用工具类Jackson配置属性Jackson解析JSON数据Jackson序列化Java对象 前言 Json数据格式这两年发展的很快,其声称相对XML格式有很对好处...
  • kobejayandy
  • kobejayandy
  • 2015年05月20日 13:45
  • 21416

Json Converter例子

public final class JsonConverter {     @SuppressWarnings("unchecked")     public static T convert(...
  • ppby2002
  • ppby2002
  • 2014年02月24日 16:45
  • 1635

Jackson解析json API和实现分析

原文地址:Jackson解析json API和实现分析
  • u014263805
  • u014263805
  • 2014年11月02日 18:21
  • 7995

Jackson 工具类使用及配置指南

目录 前言Jackson使用工具类Jackson配置属性Jackson解析JSON数据Jackson序列化Java对象 前言 Json数据格式这两年发展的很快,其声称相对XML格式有很对好处...
  • baidu_18607183
  • baidu_18607183
  • 2016年04月18日 16:52
  • 2262
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Jackson异常情况处理
举报原因:
原因补充:

(最多只允许输入30个字)