Ignore file extensions in Spring MVC

If you’re using Java configuration (i.e. not XML) and are using endpoints that have a “.” in the last token of the path you’ll probably have noticed the default Spring behaviour where anything after the “.” is truncated.

Luckily there’s a simple fix.

Here’s an example of a familiar endpoint. You’ve got an endpoint that needs to accept an email address as part of the path…

@RequestMapping(value = "/some/path/{email}", method = RequestMethod.GET)
public ResponseEntity<SimpleMessage> getSimpleMessage(@PathVariable("email") String email) {
    ...
}

 

So when you call GET /some/path/foo@devpolito.com the email identifier is captured as “foo@devpolito.com”, right? Wrong. In fact the default behaviour of Spring is to recognise file extensions and do something smart with them.

The problem is a well known one, with some detailed explanations and solutions here and here.

The first thing to be aware of it, you need to change the path to a regular expression. That way you can tell Spring that you want to capture the entire token:

@RequestMapping(value = "/some/path/{email:+.}", method = RequestMethod.GET)
public ResponseEntity<SimpleMessage> getSimpleMessage(@PathVariable("email") String email) {
    ...
}

For the most part this seems to work (at least according to those Stack Overflow posts).

But I’m using Java configuration not XML…

Although the above should work, it doesn’t – strangely it does work for unrecognized file extensions like “foo.foobarski”. However, switch to recognized file extension like “foo.jpg” and suddenly it doesn’t get recognized.

Another trick I’ve read is:

@EnableWebMvc
@ComponentScan(...)
@Configuration
public class MyWebMvcConfig extends WebMvcConfigurerAdapter{

    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        configurer.setUseSuffixPatternMatch(false);
    }
}

This doesn’t seem to work at all. I suspect there is a second configurer somewhere or perhaps this one gets overridden. I’m not sure.

However this one works a treat:

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

 

Leave a comment