Download Java / JSP image. Where to store these image files?

I am writing a simple application that allows the user to upload images. After downloading, the user can mark or delete them.

I figured out how to upload files and save them after uploading files. I track the global image storage path. In the database, I store metadata about images such as file name, tags, etc.

I am using Java / JSP (specifically the Stripes structure, but my problem is general).

My question is, where can I store these image files after they are downloaded?

Right now I have two web applications deployed on a Tomcat server. One main web application and another is where I upload images.

But this does not work, because I do not see the downloaded images in the main application until I reinstall and restart Tomcat.

It seems that Tomcat does not automatically select new uploaded images.

Does anyone have any solutions?

This is a simple project, so I do not want to store them in a database or use Apache for images. This is too complicated for this small project.

Thanks.

+4
source share
6 answers

Definitely do not save the images in the database, but you want to save the image path in the database. This will allow you to save the image anywhere.

Since you are using two tomcat applications, the best option would be to save the images outside of any application and transfer the image back to the user instead of allowing tomcat to manage the files. Otherwise, I would ask why you are trying to do this with two web applications.

+5
source

However, storing uploaded images inside the web application directory is not wise, and you know that.

By the way, you can see this fooobar.com/questions/7373 / ... , recently discussed where to store images. This may not solve your problem, it will undoubtedly give you more confidence in what you are doing.

+3
source

I decided it differently.

First, the unbearable way is that Glassfish (and I believe Tomcat too) allows you to map the external directory to the webapps hierarchy. It works very well and does exactly what you want. It allows you to store your images in an external directory away from your web application, but still serve them.

However, this method is not portable.

A way to make this portable is to create a filter.

You put the filter in some place, for example "/ images".

What the filter does:

  • he checks that the image (or something, it works with any static resource) in a special directory inside webapp. In our example, we will use url / webapp / images.

  • if the file does NOT exist, we will copy the file from your external location to the appropriate location in webapp. So let's say reqyest url is "/images/banner.gif". And your files are stored on disk in the folder "/ home / app / images". So, our source file is "/home/app/images/banner.gif". Then we copy it to where we want it in the webapp tree. For this we use "ServletContext.getRealPath". Thus, the destination will be "ServletContext.get RealPath" ("/webapp/images/banner.gif"). Just copy the source to your destination.

  • If the file already exists or exists, just go to the actual image in /webapp/images/banner.gif.

In fact, you get the cache file in your webapps deployment tree. The downside is the cache, so it needs to be maintained (i.e. you need to check if the original is newer than your cache, make sure you delete if the source is deleted, etc.). In addition, it duplicates your resources, so your images will ultimately consume twice as much disk space. Finally, the initial cost of copying at startup.

However, it works, and this prevents you from serving static resources using your own code. (This is the 3rd solution, map the filter / servlet to intercept the URLs and just pass it to yourself.)

I would look at the construct inside Tomcat (assuming it exists) to do the mapping for you. I know that it exists in Glassfish. (Google alternatedocroot for Glassfish to see how it works.)

+2
source

I used two web applications to avoid writing uploaded images in case I reinstalled the new main war file of the application.

But, as you say, there is no other choice but to pass them through a servlet or something that, I think, I can leave them outside the tomcat directory.

I wanted to avoid writing this streaming servlet. This is too small a project to deal with all the mess (for example, the correct content type, 404, etc.) when writing a streaming servlet.

0
source
import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Image streaming Servlet. */ public class ImageDisplayServlet extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public ImageDisplayServlet() { super(); } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String relativePath = trimToEmpty(request.getPathInfo()); // Make sure no one try to screw with us. // This is important as user can literally access any file if we are not careful if(isXSSAttack(relativePath) == false) { String pathToFile = this.getServletContext().getRealPath(request.getPathInfo()); File file = new File(pathToFile); System.out.println("Looking for file " + file.getAbsolutePath()); // show a 404 page if(!file.exists() || !file.isFile()) { httpError(404, response); } else { try { streamImageFile(file, response); } catch(Exception e) { // Tell the user there was some internal server error.\ // 500 - Internal server error. httpError(500, response); e.printStackTrace(); } } } else { // what to do if i think it is a XSS attack ?!? } } private void streamImageFile(File file, HttpServletResponse response) { // find the right MIME type and set it as content type response.setContentType(getContentType(file)); BufferedInputStream bis = null; BufferedOutputStream bos = null; try { response.setContentLength((int) file.length()); // Use Buffered Stream for reading/writing. bis = new BufferedInputStream(new FileInputStream(file)); bos = new BufferedOutputStream(response.getOutputStream()); byte[] buff = new byte[(int) file.length()]; int bytesRead; // Simple read/write loop. while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) { bos.write(buff, 0, bytesRead); } } catch (Exception e) { throw new RuntimeException(e); } finally { if (bis != null) { try { bis.close(); } catch (IOException e) { e.printStackTrace(); // To late to do anything about it now, we may have already sent some data to user. } } if (bos != null) { try { bos.close(); } catch (IOException e) { e.printStackTrace(); // To late to do anything about it now, we may have already sent some data to user. } } } } private String getContentType(File file) { if(file.getName().length() > 0) { String[] parts = file.getName().split("\\."); if(parts.length > 0) { // only last part interests me String extention = parts[parts.length - 1]; if(extention.equalsIgnoreCase("jpg")) { return "image/jpg"; } else if(extention.equalsIgnoreCase("gif")) { return "image/gif"; } else if(extention.equalsIgnoreCase("png")) { return "image/png"; } } } throw new RuntimeException("Can not find content type for the file " + file.getAbsolutePath()); } private String trimToEmpty(String pathInfo) { if(pathInfo == null) { return ""; } else { return pathInfo.trim(); } } private void httpError(int statusCode, HttpServletResponse response) { try { response.setStatus(statusCode); response.setContentType("text/html"); PrintWriter writer = response.getWriter(); writer.append("<html><body><h1>Error Code: " + statusCode + "</h1><body></html>"); writer.flush(); } catch (IOException e) { e.printStackTrace(); } } private boolean isXSSAttack(String path) { boolean xss = false; // Split on the bases of know file separator String[] parts = path.split("/|\\\\"); // Now verify that no part contains anything harmful for(String part : parts) { // No double dots .. // No colons : // No semicolons ; if(part.trim().contains("..") || part.trim().contains(":") || part.trim().contains(";")) { // Fire in the hole! xss = true; break; } } return xss; } /** * @see HttpServlet#doPost(Ht/promotions/some.jpgtpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } } 

Ok Here is a servlet that I quickly wrote that can transfer images:

Here is a list of limitations and problems with information:

  • Could be XSS vulnerability with caution
  • Not ready production as a reference
  • Images must be in the web application directory. It's easy to change, but I'm too lazy (it doesn't cost too little for a project)
  • Download only jpg, gif or png files.

Application:

Say you are deploying this web application called image as a standalone application.

http://www.example.com/images/promotions/promo.jpg

means that in this image web application there should be a directory in the "promotions" with the image "promo.jpg".

PS: Do not ask why I am making this solution only for Servlet Container, which sucks a lot of time.

0
source
  <servlet> <description></description> <display-name>ImageDisplayServlet</display-name> <servlet-name>ImageDisplayServlet</servlet-name> <servlet-class>com.example.images.ImageDisplayServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>ImageDisplayServlet</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> 

Oh, you can customize your servlet as above to get the best results: P

0
source

All Articles