The dot in the path variable at the end of the URI causes two unexpected behaviours (unexpected for the majority of users, except those familiar with the huge number of Spring configuration properties).
The first (which can be fixed using the {email:.+}
regex) is that the default Spring configuration matches all path extensions. So setting up a mapping for /api/{file}
will mean that Spring maps a call to /api/myfile.html
to the String argument myfile
. This is useful when you want /api/myfile.html
, /api/myfile.md
, /api/myfile.txt
and others to all point to the same resource. However, we can turn this behaviour off globally, without having to resort to a regex hack on every endpoint.
The second problem is related to the first and correctly fixed by @masstroy. When /api/myfile.*
points to the myfile
resource, Spring assumes the path extension (.html
, .txt
, etc.) indicates that the resource should be returned with a specific format. This behaviour can also be very useful in some situations. But often, it will mean that the object returned by a method mapping cannot be converted into this format, and Spring will throw a HttpMediaTypeNotAcceptableException
.
We can turn both off with the following (assuming Spring Boot):
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
// turn off all suffix pattern matching
configurer.setUseSuffixPatternMatch(false);
// OR
// turn on suffix pattern matching ONLY for suffixes
// you explicitly register using
// configureContentNegotiation(...)
configurer.setUseRegisteredSuffixPatternMatch(true);
}
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.favorPathExtension(false);
}
}
More about Content Negotiation.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…