Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring MVC return HTTP 406 on URL with dot

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

like image 977
Vartlok Avatar asked May 18 '15 14:05

Vartlok


2 Answers

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.

like image 173
David Lavender Avatar answered Sep 30 '22 03:09

David Lavender


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

like image 36
Alex Vidmych Avatar answered Sep 30 '22 04:09

Alex Vidmych