Java 以最佳性能将图像写入 servlet 响应
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2979758/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Writing image to servlet response with best performance
提问by tabdulin
I'm writing an image to servlet response with best performance. Any advices, practices, experience?
我正在以最佳性能将图像写入 servlet 响应。任何建议,做法,经验?
采纳答案by BalusC
For best performance and efficiency, don't put the entire content in byte[]
. Each byte
eats, yes, one byte from Java's memory. Imagine 100 concurrent users which requests 10 images of each 100KB, that's already 100MB of Java memory eaten away.
为了获得最佳性能和效率,请勿将整个内容放在byte[]
. byte
是的,每个都从 Java 的内存中吃掉一个字节。想象一下,100 个并发用户请求每 100KB 的 10 张图像,这已经消耗了 100MB 的 Java 内存。
Get the image as an InputStream
from the DB using ResultSet#getBinaryStream()
, wrap it in an BufferedInputStream
and write it to the OutputStream
of the response wrapped in an BufferedOutputStream
through a small byte[]
buffer.
使用InputStream
从 DB 中获取图像ResultSet#getBinaryStream()
,将其包装在 an 中,然后通过一个小缓冲区将其BufferedInputStream
写入OutputStream
包装在 an 中的响应的。BufferedOutputStream
byte[]
Assuming that you select images by the database key as identifier, use this in your HTML:
假设您通过数据库键选择图像作为标识符,请在您的 HTML 中使用它:
<img src="images/123">
Create a Servlet
class which is mapped in web.xml
on an url-pattern
of /images/*
and implement its doGet()
method as follows.:
创建Servlet
其在映射类web.xml
上url-pattern
的/images/*
并执行其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) {}
}
In the ImageDAO#find()
you can use ResultSet#getBinaryStream()
to get the image as an InputStream
from the database.
在ImageDAO#find()
您可以使用从数据库中ResultSet#getBinaryStream()
获取图像InputStream
。
回答by M.J.
you can use byte of array type for image from servlet if it is there in Database of Blob type.
如果 Blob 类型的数据库中存在 servlet 中的图像,则可以将数组类型的字节用于图像。
byte[] image;
or there is one more way, but it is a bit complex. when u call your servlet, so before that u need to identify if the call is for image or it is normal call. if it is a normal call then u can go ahead to call servlet, but if it a call for image then don't call servlet but u can store the image references at some physical location in computer and retrieve the same.
或者还有一种方法,但它有点复杂。当您调用 servlet 时,因此在此之前您需要确定调用是针对图像还是正常调用。如果是正常调用,那么您可以继续调用 servlet,但是如果它是对图像的调用,则不要调用 servlet,但是您可以将图像引用存储在计算机中的某个物理位置并检索它。
But this method will not work if u have images in DB, rather u can have relative paths in DB and then u can fetch the image from that path.
但是,如果您在 DB 中有图像,则此方法将不起作用,而您可以在 DB 中有相对路径,然后您可以从该路径中获取图像。
回答by Edwin Buck
If the images are static, keep in mind that the fastest response is the one that is handled before it gets to you.
如果图像是静态的,请记住,最快的响应是在它到达您之前处理的响应。
You can stand up Apache's httpd in front of your Tomcat server. You can use other variants of caching edge servers. There are plenty of tricks along those lines.
你可以在你的Tomcat服务器前面站起来Apache的httpd。您可以使用缓存边缘服务器的其他变体。沿着这些路线有很多技巧。
Of course, this supposes that your application is written where a URL effectively maps to one image in a way that is easily cached. If your application lacks this, the benefits are great enough to consider a restructuring.
当然,这假设您的应用程序编写的 URL 以一种易于缓存的方式有效映射到一个图像。如果您的应用程序缺少此功能,那么好处足以考虑进行重组。