Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is proper way to stream media with Spring MVC

I have a controller method that simply streams bytes for media (images, css, js, etc.) to the client. I first tried something like this:

@RequestMapping(value="/path/to/media/**", method=RequestMethod.GET)
@ResponseBody
public byte[] getMedia(HttpServletRequest request) throws IOException
{
    //logic for getting path to media on server

    return Files.readAllBytes(Paths.get(serverPathToMedia));
}

I originally tested this in Firefox, and it all seemed to work fine. However, I then tried it in Chrome, and then found that none of the images work. So, I then changed it to something like this:

@RequestMapping(value="/path/to/media/**", method=RequestMethod.GET)
public ResponseEntity<byte[]> getMedia(HttpServletRequest request) throws IOException
{
    //logic for getting path to media on server

    byte[] bytes = Files.readAllBytes(Paths.get(serverPathToMedia));
    //logic for setting some header values like Content-Type and Content-Length
    return new ResponseEntity<byte[]>(bytes, headers, HttpStatus.OK);
}

This gave the same results as before. I saw in the developer tools that my response headers were coming down as expected, but still no image bytes

Next I tried something like this:

@RequestMapping(value="/path/to/media/**", method=RequestMethod.GET)
public void getMedia(HttpServletRequest request, HttpServletResponse response) throws IOException
{
    //logic for getting path to media on server

    byte[] bytes = Files.readAllBytes(Paths.get(serverPathToMedia));
    response.getOutputStream().write(bytes);
}

Without even setting any response headers, this works in Firefox and Chrome. Now, while I can just do it this last way since it works, this doesn't seem like the correct Spring MVC way. I want to know why the first two things I tried didn't work, as they seem more correct. Also, is there something I didn't try that would actually be the right way to do this?

like image 424
dnc253 Avatar asked Dec 22 '12 18:12

dnc253


1 Answers

Your last approach is pretty much the way to go about it. The only change that I can suggest is to not keep the entire content file to be streamed in memory, instead to stream out the content with buffering - IOUtils from Apache commons can do this for you.

like image 75
Biju Kunjummen Avatar answered Oct 06 '22 01:10

Biju Kunjummen