javahttpweb-applicationswebserverstatic-content

How to serve static content in a Java web app from internal server?


It's a standard (possibly trivial) situation, but I cannot find detailed information on the topic.

Suppose we have a web application A (http://my-webapp) and a file server F (http://file-server).

For clarity:

What is the best practice to show in A a picture stored on F?

Suppose client makes a request http://my-webapp/pictures/123, where 123 - any id, which somehow points to a picture stored as http://file-server/storage/xxx123.jpg, and expects to see the picture in the browser.


Solution

  • I propose the following solution as a minimal example that could be a good starting point.

    Redirection by .htaccess seems to be doing similar things on the low level.

    Actually the problem is supposed to be solved by web application server itself without intervention of external tools (like Apache httpd or Nginx).

    1. Declare servlet in web.xml

    <servlet>
        <servlet-name>pictures</servlet-name>
        <servlet-class>myapplication.servlets.HiddenFileServlet </servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>pictures</servlet-name>
        <url-pattern>/pictures/*</url-pattern>
    </servlet-mapping>
    

    2. Implement the servlet

    public class HiddenFileServlet extends HttpServlet
    {     
      @Inject
      MyService myService; // a service for paths finding on http://file-server
    
      @Override
      protected void doGet( HttpServletRequest req, HttpServletResponse resp ) throws IOException
      {        
        String requestedUri = req.getRequestURI();
    
        String fileName = myService.getFileName( requestedUri );
    
        String mime = getServletContext().getMimeType( fileName );
    
        if ( mime == null )
        {
          resp.setStatus( HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
          return;
        }
        else
        {
          resp.setContentType( mime );
        }
    
        // path on http://file-server/storage
        URL fileFullPath = myService.getInternalPath( requestedUri );
    
        URL file = new URL( fileFullPath );
    
        try (
            InputStream in = file.openStream();
            OutputStream out = resp.getOutputStream()
        )
        {
           org.apache.commons.compress.utils.IOUtils.copy( in, out );
        }
      }
    }