0

I am using Spring-MVC and I need to send a MP4 file back to the user. The MP4 files are, of course, very large in size (> 2 GB).

I found this SO thread Downloading a file from spring controllers, which shows how to stream back a binary file, which should theoretically work for my case. However, what I am concerned about is efficiency.

In one case, an answer may implicate to load all the bytes into memory.

byte[] data = SomeFileUtil.loadBytes(new File("somefile.mp4"));

In another case, an answer suggest using IOUtils.

InputStream is = new FileInputStream(new File("somefile.mp4"));
OutputStream os = response.getOutputStream();
IOUtils.copy(is, os);

I wonder if either of these are more memory efficient than simply defining a resource mapping?

<resources mapping="/videos/**" location="/path/to/videos/"/>

The resource mapping may work, except that I need to protect all requests to these videos, and I do not think resource mapping will lend itself to logic that protects the content.

Is there another way to stream back binary data (namely, MP4)? I'd like something that's memory efficient.

Community
  • 1
  • 1
Jane Wayne
  • 8,205
  • 17
  • 75
  • 120

2 Answers2

1

I would think that defining a resource mapping would be the cleanest way of handling it. With regards to protecting access, you can simply add /videos/** to your security configuration and define what access you allow for it via something like

<security:intercept-url pattern="/videos/**" access="ROLE_USER, ROLE_ADMIN"/>

or whatever access you desire.

Also, you might consider saving these large mp4's to a cloud storage and/or CDN such as Amazon S3 (with our without CloudFront).

Then you can generate unique urls which will last as long as you want them to. Then the download is handled by Amazon rather than having to use the computing power, data space, and memory of your web server to serve up the large resource files. Also, if you use something like CloudFront, you can configure it for streaming rather than download.

DavidA
  • 3,984
  • 5
  • 25
  • 38
  • Besides, authentication and authorization, I have some "custom" logic that places additional constraints on the MP4 files (e.g. no more than 3 MP4s can be streamed at once). The approach you give satisfies partially my requirements, however, are there "hooks" withing Spring MVC and Security to add more access logic? – Jane Wayne May 05 '14 at 13:00
  • You can create your own custom security filter: http://docs.spring.io/spring-security/site/docs/3.0.x/reference/ns-config.html#ns-custom-filters – DavidA May 06 '14 at 19:28
1

Loading the entire file into memory is worse, as well as using more memory and being non-scalable. You don't transmit any data until you've loaded it all, which adds all that latency.

user207421
  • 305,947
  • 44
  • 307
  • 483