Spring MVC 在带有点的 URL 上返回 HTTP 406

Posted

技术标签:

【中文标题】Spring MVC 在带有点的 URL 上返回 HTTP 406【英文标题】:Spring MVC return HTTP 406 on URL with dot 【发布时间】:2015-07-30 03:23:14 【问题描述】:

我发现 Spring MVC 的一种非常奇怪的行为。

我有带有方法的控制器:

@RequestMapping (value = "/delete/id:.*", method = RequestMethod.DELETE)
public ResponseEntity<Response> delete(@PathVariable (value = "id") final String id) 
    HttpStatus httpStatus = HttpStatus.OK;
    final Response responseState = new Response( ResponseConstants.STATUS_SUCCESS );
    try 
        POJO pojo = mediaFileDao.findById( id );
        if (pojo != null) 
            delete(pojo);
         else 
            httpStatus = HttpStatus.NOT_FOUND;
            responseState.setError( "NOT_FOUND" );
        
     catch (Exception e) 
        httpStatus = HttpStatus.INTERNAL_SERVER_ERROR;
        responseState.setError( e.getMessage() );
    
    return new ResponseEntity<>( responseState, httpStatus );

所以,问题是当 id 包含点时(例如“my_file.wav”)Spring 在任何情况下都会返回 HTTP 406,但如果 id 不包含点,Spring 在我 expet 时返回 responseState(as json)。我尝试通过不同的方式修复它(添加@ResponseBody,更改杰克逊版本,将 Spring 降级到 4.0)但没有任何结果。

谁能帮帮我?

更新我为 Spring MVN 启用日志并看到了这个

ID 包含点:

DEBUG org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver - Resolving exception from handler [public org.springframework.http.ResponseEntity<my.package.response.Response> my.package.Controller.deleteMediaFile(java.lang.String) throws java.lang.Exception]: org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
DEBUG org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver - Resolving exception from handler [public org.springframework.http.ResponseEntity<my.package.response.Response> my.package.Controller.deleteMediaFile(java.lang.String) throws java.lang.Exception]: org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
DEBUG org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver - Resolving exception from handler [public org.springframework.http.ResponseEntity<my.package.response.Response> my.package.Controller.deleteMediaFile(java.lang.String) throws java.lang.Exception]: org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation

ID 不包含点:

DEBUG org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdviceChain - Invoking ResponseBodyAdvice chain for body=my.package.response.Response@1e66a392
DEBUG org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdviceChain - After ResponseBodyAdvice chain body=my.package.response.Response@1e66a392

解决方案

Spring does not ignore file extension

SpringMVC: Inconsistent mapping behavior depending on url extension

【问题讨论】:

【参考方案1】:

您需要像这样定义自定义内容协商管理器服务:

<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager" />

<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
    <property name="favorPathExtension" value="false" />
</bean>

来自article

【讨论】:

【参考方案2】:

在你的servlet xml中,关闭Spring的后缀匹配:

<mvc:annotation-driven>
    <mvc:path-matching registered-suffixes-only="true"/>
</mvc:annotation-driven>

此功能允许调用者通过将内容作为后缀粘贴在 URL 末尾来指定他们希望返回内容的方式:

GET /user/bob.json
GET /use/bob.jsp

但 100 个项目中有 99 个不使用此功能。当 URL 的末尾恰好有点时,它只会导致问题。

【讨论】:

您的答案看起来正确,但对我没有帮助。 Spring 仍然发送 HTTP 406。 现在尝试将 requestmapping 更改为 @RequestMapping (value = "/delete/id", method = RequestMethod.DELETE) 好的,我找到了解决方案并添加了问题。

以上是关于Spring MVC 在带有点的 URL 上返回 HTTP 406的主要内容,如果未能解决你的问题,请参考以下文章

如何在 REST API 中使用带有 spring mvc 的版本?

由于 Spring MVC 中不存在 URL,验证表单提交按钮在第二次尝试后返回 404

使用spring mvc返回JSON,chrome可以,firefox不行的问题定位

Spring MVC 重定向在 url 中添加了一些参数

登录后 Spring MVC 控制器重定向到某个 URL

带有 Spring MVC 的 Vaadin 8 Spring Boot QuickTickets 仪表板