0

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:

  • A is run on Jetty 9;
  • F is visible for Jetty server, and NOT visible for a client.

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.

8
  • can't you download content of files that are in F from A server and pass it to client? you can think of your file server something like a database Commented Jun 11, 2019 at 11:49
  • you could have an .htaccess rule that redirects http://my-webapp/pictures/{id} to a script in A that reads the image file content from F and returns it Commented Jun 11, 2019 at 11:53
  • @Kaddath, path to a picture on the file server should be determined by business logic, which is written on Java, so static rules won't work here/ Commented Jun 11, 2019 at 11:57
  • "F is visible for Jetty server, and NOT visible for a client." - visible how? Commented Jun 11, 2019 at 12:01
  • @nafas, actually it's a plan B, which has problems with cleaning content cached on A. I would prefer to find a way to create something like an InputStream, which starts on F and ends in a servlet of A, to prevent intermediate storing of data on A. Commented Jun 11, 2019 at 12:02

2 Answers 2

1

"Best practice" covers a lot of ground.

For load and performance reasons, it's a good idea to use a web server (like NGINX or Apache) rather than an application server to serve static assets. Most production environments have this set up, using a web server to proxy requests to the application server when necessary.

If you have such a setup, you could map the images drive on F as a drive on your web server, and use a .htaccess rewrite rule to deal with file name logic.

If that's not possible because the file name logic cannot be captured in a regex or similar, you could write a servlet on A to issue a redirect to a "regular" web location. Something along the lines of:

I strongly recommend you do not use a servlet to read the file from F and then stream that to the browser; this consumes large amounts of memory on your application server, and may slow down or even fail depending on your local network conditions. Your application's performance will almost certainly deteriorate very quickly under load.

Sign up to request clarification or add additional context in comments.

Comments

0

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 );
    }
  }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.