使用session属性将servlet显示为img src

时间:2011-12-07 03:19:11

标签: java jsp servlets

我有一个用于显示图像的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();
    }
 }

但是这段代码不起作用,无法显示图像。我认为这不会起作用,因为我已经在会话中存储了包含输入流的文件管理器。此方法适用于从数据库检索但未存储在会话中的另一个图像文件。我实际上打印出输入流。它包含与数据库文件相同的输入流。

代码有问题吗? 或者我实际上不能在会话中存储包含输入流的文件管理器? 还是我以错误的方式使用输入流?

2 个答案:

答案 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是在项目文件夹中创建的文件夹。即这是保存所有上传图像的文件夹。