Blog

Efficiently serving video files in Java web apps with HTTP range requests

By  
Matti Tahvonen
Matti Tahvonen
·
On Aug 29, 2023 6:57:41 PM
·

Streaming video and audio content has become essential to modern web applications, providing users with an engaging and interactive experience. HTTP range requests are crucial to delivering these media files efficiently. Range requests allow for seeking within video and audio files, enhancing the performance of both the browser and the server. Additionally, certain browsers like Safari rely on Range requests for proper video functionality.

In this blog, we'll explore how to tackle HTTP Range requests in Java web apps and how Java servers and frameworks handle them.

The importance of HTTP range requests

HTTP Range requests allow clients to request only specific portions of a resource, which is particularly useful for video and audio files. Without Range requests, the server would have to transmit the entire file even when only a small section is needed, resulting in wasted bandwidth and slower loading times. By supporting Range requests, servers can efficiently serve partial content, enabling seamless playback and seeking within media files.

Range requests in Java servers

Many Java servers, by default, provide support for HTTP Range requests when dealing with resources through their built-in mechanisms. For instance, Range requests are automatically supported if you serve video files through standard resource handling in Java servers, such as Tomcat or Jetty.

The nasty thing is that unless the videos are, e.g., static how-to material, they can seldom be statically embedded into your war or jar files.

Spring and Range Requests

Spring MVC, a popular Java framework for building web applications, supports HTTP Range requests if used accordingly. You can take advantage of this feature effortlessly by serving resources through Spring's built-in mechanisms. This ensures that video files are served efficiently and enables smooth playback, seeking, and downloading.

To make Spring MVC (or Spring Web Flux) tackle Range requests for you, your REST endpoint must return an implementation of the Resource interface. Otherwise, Spring can’t efficiently tackle those.

Alternatively, if you are serving video files directly from your file system, you can configure an additional resource handler, like I recently did in this Vaadin add-on demo using Spring Boot.

Custom servlets and Vaadin StreamResource considerations

While Java servers and Spring MVC can easily handle Range requests, problems may arise when attempting to serve files directly through a custom Servlet. The same applies to Vaadin's StreamResource concept. Implementing Range requests is certainly possible, but implementing it properly from scratch can be complex.

In the tests for the VCamera add-on, I recently implemented basic Range request support for StreamResource (a pure servlet handler would be pretty similar). This implementation was designed to ensure enough compatibility with Safari for testing purposes. But if you look into implementations of DefaultServlets in Tomcat or Jetty, you’ll understand that it is most likely broken for anything more advanced. For a production-ready Servlet or StreamResource implementation, I’d carefully look into Jetty’s solution.

However, I would suggest attempting to avoid writing such code whenever possible. There are a couple of effective approaches to consider:

  • Utilize Existing Server code or front proxy: Whenever possible, leverage the built-in resource handling mechanisms provided by the Java server. For example, in Tomcat, you could configure an additional “exploded” web app (~ not deployed as a war file) just to serve media files from your special directory. 
    Or, if you happen to have a front proxy running, you can configure that to serve media files even before the request hits your Java server. This way, Range requests are handled automatically by a proven code, saving you from the intricacies of implementing it manually.
  • Use Spring MVC: By using an existing library like Spring MVC, you can avoid writing a ton of fragile client-server communication code.
  • CDN: Content Delivery Networks (CDNs) can significantly improve video serving performance by caching and delivering media files closer to users. They often handle Range requests efficiently, reducing server load and improving overall user experience. Like with front proxy configuration, you’ll technically move this responsibility away from your Java server altogether. 

Conclusion

HTTP Range requests play a crucial role in efficiently serving video and audio files in Java web applications. They enhance the user experience by enabling smooth playback and seeking and ensuring compatibility with specific browsers like Safari.

By leveraging existing server features, Spring MVC, CDNs, or front proxies, developers can simplify video file serving and provide a seamless multimedia experience to users. Embracing these best practices will lead to a more robust and responsive web application, elevating user satisfaction and engagement.

New to Vaadin? Learn to build and deploy a modern web application completely in Java. Get started ->  

Matti Tahvonen
Matti Tahvonen
Matti Tahvonen has a long history in Vaadin R&D: developing the core framework from the dark ages of pure JS client side to the GWT era and creating number of official and unofficial Vaadin add-ons. His current responsibility is to keep you up to date with latest and greatest Vaadin related technologies. You can follow him on Twitter – @MattiTahvonen
Other posts by Matti Tahvonen