Reputation: 6856
I am using Spring MVC 3.2.2.RELEASE, and this is my first attempt at using Spring's Java based configuration (@Configuration
).
I have a controller that I use to handle certain files. The content of the files is read by my service method MyContentService.getResource(String)
. At the moment, the content type is always text/html
.
How can I config my Spring MVC application so that it correctly sets the type of the content returned? The content type can only be determined at runtime.
My controller at the moment, which incorrectly always sets the type to text/html
:
@Controller
public class MyContentController {
MyContentService contentService;
@RequestMapping(value = "content/{contentId}")
@ResponseBody
public byte[] index(@PathVariable String contentId) {
return contentService.getResource(contentId);
}
}
EDIT:
The following method works (with PNG and JPEG files), but I am not comfortable with URLConnection
determining the content type (e.g. PDF, SWF, etc):
@RequestMapping(value = "content/{contentId}/{filename}.{ext}")
public ResponseEntity<byte[]> index2(@PathVariable String contentId, @PathVariable String filename, @PathVariable String ext, HttpServletRequest request) throws IOException {
byte[] bytes = contentService.getResource(contentId);
String mimeType = URLConnection.guessContentTypeFromName(filename + "." + ext);
if (mimeType != null) {
final HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.valueOf(mimeType));
return new ResponseEntity<byte[]>(bytes, headers, HttpStatus.OK);
} else {
logger.warn("Unable to determine the mimeType for " + getRequestedUrl(request));
return new ResponseEntity<byte[]>(HttpStatus.NOT_FOUND);
}
}
Upvotes: 0
Views: 8261
Reputation: 124506
Currently you are only returning a byte[]
which doesn't hold much information, only the actual content (as a byte[]
).
You can wrap the byte[]
in a HttpEntity
or ResponseEntity
and set the appropriate content type on that. Spring MVC will use the content type of the entity to set the actual content type to the response.
To determine the filetype you can use the FileTypeMap
of the javax.activation
framework or use a library (see Getting A File's Mime Type In Java).
@RequestMapping(value = "content/{contentId}")
@ResponseBody
public HttpEntity index(@PathVariable String contentId) {
String filepath = // get path to file somehow
String contentType = FileTypeMap.getDefaultFileTypeMap().getContentType(filePath);
byte[] content = contentService.getResource(contentId);
final HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.valueOf(mimeType));
return new HttpEntity(content, headers);
}
Upvotes: 2