7

I have found one very strange behaviour of Spring MVC.

I have controller with method:

@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 );
}

So, problem is when id contains dot (ex. "my_file.wav") Spring returns HTTP 406 in any case, but if id doesn't contain dot, Spring returns responseState(as json) as I expet. I tried to fix it by different way (add @ResponseBody, change jackson version, downgrade Spring to 4.0) but without any result.

Can any one help me?

UPDATE I enable logs for Spring MVN and saw this

ID contains dot:

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 doesn't contain dot:

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

SOLUTION

Spring does not ignore file extension

SpringMVC: Inconsistent mapping behavior depending on url extension

Community
  • 1
  • 1
Vartlok
  • 2,539
  • 3
  • 32
  • 46

2 Answers2

3

In your servlet xml, turn off Spring's suffix matching:

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

This is a feature that allows callers to specify how they want their content returned by sticking it as a suffix at the end of the URL:

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

But 99 out of 100 projects don't use this feature. And it just causes problems when there happen to be dots at the end of the URL.

David Lavender
  • 8,021
  • 3
  • 35
  • 55
1

You need to have a custom content negotiation manager service defined like this:

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

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

Came from this article