即使Accept被定义为null,也会调用@GetMapping

时间:2018-01-02 00:18:15

标签: spring spring-mvc spring-rest

我正在使用Spring Framework 4.3.13.RELEASE

关于休息,对于POST,我有以下内容:

@Controller
@RequestMapping(path="/personas")
public class PersonaRestController {

    @PostMapping(consumes={MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_UTF8_VALUE})
    public ResponseEntity<Void> saveOne(
            @Validated @RequestBody Persona persona, ...

关于测试使用JUnitResultActions我可以收到java.lang.AssertionError: No handler错误消息并确认以下内容:

MockHttpServletRequest:
      HTTP Method = POST
      Request URI = /personas
       Parameters = {}
          Headers = {}

Handler:
             Type = null

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/xml, application/json;charset=UTF-8]}
     Content type = null
             Body = 
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

感知此行为是因为saveOne方法要求内容数据为XMLJSON,对于此测试方案,未发送Content-Type

因此,预计Spring会出现HttpMediaTypeNotSupportedException个实例。然后,@Test方法失败,并显示java.lang.AssertionError: No handler错误消息,因为没有处理用户请求的处理程序。

直到这里一切都好。

同样,关于休息,对于GET,我有以下内容:

@GetMapping(path="/{id}",
            produces={MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_UTF8_VALUE})
public @ResponseBody Persona findOneById(@PathVariable String id){
    return personaService.findOneById(id);
}

对于其他测试方案,包含以下内容:

MockHttpServletRequest:
      HTTP Method = GET
      Request URI = /personas/100
       Parameters = {}
          Headers = {}

Handler:
             Type = com.manuel.jordan.rest.persona.PersonaRestController
           Method = public com.manuel.jordan.domain.Persona com.manuel.jordan.rest.persona.PersonaRestController.findOneById(java.lang.String)

我的拦截器显示以下数据

HttpHeaderControlInterceptor - preHandle 
   HttpServletRequest > 
    URL: http://localhost/personas/100 
    URI: /personas/100 
       HttpMethod: GET 
          Accept: null 
          Accept-Language: null 
          Content-Type: null 

我很困惑为什么调用findOneById方法,即使Accept为空时处理程序也是如此。我曾预料到类似于java.lang.AssertionError: No handler错误消息和HttpMediaTypeNotAcceptableException类的内容,因为findOneById方法可以返回XMLJSON中的数据

缺少什么?

1 个答案:

答案 0 :(得分:1)

我不完全确定,但猜测它是由HTTP 1.1引起的,

参见章节 - 10.4.7 406不可接受 here

  

注意:允许HTTP / 1.1服务器返回响应         根据发送的接受标头不可接受         请求。在某些情况下,这甚至可能比发送一个更好         406回应。鼓励用户代理检查标题         传入的响应,以确定它是否可以接受。

我认为,consumesproduces的处理方式不同,这就是您看到差异的原因。

请参阅此问题here

在我删除之前,我已经发布了一个答案。基本上,我误解了你的问题。