4

I have a controller that serves files (images, pdfs, etc,.):

@Controller
public class FileController {

    @ResponseBody
    @RequestMapping("/{filename}")
    public Object download(@PathVariable String filename) throws Exception {
        returns MyFile.findFile(filename);
    }

}

If I request a file with the following Accept header I get a 406:

Request     
URL: http://localhost:8080/files/thmb_AA039258_204255d0.png
Request Method:GET
Status Code:406 Not Acceptable
Request Headers
Accept:*/*

If I request the same file with the following Accept header I get a 200:

URL: http://localhost:8080/files/thmb_AA039258_204255d0.png
Request Method: GET 
Status Code:200 OK
Request Headers
Accept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5

This is the only view resolver in my spring-mvc context:

<bean class="org.springframework.web.servlet.view.UrlBasedViewResolver" id="tilesViewResolver">
   <property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView"/>
</bean>

Is there anyway to configure spring mvc to ignore the Accept header? I've seen example of doing this with ContentNegotiatingViewResolver, but only for handling xml and json.

matt b
  • 138,234
  • 66
  • 282
  • 345
Mark Pope
  • 11,244
  • 10
  • 49
  • 59
  • This is a very similar question but for json: http://stackoverflow.com/questions/5315288/spring-returning-json-with-responsebody-when-the-accept-header-is-throws-htt – Mark Pope Mar 25 '11 at 21:27

3 Answers3

6

So this is the code I ended up with to get it working:

@Controller
public class FileController {

    @ResponseBody
    @RequestMapping("/{filename}")
    public void download(@PathVariable String filename, ServletResponse response) throws Exception {
        MyFile file = MyFile.find(filename);
        response.setContentType(file.getContentType());
        response.getOutputStream().write(file.getBytes());

    }


}
Mark Pope
  • 11,244
  • 10
  • 49
  • 59
2

I used this to lock to the JSON response type:

@Configuration
@EnableWebMvc
public class ApplicationConfiguration extends WebMvcConfigurerAdapter {

    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {

        configurer.favorPathExtension(false);
        configurer.ignoreAcceptHeader(true);
        configurer.defaultContentType(MediaType.APPLICATION_JSON);

    }

}

favorPathExtension(false) is needed because Spring by default (at least in 4.1.5) favors path-based content negotiation (i.e. if the URL ends with ".xml", it will try to return XML, etc.).

rustyx
  • 80,671
  • 25
  • 200
  • 267
-1

When you use ResponseBody annotation, I think that is part of the deal that it looks at the Accept header and tries to do some mapping or whatever. There are plenty of other ways to send a response though if you can't figure out how to do it with that annotation.

Dave L.
  • 9,595
  • 7
  • 43
  • 69