之前使用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 = 200
Error message = null
Headers = {Content-Type=[application/json;charset=UTF-8]}
Content type = application/json;charset=UTF-8
Body = {"code":2000,"message":"","data":"p1=x001, p2=10010"}
Forwarded URL = null
Redirected URL = null
Cookies = []

四、扩展

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

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

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

http://javatech.wang/index.php/archives/82/

SpringMVC接口测试异常:Can not deserialize instance of int out of START_OBJECT token的更多相关文章

  1. JSON parse error: Cannot deserialize instance of `int` out of START_OBJECT token; nested exception is com.fasterxml.jackson.databind.exc

    代码程序: @PostMapping("selectById") @ResponseBody public Result selectById(@RequestBody int i ...

  2. Can not deserialize instance of xxx out of START_ARRAY token

    Json 反序列化异常 Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableEx ...

  3. Jackson反序列化提示:Can not deserialize instance of Task out of START_ARRAY token

    解决方法: 1.没有绝对的方法,只能不断的测试和排查. 2.检查一下JSON数据和实体的字段结构是不是不一致导致的.比如JSON数据是数组,而实体字段为非数组. 参考: https://stackov ...

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

    关于fasterxml-jackson发生Can not deserialize instance of异常原因验证 这两天线上有大量的java.lang.IllegalArgumentExcepti ...

  5. JSON parse error: Can not deserialize instance of java.lang.String out of START_OBJECT token; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of j

    异常信息如下: JSON parse error: Can not deserialize instance of java.lang.String out of START_OBJECT token ...

  6. SpringMVC 处理异常的4种方式

    springmvc处理异常有三种方式: 1.在一个controller中定义一个方法,用@ExceptionHandler注解标注.(优先级最高) @ExceptionHandler public M ...

  7. springmvc 通过异常增强返回给客户端统一格式

    在springmvc开发中,我们经常遇到这样的问题:逻辑正常执行时返回客户端指定格式的数据,比如json,但是遇NullPointerException空指针异常,NoSuchMethodExcept ...

  8. Could not read document: Can not deserialize instance of java.lang.String out of START_ARRAY

    线上问题: { "timestamp": "1544510665", "status": 400, "error": & ...

  9. 解决用户自生成meta导入kylin后报错问题Can not deserialize instance of java.lang.String[] out of VALUE_STRING token

    报错栈: -- ::, ERROR [http-bio--exec-] cube.CubeManager: : Error during load cube instance, skipping : ...

随机推荐

  1. CSS解决无空格太长的字母,数字不会自动换行的问题

    其实很简单,代码如下所示,注意 Style: <div class="detail_title" style="word-break: break-all;&quo ...

  2. Struts2技术内幕 读书笔记二 web开发的基本模式

    最佳实践 在讨论基本模式之前,我们先说说一个词:最佳实践 任何程序的编写都得遵循一个特定的规范.这种规范有约定俗称的例如:包名全小写,类名每个单词第一个字母大写等等等等;另外还有一些需要我们严格遵守的 ...

  3. ERP-非财务人员的财务培训教(一.一)------基本会计知识

    一.基本会计知识 第一节 会计是企业的语言 反映企业经济状况的两组会计语言词汇 四个层次的会计语言规则 财务会计报告的组成 会计语言要素 会计工作主要是把企业杂乱的会计数据归纳整理,加工编制成有用的财 ...

  4. 图像的基本运算——scale, rotation, translation

    图像是视觉信息的直接反应,图像呈现出各种各样的特效都是通过图像的基本运算来完成的.图像最基本的运算有三种,分别是scale,rotation 和translation,叫做尺度,旋转和平移.很多图像的 ...

  5. java--银行业务调度系统

    转载请申明出处:http://blog.csdn.net/xmxkf   1. 银行调度业务系统的题目来源与需求阐述 银行业务调度系统: 模拟实现银行业务调度系统逻辑,具体需求如下: 1.银行内有6个 ...

  6. 字符编辑技术C语言实现

    #include<string.h> #include<ctype.h> #include<stdio.h> /*插入函数 ccode待插入的字符 anystrin ...

  7. LeetCode之旅(13)-Valid Anagram

    题目介绍: Given two strings s and t, write a function to determine if t is an anagram of s. For example, ...

  8. 巨高兴,偶的文章 “如何在服务器上配置ODBC来访问本机DB2for Windows服务器”被推荐至CSDN博客首页

    非常高兴,偶的文章 "如何在服务器上配置ODBC来访问本机DB2for Windows服务器"被推荐至CSDN博客首页,截图留念.                  文章被推荐在C ...

  9. Win10家庭版中的SQL2005无法远程连接

    最近公司重新更换了电脑,电脑自事Win10家庭版本.在安装开发工具中发现有不少的问题,如无法安装SQL Server 2005,无法安装VS2013等.最终通过网上寻找安装SQL Server 200 ...

  10. .net 异步编程async & await关键字的思考

    C# 5.0引入了两个关键字 async和await,这两个关键字在很大程度上帮助我们简化了异步编程的实现代码,而且TPL中的task与async和await有很大的关系 思考了一下异步编程中的asy ...