Get Request fails for .com email addresses because

2019-07-02 18:42发布

问题:

(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?

回答1:

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


回答2:

I came across this problem when upgraded from spring 3.1.2 to 3.2.7. The answer by Nina helped me (which should be marked as the answer). But instead of extending the WebMvcConfigurerAdapter I did it in my WebConfig that extended WebMvcConfigurationSupport.

@Configuration
public class WebConfig extends WebMvcConfigurationSupport {
  @Override
  public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
      super.configureContentNegotiation(configurer);
      configurer.favorPathExtension(false).favorParameter(true);
  }
}