欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Mock测试时产生HttpMediaTypeNotSupportedException异常,415状态码问题的解决办法

程序员文章站 2022-07-14 18:40:40
...

Mock测试时产生HttpMediaTypeNotSupportedException异常,415状态码问题的解决办法

一. 异常问题

我在项目中利用Mock进行测试时,产生了HttpMediaTypeNotSupportedException异常信息:

Resolved Exception: Type = org.springframework.web.HttpMediaTypeNotSupportedException

并且有如下状态码提示,本来启动200状态码,现在得到了415状态码。

AssertionError: Status expected:<200> but was:<415>

Mock测试时产生HttpMediaTypeNotSupportedException异常,415状态码问题的解决办法

Mock测试时产生HttpMediaTypeNotSupportedException异常,415状态码问题的解决办法

Mock测试时产生HttpMediaTypeNotSupportedException异常,415状态码问题的解决办法

异常信息描述:

 MockHttpServletRequest:
       HTTP Method = POST
       Request URI = /user/save
        Parameters = {}
           Headers = [Accept:"application/json", Content-Length:"37"]
           Body = {"username":"test3","password":"123"}
        Session Attrs = {}
 ​
        Handler:
            Type = com.yyg.boot.web.UserController
            Method = com.yyg.boot.web.UserController#save(User)
 ​
 Async:
     Async started = false
     Async result = null
 ​
 Resolved Exception:
        Type = org.springframework.web.HttpMediaTypeNotSupportedException
 ​
 ModelAndView:
         View name = null
         View = null
         Model = null
 ​
 FlashMap:
        Attributes = null
 ​
 MockHttpServletResponse:
            Status = 415
            Error message = null
            Headers = [Accept:"application/json, application/octet-stream, application/xml, application/*+json, text/plain, text/xml, application/x-www-form-urlencoded, application/*+xml, multipart/form-data, multipart/mixed, */*"]
      Content type = null
      Body = 
      Forwarded URL = null
      Redirected URL = null
      Cookies = []
 ​
 java.lang.AssertionError: Status expected:<200> but was:<415>
 Expected :200
 Actual   :415
 @Test
 public void save() throws Exception {
    String json = "{\"username\":\"test3\",\"password\":\"123\"}";
    mvc.perform(MockMvcRequestBuilders.post("/user/save")
        .accept(MediaType.APPLICATION_JSON)
        //传json参数
        .content(json))
        .andExpect(MockMvcResultMatchers.status().isOk())
        .andDo(MockMvcResultHandlers.print());
 }
 @Test
 public void save() throws Exception {
    String json = "{\"username\":\"test3\",\"password\":\"123\"}";
    mvc.perform(MockMvcRequestBuilders.post("/user/save")
        .accept(MediaType.APPLICATION_JSON)
        //添加这样一个设置,保持浏览器请求与接收到的数据类型一致,都是json格式
        .contentType(MediaType.APPLICATION_JSON)
        //传json参数
        .content(json))
        .andExpect(MockMvcResultMatchers.status().isOk())
        .andDo(MockMvcResultHandlers.print());
 }

二. 原因分析

其实从log日志信息中分析可以发现,Mock的请求头中Accept要求的内容类型为”application/json“!

并且415状态码代表的是:服务器无法处理请求附带的媒体格式!也就是对于当前请求的方法和所请求的资源,请求中提交的实体并不是服务器中所支持的格式,因此请求被拒绝!

Mock测试时产生HttpMediaTypeNotSupportedException异常,415状态码问题的解决办法

然后Mock的响应头中返回的Accept数据类型却并不是单纯的”application/json“!

Mock测试时产生HttpMediaTypeNotSupportedException异常,415状态码问题的解决办法

所以产生了415状态码。

Mock测试时产生HttpMediaTypeNotSupportedException异常,415状态码问题的解决办法

我看了一下我的代码,发现是这么写的,原来是只设置了accept请求头接受类型,并没有设置contentType类型。

@Test
public void save() throws Exception {
   String json = "{\"username\":\"test3\",\"password\":\"123\"}";
   mvc.perform(MockMvcRequestBuilders.post("/user/save")
       .accept(MediaType.APPLICATION_JSON)
       //传json参数
       .content(json))
       .andExpect(MockMvcResultMatchers.status().isOk())
       .andDo(MockMvcResultHandlers.print());
}

三. 解决办法

在mock中设置accept与contentType类型一致就可以了! 

@Test
 public void save() throws Exception {
    String json = "{\"username\":\"test3\",\"password\":\"123\"}";
    mvc.perform(MockMvcRequestBuilders.post("/user/save")
        .accept(MediaType.APPLICATION_JSON)
        //添加这样一个设置,保持浏览器请求与接收到的数据类型一致,都是json格式
        .contentType(MediaType.APPLICATION_JSON)
        //传json参数
        .content(json))
        .andExpect(MockMvcResultMatchers.status().isOk())
        .andDo(MockMvcResultHandlers.print());
 }

四. Accept与Content-Type的区别

1. Http报头分类

Http报头分为通用报头,请求报头,响应报头和实体报头。

  • 请求方的HTTP报头包括:通用报头|请求报头|实体报头

  • 响应方的HTTP报头包括:通用报头|响应报头|实体报头

2. 两者类型不同

Accept属于请求报头,Content-Type属于实体报头。

3. 两者作用不同

Accept代表发送端(客户端/浏览器)希望接受的数据类型。 比如:Accept:application/json; 代表客户端/浏览器希望接受的数据类型是json类型。

Content-Type代表发送端(客户端or浏览器or服务器)发送的实体数据的数据类型。比如:Content-Type:application/json; 代表发送端/浏览器/服务器发送的数据格式是json。

二者合起来, Accept:application/json; Content-Type:application/json,即代表希望接受的数据类型是json格式,本次请求发送的数据格式也是json。

 

相关标签: 异常解决