当前位置: 代码迷 >> Java Web开发 >> 生成图片验证码的代码总是提示有错!解决方案
  详细解决方案

生成图片验证码的代码总是提示有错!解决方案

热度:21   发布时间:2016-04-17 12:15:48.0
生成图片验证码的代码总是提示有错!
HTML code
<%@ page language="java" import="java.util.*" pageEncoding="GBK" import="java.awt.*,java.awt.image.*,javax.imageio.*"%><%/*使用方法:在需要显示验证码的html代码中使用<img p">  在需判断session的时候判断session.getAttribute("vcode")*/try{  int codeLength=4;//验证码长度  int mixTimes=5;//模糊程度参数  Color bgColor=getRandColor(200, 250);//背景颜色  Color bfColor=new Color(0,0,0);//字体颜色  boolean ifRandomColor=true;//单个字符是否颜色随机  boolean ifMixColor=true;//模糊线是否颜色随机  //设置页面不缓存  response.setHeader("Pragma", "No-cache");  response.setHeader("Cache-Control", "no-cache");  response.setDateHeader("Expires", 0);  // 在内存中创建图象  int width = 13*codeLength+6, height = 20;  BufferedImage image = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);  // 获取图形上下文  Graphics g = image.getGraphics();  // 设定背景色  g.setColor(bgColor);  g.fillRect(0, 0, width, height);  //设定字体  g.setFont(new Font("Times New Roman", Font.PLAIN, 18));  //画边框  g.setColor(new Color(33,66,99));  g.drawRect(0,0,width-1,height-1);  // 随机产生干扰线,使图象中的认证码不易被其它程序探测到  g.setColor(getRandColor(160, 200));  for (int i = 0; i < mixTimes*codeLength/10; i++) {    if(ifMixColor)         g.setColor(getRandColor(160, 200));    int x = random.nextInt(width);    int y = random.nextInt(height);    int xl = random.nextInt(12);    int yl = random.nextInt(12);    g.drawLine(x, y, x + xl, y + yl);  }  // 取随机产生的认证码(codeLength位数字)  String sRand = "";  String rand;  String letters="abcdefghijklmnopqrstuvwxyz0123456789";  for (int i = 0; i < codeLength; i++) {      int l=random.nextInt(36);    rand = letters.substring(l,l+1);    sRand = sRand+rand;    // 将认证码显示到图象中    if(ifRandomColor)      g.setColor(getRandColor(20,110,0));     else      g.setColor(bfColor);     //调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成    g.drawString(rand, 13 * i + 6, 16);  }  // 将认证码存入SESSION  session.setAttribute("vcode", sRand);  System.out.println("vcode.jsp生成的验证:"+sRand);  // 图象生效  g.dispose();  // 输出图象到页面  ImageIO.write(image, "PNG", response.getOutputStream());}catch(Exception e){}%><%!//给定范围获得随机颜色private static Random random=new Random();private Color getRandColor(int fc, int bc) {  return getRandColor(fc, bc, fc);}private Color getRandColor(int fc, int bc,int interval) {  if (fc > 255) {    fc = 255;  }  if (bc > 255) {    bc = 255;  }  int r = fc + random.nextInt(bc - interval);  int g = fc + random.nextInt(bc - interval);  int b = fc + random.nextInt(bc - interval);  return new Color(r, g, b);}%>


运行之后,能够生成验证码,而且也能够正确验证。
问题是:这句代码:ImageIO.write(image, "PNG", response.getOutputStream());
总是报异常!java.lang.IllegalStateException: getOutputStream() has already been called for this response

这段代码是在学校做项目,老师提供的。项目现在做好了,但总是这里有点瑕疵,心里总是不舒服。
因为代码是拷贝回来的,我也不知道怎么修改。请问怎样修改呢?谢谢!

------解决方案--------------------
1.新建servlet类继承自public class Image extends HttpServlet,实现doGet方法,把以上代码放在doGet方法里
2.在web.xml里配置servlet
XML code
    <servlet>        <servlet-name>Image</servlet-name>                <!--servlet类的全名,即包括包名+类名-->        <servlet-class>com.test.servlet.Image</servlet-class>        <load-on-startup>10</load-on-startup>    </servlet>    <servlet-mapping>        <servlet-name>Image</servlet-name>                <!--这里配置访问路径-->        <url-pattern>/servlet/Image</url-pattern>    </servlet-mapping>
------解决方案--------------------
out.clear();//获取新的body
out=pageContext.pushBody();
在jsp里清除out也可以排除异常
  相关解决方案