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
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With