我有一个用于显示图像的servlet。这个servlet实际上是由
调用的<img src="/displaySessionImage?widgetName=something"/>
我的得到&amp;发布重定向到此方法,
protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
String widgetName = request.getParameter("widgetName");
try {
//this is my file manager which was store ealier
StorageFile file = (StorageFile)session.getAttribute(widgetName);
response.setContentType(file.getContentType());
//the file manager can retrieve input stream
InputStream in = file.getInputStream();
OutputStream outImage = response.getOutputStream();
byte[] buf = new byte[1024];
int count = 0;
while ((count = in.read(buf)) >= 0) {
outImage.write(buf, 0, count);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
但是这段代码不起作用,无法显示图像。我认为这不会起作用,因为我已经在会话中存储了包含输入流的文件管理器。此方法适用于从数据库检索但未存储在会话中的另一个图像文件。我实际上打印出输入流。它包含与数据库文件相同的输入流。
代码有问题吗? 或者我实际上不能在会话中存储包含输入流的文件管理器? 还是我以错误的方式使用输入流?
答案 0 :(得分:0)
你真的不清楚实际发生了什么,也许只是无知。但是在会话中存储和传递InputStream
已经不是一个好兆头了。首先,它不可序列化。其次,您完全从创建它的上下文中分离输入流(因此在初始上下文完成时可能会隐式地关闭/释放它)。第三,输入流通常只能读取一次(因此,一旦读取它,就不能再读取它,你必须创建一个新的。)
通常的做法是在InputStream
创建后直接将byte[]
读入byte[]
,然后将InputStream input = uploadedFile.getInputStream();
ByteArrayOutputStream output = new ByteArrayOutputStream();
// Copy bytes from input to output the usual way.
// ...
byte[] content = output.toByteArray();
// Now store it in session.
存储在会话中。
// ...
response.getOutputStream().write(content);
然后在图像servlet中,只需执行
byte[]
您只需要知道{{1}}的每个字节都会占用JVM内存的一个字节。确保你不要过火。一旦您不再需要,就立即从会话中删除该属性。如有必要,请使用临时文件存储,以确保是否必须处理大文件。
更新:
我正在使用firebug,响应选项卡为空,在标题选项卡中,响应标头包含:content-type:image / jpeg,content-length:0,服务器和日期。
内容长度为0确认输入流已被读取(或其源已被隐式释放)。这只能证实我最初的猜测。不,手动设置内容长度标题不会解决问题。当响应主体完全适合默认响应缓冲区时,servlet容器已经自动关注它;否则它会切换到分块编码。
答案 1 :(得分:0)
您的代码无效,因为您无法显示已上传的图片,因为您的img语法错误。
试试这个:
<img src="${pageContext.request.contextPath}/submit/Java/2.jpg">
此处,/submit
是在项目文件夹中创建的文件夹。即这是保存所有上传图像的文件夹。