Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FileSystemResource is returned with content type json

I have the following spring mvc method that returns a file:

@RequestMapping(value = "/files/{fileName}", method = RequestMethod.GET)
public FileSystemResource getFiles(@PathVariable String fileName){

    String path="/home/marios/Desktop/";

    return new FileSystemResource(path+fileName);

}

I expect a ResourceHttpMessageConverter to create the appropriate response with an octet-stream type according to its documentation:

If JAF is not available, application/octet-stream is used.

However although I correctly get the file without a problem, the result has Content-Type: application/json;charset=UTF-8

Can you tell me why this happens?

(I use spring version 4.1.4. I have not set explicitly any message converters and I know that spring loads by default among others the ResourceHttpMessageConverter and also the MappingJackson2HttpMessageConverter because I have jackson 2 in my classpath due to the fact that I have other mvc methods that return json.

Also if I use HttpEntity<FileSystemResource> and set manually the content type, or specify it with produces = MediaType.APPLICATION_OCTET_STREAM it works fine.

Note also that in my request I do not specify any accept content types, and prefer not to rely on my clients to do that)

like image 321
Marios Avatar asked Sep 28 '22 21:09

Marios


1 Answers

I ended up debugging the whole thing, and I found that AbstractJackson2HttpMessageConverter has a canWrite implementation that returns true in case of the FileSystemResource because it just checks if class is serializable, and the set media type which is null since I do not specify any which in that case is supposed to be supported by it.

As a result it ends up putting the json content types in a list of producible media types. Of course ResourceHttpMessageConverter.canWrite implementation also naturally returns true, but the ResourceHttpMessageConverter does not return any producible media types.

When the time to write the actual response comes, from the write method implementation, the write of the ResourceHttpMessageConverter runs first due to the fact that the ResourceHttpMessageConverter is first in the list of the available converters (if MappingJackson2HttpMessageConverter was first, it would try to call write since its canWrite returns true and throw exception), and since there was already a producible content type set, it does not default to running the ResourceHttpMessageConverter.getDefaultContentType that would set the correct content type.

If I remove json converter all would work fine, but unfortunately none of my json methods would work. Therefore specifying the content type is the only way to get rid of the returned json content type

like image 110
Marios Avatar answered Oct 03 '22 02:10

Marios