Mark Pope
Mark Pope

Reputation: 11274

Ignore Accept header in spring mvc

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.

Upvotes: 4

Views: 8586

Answers (3)

rustyx
rustyx

Reputation: 85531

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.).

Upvotes: 2

Mark Pope
Mark Pope

Reputation: 11274

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());

    }


}

Upvotes: 6

Dave L.
Dave L.

Reputation: 9801

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.

Upvotes: -1

Related Questions