Как получить изображение в JSP из базы данных Oracle?

На странице JSP я хочу отобразить изображение, хранящееся в базе данных. Как мне это сделать?

Я попробовал следующий код JSP, но он ничего не отображает в браузере. Что я делаю неправильно?

<%

        HttpSession ses2=request.getSession();
        String email2 = (String)ses2.getAttribute("ses_email");
        Connection cn2;
        PreparedStatement ps2;
        try
        {
        Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
            cn2=DriverManager.getConnection("jdbc:odbc:sm","system","gecbsp");
            ps2=cn2.prepareStatement("select * from smreg3 where email = "+
                                "'"+email2+"'");
            ResultSet rs2=ps2.executeQuery();
            //ServletOutputStream sos=response.getOutputStream();

        if(rs2.next())   
        {  
        byte[] bytearray = new byte[1024];  
        int size=0;  
        InputStream image;  
        image = rs2.getBinaryStream(1);  
        response.reset();  
        response.setContentType("image/jpeg");  
        while((size=image.read(bytearray))!= -1 )  
        {  
        response.getOutputStream().write(bytearray,0,size);  
        }   
        response.flushBuffer();  
        image.close();  
        rs2.close();  
        }  
        }
        catch(Exception ee)
        {
            ee.printStackTrace();
        }
        %>  

Ошибка:

java.lang.IllegalStateException
    at org.apache.catalina.connector.ResponseFacade.reset(ResponseFacade.java:310)
    at org.apache.jsp.profile_jsp._jspService(profile_jsp.java:193)
    at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:393)
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:320)
    at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:266)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:263)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:584)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
    at java.lang.Thread.run(Thread.java:619)

1 ответ

Просто переместите этот код в сервлет, и все будет хорошо. В вашем случае ответ не может быть использован напрямую, так как, вероятно, JSP уже записал информацию заголовка в ответ.

В сервлете ваш код будет выглядеть так:

открытый класс TestServlet расширяет HttpServlet {

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {
    HttpSession session = req.getSession();
    String email = (String)session.getAttribute("ses_email");
    Connection cxn;
    PreparedStatement ps;
    try {
        Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
        cxn = DriverManager.getConnection("jdbc:odbc:sm","system","gecbsp");
        ps = cxn.prepareStatement("select * from smreg3 where email = ?");
        ps.setString(1, email); // this avoids sql injection
        ResultSet rs = ps.executeQuery();
        if(rs.next()) {
            InputStream in = rs.getBinaryStream(1);
            byte[] buffer = copyStream(in); // use a library like Apache commons IO here
            rs.close(); cxn.close();
            resp.setContentType("image/jpeg");
            resp.getOutputStream().write(buffer);
            resp.flushBuffer();

        }
    }catch(Exception e){
        e.printStackTrace(); // replace this by a proper logging framework
    }
}

private byte[] copyStream(InputStream in) {
    // just the copy code from your initial example
}

}

После этого вам также нужно будет сделать сервлет доступным в вашем файле web.xml.

Примерно так должно быть в разделе веб-приложений web.xml:

<servlet-mapping>
    <servlet-name>downloadServlet</servlet-name>
    <url-pattern>download</url-pattern>
</servlet-mapping>
<servlet>
    <servlet-name>downloadServlet</servlet-name>
    <servlet-class>test.TestServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

Затем сервлет доступен как /download в контексте вашего веб-приложения.

Другие вопросы по тегам