Currently implemented a REST endpoint as below:
@RequestMapping(path = "/login/user/{username:.+}", method = POST, produces = "application/json; charset=utf-8")
@ResponseStatus(code = HttpStatus.OK)
public User userLogin(@PathVariable("username") String username, @RequestBody Password password) {
//do stuff
return new User(UUID.randomUUID());
}
I currently use email address as a username, and when I use one ending in .au, the endpoint returns a 406 Content not acceptable.
I tried playing around and changing the above to this
@RequestMapping(path = "/login/user/{username:.+}", method = POST, produces = "application/json; charset=utf-8")
@ResponseStatus(code = HttpStatus.OK)
public String userLogin(@PathVariable("username") String username, @RequestBody Password password) {
//do stuff
return "blah";
}
When I access it, it prompts me to download an .au file (audio format made by Sun microsystems...), which contains "blah". If I check the value of the username anytime within the method, I get the correct email address, with .au included.
I'm guessing something in the Spring stack is parsing the .au and trying to enforce a different media type so now it ignores application/json
I recently faced the same issue and found the issue. Thought of sharing it here as it would help others. This behaviour @Patrick explained seems to be occurring due to URL (URL suffix) based content negotiation in Spring MVC.
What is Content Negotiation?
There are situations where we have to deal with multiple representations (or views) of the same data returned by the controller. Working out which data format to return is called Content Negotiation.
How does Content Negotiation Work?
When making a request via HTTP it is possible to specify what type of response you would like by setting the
Accept
header property. However, browsers actually send very confusingAccept
headers, which makes relying on them impractical. Therefore Spring offers some alternative conventions for content negotiation.Spring Content Negotiation Alternatives - URL suffixes and/or a URL Parameter
In the above case explained in the question, what you see is path extension based content negotiation in action. (.au)
From the hava doc of ContentNegotiationConfigurer,
The Solution - Setting favorPathExtension to false
Please note that above configurations have some additional changes apart from setting favorPathExtension to false.
More details on this can be found here.
Just for completion, the response we get with the issue is as follows.