Search code examples
springgetfile-extensionhttp-status-code-406media-type

Get Request fails for .com email addresses because Spring interpretes it as a extensions


(See edit part below 20.08.2015)

I had a similar problem recently (Get request only works with trailing slash (spring REST annotations)) and the solution was to add a regex to the value of @RequestMapping (see also Spring MVC @PathVariable getting truncated).

But now we have realised that the problem still exists, but only for email addresses ending on .com or .org. This is very weird.

Shortly, I use Spring Annotations building a REST Service. I have a GET request with three parameters, the last is an email.

My Controller:

@RequestMapping(method = GET, value = "/{value1}/{value2}/{value3:.+}",
  produces = MediaType.APPLICATION_JSON_VALUE + ";charset=UTF-8")    
  public ResponseEntity<MyResponseType> getMyResource(
    @ApiParam(value = "...",...)
    @PathVariable("value1") String value1,
    @ApiParam(value = "...",...)
    @PathVariable("value2") String value2,
    @ApiParam(value = "...",...)
    @PathVariable("value3") String value3) {
      //...
}

If I call: http://myserver:8080/myresource/value1/value2/value3

with value3= email@domain.de / co.uk / .name / .biz /.info, there is no problem at all.

But with certain top level domains (.com, .org so far) I receive Http Status Code 406 (Not accepted).

It works if I add a trailing slash:

http://myserver:8080/myresource/value1/value2/value3/

As we use swagger and swagger does not add trailing slashes, adding a trailing slash is not an option.

What might cause this problem?

I use an ErrorHandler which extends ResponseEntityExceptionHandler. I debugged it and found that HttpMediaTypeNotAcceptableException ("Could not find acceptable representation") is thrown. But I can't find out yet who is throwing it and why.


edit

I found out that the path http://myserver:8080/myresource/value1/value2/myemail@somewhere.com

is interpreted as file, and "com" is the file extension for the media type "application/x-msdownload", so in Spring's class ProducesRequestCondition.ProduceMediaTypeExpression in the method matchMediaType the line "getMediaType().isCompatibleWith(acceptedMediaType)" fails, because the actually produced media type is "application/json;charset=UTF-8", not "application/x-msdownload".

So the questions changes to: How can I make Spring understand, that .com is not a file extension?


Solution

  • This thread helped me: SpringMVC: Inconsistent mapping behavior depending on url extension

    Obviously this is not a bug but a "feature" and there are two different ways to disable it. I used the annotation version:

    @Configuration
    @EnableWebMvc
    public class RestCommonsMvcConfig extends WebMvcConfigurerAdapter {
    
      @Override
      public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer.favorPathExtension(false);
      }
    }