最近在做验证码的时候碰到了这样一个错误:
java.lang.IllegalStateException: getOutputStream() has already been called for this response
再三测试发现当在jsp页面上加上out.clear();和 pageContext.pushBody();的时候错误就会消失
下面我把源代码贴出来,以便以后使用,如果有朋友也碰到这样的错误也可以注意一下,少走弯路。
用来生成验证码图片的java类:
package com.xueji.common;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;
import javax.imageio.ImageIO;
/**
* @author dzy
* 生成验证码图片
*/
public class MakeCertPic {
//验证码图片中可以出现的字符集,可根据需要修改
private char mapTable[]={
'a','b','c','d','e','f',
'g','h','i','j','k','l',
'm','n','o','p','q','r',
's','t','u','v','w','x',
'y','z','0','1','2','3',
'4','5','6','7','8','9'};
/**
* 功能:生成彩色验证码图片
* 参数width为生成图片的宽度,参数height为生成图片的高度,参数os为页面的输出流
*/
public String getCertPic(int width, int height, OutputStream os) {
if(width<=0)width=60;
if(height<=0)height=20;
BufferedImage image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
// 获取图形上下文
Graphics g = image.getGraphics();
// 设定背景色
g.setColor(new Color(0xDCDCDC));
g.fillRect(0, 0, width, height);
//画边框
g.setColor(Color.black);
g.drawRect(0,0,width-1,height-1);
// 取随机产生的认证码
String strEnsure = "";
// 4代表4位验证码,如果要生成更多位的认证码,则加大数值
for(int i=0; i<4; ++i) {
strEnsure+=mapTable[(int)(mapTable.length*Math.random())];
}
// 将认证码显示到图像中,如果要生成更多位的认证码,增加drawString语句
g.setColor(Color.black);
g.setFont(new Font("Atlantic Inline",Font.PLAIN,18));
String str = strEnsure.substring(0,1);
g.drawString(str,8,17);
str = strEnsure.substring(1,2);
g.drawString(str,20,15);
str = strEnsure.substring(2,3);
g.drawString(str,35,18);
str = strEnsure.substring(3,4);
g.drawString(str,45,15);
// 随机产生10个干扰点
Random rand = new Random();
for (int i=0;i<10;i++) {
int x = rand.nextInt(width);
int y = rand.nextInt(height);
g.drawOval(x,y,1,1);
}
// 释放图形上下文
g.dispose();
try {
// 输出图像到页面
ImageIO.write(image, "JPEG", os);
os=null;
} catch (IOException e) {
return "";
}
return strEnsure;
}
}
放置验证码的jsp页面
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@page contentType="image/JPEG" %>
<%
out.clear();
pageContext.pushBody();
%>
struts 的Action:
package com.xueji.action;
import java.io.IOException;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.xueji.common.MakeCertPic;
public class MakeCertPicAction extends ActionSupport{
MakeCertPic makeCertPic = new MakeCertPic();
private String t;
public String getT() {
return t;
}
public void setT(String t) {
this.t = t;
}
public String makeCertPic(){
ActionContext cxt = ActionContext.getContext();
HttpServletResponse response = (HttpServletResponse)cxt.get(ServletActionContext.HTTP_RESPONSE);
HttpServletRequest request = (HttpServletRequest)cxt.get(ServletActionContext.HTTP_REQUEST);
String strEnsure = null;
try {
strEnsure = makeCertPic.getCertPic(0,0, response.getOutputStream());
request.getSession().setAttribute("certCode", strEnsure);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "makePic";
}
}
struts.xml;
<package name="registration" namespace="/" extends="struts-default">
<result-types>
<result-type name="json" class="org.apache.struts2.json.JSONResult"/>
</result-types>
<global-results>
<result name="error">/error.jsp</result>
</global-results>
<action name="makeCertPic" class="com.xueji.action.MakeCertPicAction" method="makeCertPic">
<result name="makePic">/comjsp/makeCertPic.jsp</result>
</action>
</package>
<!-- Add packages here -->
</struts>
登录界面:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>学生入口</title>
<link rel="stylesheet" type="text/css" href="css/style.css"/>
<script type="text/javascript" src="js/js.js"></script>
<script type="text/javascript">
function reloadcode(){
var verify=document.getElementById('safecode');
verify.setAttribute('src','makeCertPic?t='+Math.random());
}
</script>
</head>
<body>
<div id="top"> </div>
<form id="login" name="login" action="login_student" method="post">
<div id="center">
<div id="center_left"></div>
<div id="center_middle">
<div class="user">
<label>用户名:
<input type="text" name="username" id="user" />
</label>
</div>
<div class="user">
<label>密 码:
<input type="password" name="userpassword" id="pwd" />
</label>
</div>
<div class="chknumber">
<label>验证码:
<input name="chknumber" type="text" id="chknumber" maxlength="4" class="chknumber_input" />
</label>
<img src="makeCertPic" id="safecode" οnclick="reloadcode()" alt="看不清楚,换一张"/>
</div>
</div>
<div id="center_middle_right"></div>
<div id="center_submit">
<div class="button"> <img src="images/dl.gif" width="57" height="20" οnclick="form_submit()" > </div>
<div class="button"> <img src="images/cz.gif" width="57" height="20" οnclick="form_reset()"> </div>
</div>
<div id="center_right"></div>
</div>
</form>
<div id="footer"></div>
</body>
</html>