首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > Java Web开发 >

高分求解:Jsp生成图片验证码,Tomcat报错,该怎么处理

2011-12-30 
高分求解:Jsp生成图片验证码,Tomcat报错Java code%@ page contentTypeimage/jpeg importjava.awt.*,

高分求解:Jsp生成图片验证码,Tomcat报错

Java code
<%@ page contentType="image/jpeg" import="java.awt.*,java.awt.image.*,java.util.*,javax.imageio.*" %><%!Color getRandColor(int fc,int bc){        Random random = new Random();        if(fc>255) fc=255;        if(bc>255) bc=255;        int r=fc+random.nextInt(bc-fc);        int g=fc+random.nextInt(bc-fc);        int b=fc+random.nextInt(bc-fc);        return new Color(r,g,b);        }%><%response.setHeader("Pragma","No-cache");response.setHeader("Cache-Control","no-cache");response.setDateHeader("Expires", 0);int width=60, height=20;BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);Graphics g = image.getGraphics();Random random = new Random();g.setColor(getRandColor(250,252));g.fillRect(0, 0, width, height);g.setFont(new Font("Times New Roman",Font.PLAIN,20));g.setColor(getRandColor(150,160));for (int i=0;i<30;i++){ int x = random.nextInt(width); int y = random.nextInt(height);        int xl = random.nextInt(10);        int yl = random.nextInt(10); g.drawLine(x,y,x+xl,y+yl);}String sRand="";for (int i=0;i<4;i++){    String rand=String.valueOf(random.nextInt(10));sRand+=rand;    g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)));    g.drawString(rand,13*i+6,16);}session.setAttribute("random",sRand);g.dispose();ImageIO.write(image, "JPEG", response.getOutputStream());%> 


运行后tomcat报错:

严重: Servlet.service() for servlet jsp threw exception
java.lang.IllegalStateException: getOutputStream() has already been called for this response
at org.apache.catalina.connector.Response.getWriter(Response.java:604)
at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:198)
at org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:125)
at org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:118)
at org.apache.jasper.runtime.PageContextImpl.release(PageContextImpl.java:186)
at org.apache.jasper.runtime.JspFactoryImpl.internalReleasePageContext(JspFactoryImpl.java:118)
at org.apache.jasper.runtime.JspFactoryImpl.releasePageContext(JspFactoryImpl.java:77)
at org.apache.jsp.inc.random_jsp._jspService(random_jsp.java:142)
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:230)
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:104)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:261)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:581)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Thread.java:619)




高分求解!

[解决办法]
tomcat 把这个jsp 翻译后的 代码如下
(注意看我注释的地方)
-------------------------------

Java code
package org.apache.jsp;import javax.servlet.*;import javax.servlet.http.*;import javax.servlet.jsp.*;import java.awt.*;import java.awt.image.*;import java.util.*;import javax.imageio.*;public final class testpic_jsp extends org.apache.jasper.runtime.HttpJspBase    implements org.apache.jasper.runtime.JspSourceDependent {Color getRandColor(int fc, int bc) {        Random random = new Random();        if (fc > 255)            fc = 255;        if (bc > 255)            bc = 255;        int r = fc + random.nextInt(bc - fc);        int g = fc + random.nextInt(bc - fc);        int b = fc + random.nextInt(bc - fc);        return new Color(r, g, b);    }  private static final JspFactory _jspxFactory = JspFactory.getDefaultFactory();  private static java.util.List _jspx_dependants;  private javax.el.ExpressionFactory _el_expressionfactory;  private org.apache.AnnotationProcessor _jsp_annotationprocessor;  public Object getDependants() {    return _jspx_dependants;  }  public void _jspInit() {    _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();    _jsp_annotationprocessor = (org.apache.AnnotationProcessor) getServletConfig().getServletContext().getAttribute(org.apache.AnnotationProcessor.class.getName());  }  public void _jspDestroy() {  }  public void _jspService(HttpServletRequest request, HttpServletResponse response)        throws java.io.IOException, ServletException {    PageContext pageContext = null;    HttpSession session = null;    ServletContext application = null;    ServletConfig config = null;    JspWriter out = null;    Object page = this;    JspWriter _jspx_out = null;    PageContext _jspx_page_context = null;    try {      response.setContentType("image/jpeg");      pageContext = _jspxFactory.getPageContext(this, request, response,                  null, true, 8192, true);      _jspx_page_context = pageContext;      application = pageContext.getServletContext();      config = pageContext.getServletConfig();      session = pageContext.getSession();      out = pageContext.getOut();      _jspx_out = out;      //  注意这儿.  这儿用的是 PrintWriter &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&  ①      out.write('\r');      out.write('\n');      out.write('\r');      out.write('\n');    response.setHeader("Pragma", "No-cache");    response.setHeader("Cache-Control", "no-cache");    response.setDateHeader("Expires", 0);    int width = 60, height = 20;    BufferedImage image = new BufferedImage(width, height,            BufferedImage.TYPE_INT_RGB);    Graphics g = image.getGraphics();    Random random = new Random();    g.setColor(getRandColor(250, 252));    g.fillRect(0, 0, width, height);    g.setFont(new Font("Times New Roman", Font.PLAIN, 20));    g.setColor(getRandColor(150, 160));    for (int i = 0; i < 30; i++) {        int x = random.nextInt(width);        int y = random.nextInt(height);        int xl = random.nextInt(10);        int yl = random.nextInt(10);        g.drawLine(x, y, x + xl, y + yl);    }    String sRand = "";    for (int i = 0; i < 4; i++) {        String rand = String.valueOf(random.nextInt(10));        sRand += rand;        g.setColor(new Color(20 + random.nextInt(110), 20 + random        .nextInt(110), 20 + random.nextInt(110)));        g.drawString(rand, 13 * i + 6, 16);    }    session.setAttribute("random", sRand);    g.dispose();        // 这儿你又调用OutputStream ,  &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&   ③    ImageIO.write(image, "JPEG", response.getOutputStream());     //  注意这儿.  这儿用的是 PrintWriter &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&  ②      out.write('\r');      out.write('\n');    } catch (Throwable t) {      if (!(t instanceof SkipPageException)){        out = _jspx_out;        if (out != null && out.getBufferSize() != 0)          try { out.clearBuffer(); } catch (java.io.IOException e) {}        if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);      }    } finally {      _jspxFactory.releasePageContext(_jspx_page_context);    }  }} 


[解决办法]
我了写过一个, 把它贴出来吧.在我blog上呢. 还有好玩的. 欢迎看一下
http://newblog.tom.com/cn_z
-----------------

Java code
package cn.z.servlet;import java.awt.Color;import java.awt.Graphics;import java.awt.image.BufferedImage;import java.io.IOException;import javax.imageio.ImageIO;import javax.servlet.ServletException;import javax.servlet.ServletOutputStream;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.awt.Font;public class GenerateCheckCodeServlet extends HttpServlet {        // 生成的验证码的宽与高    int WIDTH = 80, HEIGHT = 30;    public void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        response.setDateHeader("Expires", 0);        response.setHeader("Cache-control", "no-cache");        response.setHeader("Pragma", "no-cache");        ServletOutputStream out = response.getOutputStream();        // 得到随机的验证码        char[] rands = generateCheckCode();        BufferedImage image = new BufferedImage(WIDTH, HEIGHT,                BufferedImage.TYPE_INT_RGB);        Graphics g = image.getGraphics();        // 先画背景        drawBackground(g);        // 再画验证码        drawCheckCode(g, rands);        g.dispose();        // 设置响应头为image/jpeg        response.setContentType("image/jpeg");        // 把验证码也放到session里,以便和用户手工输入的进行对比        request.getSession().setAttribute("check-code", new String(rands));        System.out.println(new String(rands));        // 输出图片        ImageIO.write(image, "JPEG", out);        out.flush();        out.close();    }    // 生成4位随机验证码的函数    private char[] generateCheckCode() {        // 这个是用ASCII的方法,        char[] rands = new char[4];        int rand = -1;        for (int i = 0; i < rands.length; i++) {            while (rand < 48 || (rand > 57 && rand < 65)                    || (rand > 90 && rand < 97) || rand > 122) {                rand = (int) (Math.random() * 127);                // System.out.print(rand + "\t");            }            rands[i] = (char) rand;        }        return rands;    }    // 第二种生成验证码的方法    private char[] generateCheckCode2() {        // 这个是随机取出字符串中的字符.        String chars = "abcdefghijklmnopqrstuvwxyz123456789";        char[] rands = new char[4];        int rand = -1;        for (int i = 0; i < rands.length; i++) {            rand = (int) (Math.random() * chars.length());            rands[i] = chars.charAt(rand);        }        return rands;    }    private void drawCheckCode(Graphics g, char[] rands) {        // 在不同的高度画验证码的每一个字符        g.setColor(Color.BLACK);        g.setFont(new Font(null, Font.ITALIC | Font.BOLD, 18));        g.drawString("" + rands[0], 11, 25);        g.drawString("" + rands[1], 26, 15);        g.drawString("" + rands[2], 41, 23);        g.drawString("" + rands[3], 56, 18);    }    private void drawBackground(Graphics g) {        // 画背景        g.setColor(new Color(0xdcdcdc));        g.fillRect(0, 0, WIDTH, HEIGHT);        for (int i = 0; i < 500; i++) {            // 随机生成500个位置随机,颜色随机的干扰点,并画在背景上            int x = (int) (Math.random() * WIDTH);            int y = (int) (Math.random() * HEIGHT);            int red = (int) (Math.random() * 255);            int green = (int) (Math.random() * 255);            int blue = (int) (Math.random() * 255);            g.setColor(new Color(red, green, blue));            g.drawOval(x, y, 2, 0);        }    }}
[解决办法]
来晚了 详细的解释一下吧

jsp编译成servlet之后
在释放在jsp中使用的对象,会调用response.getWriter()
因为这个方法是和response.getOutputStream()相冲突的!
所以会出现以上这个异常。



然后当然是要提出解决的办法,其实挺简单的
在使用完输出流以后调用以下两行代码即可:

Java code
out.clear();out = pageContext.pushBody(); 

热点排行