estani estani - 1 month ago 13
Java Question

how to accept any path in Spring boot + MVC

I want to define an endpoint using Spring Boot + MVC that accepts a multipart file upload containing a desired target path in the url.

Example:

form the url

http://localhost:8080/upload/file/path/to/somefile.pdf
I expect to extract
/path/to/somefile.pdf
to use it later.

So far this is what I got:

@RequestMapping(method= RequestMethod.PUT, value="/file/**", consumes = "multipart/form-data")
@ResponseBody
public UploadResult uploadFile(final HttpServletRequest request, @RequestParam("file") MultipartFile file) throws IOException {
//parse from path is ok.
}


It captures any path (slashes included) but files suffixes. So this works:

http://localhost:8080/upload/file/path/to/somefile


but this doesn't

http://localhost:8080/upload/file/path/to/somefile.pdf


It answers a
406
caused by
org.springframework.web.HttpMediaTypeNotAcceptableException
.

I assume the framework is trying to infer something regarding the pdf, and don't know to handle it. I assume it's only a configuration issue... How can I stop that behavior for only that endpoint?

Failed Attempts:


  • tried turning off the suffix pattern match from WebMvcConfigurerAdapter as someone suggested

    configurer.setUseSuffixPatternMatch(false);


Sam Sam
Answer Source
HttpMediaTypeNotAcceptableException or 406 means we have problems with Content Negotiation. By default spring will first check with the path extension. 
In your case, your endpoint have suffix with .pdf, so it is expecting as application.pdf or pdf is required but your end point defined something else. So it gives 406 error. you can check more details here
<https://spring.io/blog/2013/05/11/content-negotiation-using-spring-mvc>

To resolve the issue you can easily change this configuration using ContentNegotiationConfigurer accessed by extending WebMvcConfigurerAdapter. 



 @Configuration
    @EnableWebMvc
    public class WebConfig extends WebMvcConfigurerAdapter {

      @Override
      public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer.favorPathExtension(false);
      }
    }