text: Exception With Butterfly Wings: How to return a file, a stream or a classpath resource from a Spring MVC controller
  How to return a file, a stream or a classpath resource from a Spring MVC controller
  You can use AbstractResource subclasses as return values from the controller methods, combining them with the @ResponseBody method annotation.
  Consequently, as soon as you know the filesystem path of the file or have its URI, returning a file from a Spring MVC controller is as easy as:
  @RequestMapping(value = "/file", method = RequestMethod.GET,
  public Resource getFile() throws FileNotFoundException {
  return new FileSystemResource("/Users/forketyfork/cat.jpg");
  The code to return a classpath resource is quite similar:
  @RequestMapping(value = "/classpath", method = RequestMethod.GET,
  public Resource getFromClasspath() {
  return new ClassPathResource("cat.jpg");
  But how about outputting data from a stream? A common advice is to inject HttpServletResponse as a method parameter and write directly to the output stream of the response. But this badly breaks the abstraction, not to mention the testability. Technically we can write to a Writer introduced as a method parameter, like this:
  @RequestMapping(value = "/writer", method = RequestMethod.GET,
  public void getStream(Writer writer) throws IOException {
  A seemingly simple one-liner. But if you consider serving a large chunk of binary data, this approach appears to be quite slow, memory-consuming and not very handy as it uses the Writer which deals in chars. Moreover, Spring MVC is not able to set the Content-Length header until the output is finished. Here's a slightly more verbose solution, which however does not break the abstraction and is fast and testable.
  @RequestMapping(value = "/stream", method = RequestMethod.GET,
  public Resource getStream() {
  // acquiring the stream
  InputStream stream = new ByteArrayInputStream(string.getBytes());
  // counting the length of data
  final long contentLength = string.length();
  return new InputStreamResource(stream){
  First, we acquire the stream. Then we count the length of the content we need to output. This may be done in some optimized fashion so as not to process the content entirely. Spring MVC first calls the contentLength() method of the InputStreamResource, sets the Content-Length header and then pipes the stream to the client.
  Here we touch on a bit of inconsistency in Spring API. The class InputStreamResource extends the AbstractResource, which in turn implements the method contentLength() by processing the whole incapsulated stream to count its length. InputStreamResource does not override the contentLength() method, but does override the getInputStream() method, prohibiting to call it more than once, which effectively does not allow for direct usage of this class as a controller method return value. In the example above we override the contentLength() method and provide the correct functionality.
  Posted by forketyfork at 12:48 AM
  Labels: controller, spring, spring mvc, stream
  Thank you! I was looking for something like this. Now, if it only had a corresponding contentType(String) function, I would be in business!
  forketyfork December 10, 2013 at 11:49 PM
  I'm glad my post helped you! As for the content type, I don't believe there is a universal solution for that. But if you have some guesses as of what the string may be, you can peek inside and determine its content type by some markers or typical signatures.