2019独角兽企业重金招聘Python工程师标准>>>

之前使用springmvc搭建了restful风格的接口服务,在使用mockmvc进行集成测试的时候出现了异常:Can not deserialize instance of int out of START_OBJECT token。为什么会出现这个问题?怎么解决这个问题呢?接下来本文详细分析讲解这个问题。

一、问题展现

  1. 接口代码
@ResponseBody
@RequestMapping(value = "/m1", method = RequestMethod.POST)
@ApiOperation(value = "测试方法1", httpMethod = "POST", response = ApiResult.class, notes = "测试方法1")
public ApiResult method1(@ApiParam(required = true, name = "p1", value = "参数1") @RequestBody String p1,@ApiParam(required = true, name = "p2", value = "参数2") @RequestBody Integer p2) throws Exception {String content = "p1=" + p1 + ", p2=" + p2;System.out.println(content);ApiResult<String> result = new ApiResult<String>();result.setCode(ResultCode.SUCCESS.getCode());result.setData(content);return result;
}
  1. 测试代码
@Test
public void method1Test() throws Exception {Map<String, Object> params = new HashMap<String, Object>();params.put("p1", "x001");params.put("p2", 10010);ObjectMapper mapper = new ObjectMapper();byte[] content = mapper.writeValueAsBytes(params);this.mockMvc.perform(post("/activation/m1").contentType(APPLICATION_JSON_UTF8).content(content).accept(APPLICATION_JSON_UTF8)).andExpect(status().isOk()).andExpect(content().contentType(APPLICATION_JSON_UTF8)).andExpect(jsonPath("$.code").value(2000)).andDo(print());}
  1. 执行上述测试代码控制台异常错误
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of int out of START_OBJECT token at [Source: org.springframework.mock.web.DelegatingServletInputStream@3e0fa1; line: 1, column: 1]
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:148)
at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:762)
at com.fasterxml.jackson.databind.deser.std.StdDeserializer._parseInteger(StdDeserializer.java:419)
at com.fasterxml.jackson.databind.deser.std.NumberDeserializers$IntegerDeserializer.deserialize(NumberDeserializers.java:289)
at com.fasterxml.jackson.databind.deser.std.NumberDeserializers$IntegerDeserializer.deserialize(NumberDeserializers.java:271)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3066)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2221)
at org.springframework.http.converter.json.MappingJackson2HttpMessageConverter.readJavaType(MappingJackson2HttpMessageConverter.java:168)
... 50 more

二、分析问题

  我们先从接口方法中参数注解@RequestBody说起吧!我们大家都知道@ResponseBody是把接口方法返回结果转化成JSON形式提供给方法调用者,那么相对应的,@RequestBody是把客户端POST请求content部分转化成JavaBean对象或者JSON对象。@RequestBody的解析有两个条件:

  1. POST请求中content的值必须为json格式(存储形式可以是字符串,也可以是byte数组);
  2. 被@RequestBody注解的参数类型必须是完全可以接收参数值的类型,比如:Map,JSONObject,或者对应的JavaBean;

  @RequestBody将post请求中content值转为一个整体对象,该对象包含所有参数名和参数值,所以接口方法必须也是一个参数完全接收所有参数名和参数值。根据上面展示的代码来看,@RequestBody将params对象json形式内容转换成一个整体参数值,无论是p1还是p2,都无法接收该参数值。

三、解决问题

  在method1方法中定义一个可以接收整体参数值的对象类型即可,通常可选类型有:Map、JSONObject和JavaBean,JSONObject相对于Map,其取值方法更灵活。下面我们将在method1方法中定义一个JSONObject类型的参数。

@ResponseBody
@RequestMapping(value = "/m1", method = RequestMethod.POST)
@ApiOperation(value = "测试方法1", httpMethod = "POST", response = ApiResult.class, notes = "测试方法1")
public ApiResult method1(@ApiParam(required = true, name = "p", value = "参数") @RequestBody JSONObject p) throws Exception {String content = "p1=" + p.getString("p1") + ", p2=" + p.getInt("p2");System.out.println(content);ApiResult<String> result = new ApiResult<String>();result.setCode(ResultCode.SUCCESS.getCode());result.setData(content);return result;
}

  测试响应结果正常:

MockHttpServletResponse:Status = 200Error message = nullHeaders = {Content-Type=[application/json;charset=UTF-8]}Content type = application/json;charset=UTF-8Body = {"code":2000,"message":"","data":"p1=x001, p2=10010"}Forwarded URL = nullRedirected URL = nullCookies = []

四、扩展

  对POST接口的请求可以采取表单式和接口客户端式两种方法提交。

  1. 表单式提交
      参数形式:p1=v1&p2=v2,服务端接口方法获取参数可以采用@RequestParam注解对应参数方式。

  2. 客户端提交
      这里的客户端具体指自定义编码的客户端。将所有参数信息组织成一个整体对象,然后转换成json对象,设置为post请求content的值,提交到服务端。此时服务端接口方法获取参数即需要采用本文讨论的方式。其实本文method1方法也可以自定义一个包含p1和p2两个字段的JavaBean类型,自己可以尝试一下,呵呵!

文章作者: xiaohui249
本文链接: http://javatech.wang/index.php/archives/82/
版本所有 ©转载时必须以链接形式注明作者和原始出处

转载于:https://my.oschina.net/xiaohui249/blog/607860

可以参考《SpringMVC接口测试异常:Can not deserialize instance相关推荐

  1. SpringMVC处理异常

    SpringMVC处理异常 @(SpringMVC)[springmvc, 异常] SpringMVC处理异常 SpringMVC单异常处理 SpitterController2 SpittleNot ...

  2. Rest请求使用Jackson反序列化报错,Cannot deserialize instance of `java.lang.String` out of START_OBJECT toke

    Rest接口,使用Jackson作为json转换器,后端接收请求的时候报错了,异常信息: JSON parse error: Cannot deserialize instance of `java. ...

  3. FeignClient调用 Cannot deserialize instance of `java.lang.Boolean` out of START_OBJECT token to

    异常描述 Caused by: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize inst ...

  4. 解决POSTMAN传参报错,JSON parse error: Cannot deserialize instance of `java.util.ArrayList` out of START_OB

    前言:使用POSTMAN自测代码以便前后端联调时,发送请求后,BOOM!!!服务器抛了个这样式的东西出来. Resolved [org.springframework.http.converter.H ...

  5. fasterxml-jackson发生Can not deserialize instance of的原因

    背景: 项目中使用jackson反序列化工作时出现了Can not deserialize instance of相关的异常,现在针对出现的几种情况做一个小小的总结. (1)Cannot deseri ...

  6. 解决:Can not deserialize instance of com.xxx.xx.XXModel out of START_ARRAY toke

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到教程. 1. json数据解析报错: Can not deserialize instance of com ...

  7. 前端无法反序列化START\u数组标记-JSONCannot deserialize instance of `java.lang.String` out of START_ARRAY toke

    前端传参时报错:msg: "JSON parse error: Cannot deserialize instance of java.lang.String out of START_AR ...

  8. MismatchedInputException: Cannot deserialize instance of `xxx` out of START_ARRAY token

    问题 使用postman向端发送请求时,出现 org.springframework.http.converter.HttpMessageNotReadableException: JSON pars ...

  9. Cannot deserialize instance of `com.jas.cn.ReturnData` out of START_ARRAY token

    Cannot deserialize instance of `com.jas.cn.ReturnData` out of START_ARRAY token 报错信息 错误描述 原因分析 问题排查 ...

最新文章

  1. Linux环境编程--进程通信
  2. Oracle数据库中的分页--rownum
  3. 在RHEL-4下半小时搭建Sendmail邮件服务器(下)
  4. 选带傅里叶变换(zoom-fft)
  5. springmvc学习笔记--ueditor和springmvc的集成
  6. java abstractrequest,Java AbstractJackson2HttpMessageConverter類代碼示例
  7. Java主要处理哪些类型的异常_Java技术高效处理异常有哪些呢?
  8. ORA-12514, TNS:listener does not currently know of service requested in connect descriptor
  9. Jenkins 插件安装方式全攻略
  10. 让Android Studio 使用上vs的android模拟器
  11. 邹博机器学习算法最新版 --- 献给想要入门、或者想要进阶的朋友
  12. 支付宝支付对账单java_[Java]解析支付宝对账单csv
  13. 计算某年某月某日到某年某月某日之间的天数
  14. OV7725鹰眼摄像头
  15. 故宫夜景门票最高炒至9999元 官方:二手票难以入场
  16. 数模--2022华中杯A题(Java实现)
  17. Mysql查询各科成绩前三名并分别排序
  18. 国家英语四级考试词组
  19. Javascript学习:删除字符串中的数字
  20. 新致新知 | 开启图谱赋能认知新篇章

热门文章

  1. unity 当前移动方向_Unity小工具:溶解效果(Dissolve)
  2. 计算机最低分怎么英语,编写一个学生类 有年龄 英语、数学、计算机三门成绩 求平均分、最高分、最低分...
  3. 美国道富java开发面试题_从事Java开发五年,面试9家拿到7家offer,1096面试+67笔试题...
  4. java jsp 图片上传_jsp 图片上传代码
  5. java 反射技术实例,什么是反射技术?Java中最常用的反射技术实例
  6. java8中class怎么用_Java8中你可能不知道的一些地方之方法引用实战
  7. vue多个根节点上的属性继承
  8. oracle desc卡,Oracle的一个bug,desc的bug,很夸张,这么基础的功能居然有bug
  9. Vue父组件访问子组件属性和方法、父子组件双向绑定(两种方法)
  10. python地址多少位_Python获取IP地址对应的地理位置信息!