之前,我是用jsp里生成的图片,链接到img标签中的,如下:
<img src="code.jsp"/>
code.jsp中,为生成图片的java代码,大家应该都知道,我就不贴出来了。我现在想把code.jsp中的java代码,放在action中去,做成类似下面的,
<img src="codeGetCode.action"/> 也实现同样的效果,怎么做呢?
我调了很久,没能实现,我把关键代码都贴出来,请高人帮忙看下,哪里出问题了,谢谢。
struts.xml的主要代码:
<action name="codeGetCode" class="test.CodeAction" method="getCode">
<result name="success">null</result><!-- 这里肯定有问题的了,主要改这里和action中的getCode返回类型 -->
</action>CodeAction中的getCode方法如下: public String getCode() throws Exception{
response = ServletActionContext.getResponse();
// response.addHeader("Pragma", "no-cache");
// response.addHeader("Cache-Control", "no-store");
// response.setHeader("Pragma", "no-cache");
// response.setDateHeader("Expires", 0);
// response.setContentType("text/html");
// response.setCharacterEncoding("UTF-8");
HttpSession session = request.getSession();
// 设置编码及响应类型
response.setContentType("image/jpeg");
response.setCharacterEncoding("utf-8");
request.setCharacterEncoding("utf-8");
// 设置页面不缓存
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
//out.clear();//这句针对resin服务器,如果是tomacat可以不要这句
//out = pageContext.pushBody();
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
// 在内存中创建图象
int width = 60, height = 22;
BufferedImage image = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);
// 获取图形上下文
Graphics g = image.getGraphics(); // 生成随机类
Random random = new Random(); // 设定背景色
g.setColor(getRandColor(200, 250));
g.fillRect(0, 0, width, height); // 设定字体
g.setFont(new Font("Times New Roman", Font.PLAIN, 18)); // 画边框
// g.setColor(new Color());
// g.drawRect(0,0,width-1,height-1); // 随机产生155条干扰线,使图象中的认证码不易被其它程序探测到
g.setColor(getRandColor(160, 200));//getRandColor方法为得到一个随机的Color对象
for (int i = 0; i < 155; i++) {
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);
} // 取随机产生的认证码(4位数字)
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
// 保存入session,用于与用户的输入进行比较.
// 注意比较完之后清除session.
HttpSession session = request.getSession(false);
session.setAttribute("randCode", sRand); // 图象生效
g.dispose();
OutputStream output = response.getOutputStream(); // 输出图象到页面
ImageIO.write(image, "JPEG", response.getOutputStream());
output.flush();
output.close(); return SUCCESS;
}
//生成的随机颜色
private 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);
}说明下吧,生成图片的代码肯定是没问题的了,跟这部分代码应该没关系的,问题应该是出在,return 类型这里,我试了下类似为流,也没成功,后来要认为,应该返回的类似为:org.apache.struts2.dispatcher.HttpHeaderResult 对象,httpheader,但感觉也不对,不知道那里出问题的了。
<img src="code.jsp"/>
code.jsp中,为生成图片的java代码,大家应该都知道,我就不贴出来了。我现在想把code.jsp中的java代码,放在action中去,做成类似下面的,
<img src="codeGetCode.action"/> 也实现同样的效果,怎么做呢?
我调了很久,没能实现,我把关键代码都贴出来,请高人帮忙看下,哪里出问题了,谢谢。
struts.xml的主要代码:
<action name="codeGetCode" class="test.CodeAction" method="getCode">
<result name="success">null</result><!-- 这里肯定有问题的了,主要改这里和action中的getCode返回类型 -->
</action>CodeAction中的getCode方法如下: public String getCode() throws Exception{
response = ServletActionContext.getResponse();
// response.addHeader("Pragma", "no-cache");
// response.addHeader("Cache-Control", "no-store");
// response.setHeader("Pragma", "no-cache");
// response.setDateHeader("Expires", 0);
// response.setContentType("text/html");
// response.setCharacterEncoding("UTF-8");
HttpSession session = request.getSession();
// 设置编码及响应类型
response.setContentType("image/jpeg");
response.setCharacterEncoding("utf-8");
request.setCharacterEncoding("utf-8");
// 设置页面不缓存
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
//out.clear();//这句针对resin服务器,如果是tomacat可以不要这句
//out = pageContext.pushBody();
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
// 在内存中创建图象
int width = 60, height = 22;
BufferedImage image = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);
// 获取图形上下文
Graphics g = image.getGraphics(); // 生成随机类
Random random = new Random(); // 设定背景色
g.setColor(getRandColor(200, 250));
g.fillRect(0, 0, width, height); // 设定字体
g.setFont(new Font("Times New Roman", Font.PLAIN, 18)); // 画边框
// g.setColor(new Color());
// g.drawRect(0,0,width-1,height-1); // 随机产生155条干扰线,使图象中的认证码不易被其它程序探测到
g.setColor(getRandColor(160, 200));//getRandColor方法为得到一个随机的Color对象
for (int i = 0; i < 155; i++) {
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);
} // 取随机产生的认证码(4位数字)
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
// 保存入session,用于与用户的输入进行比较.
// 注意比较完之后清除session.
HttpSession session = request.getSession(false);
session.setAttribute("randCode", sRand); // 图象生效
g.dispose();
OutputStream output = response.getOutputStream(); // 输出图象到页面
ImageIO.write(image, "JPEG", response.getOutputStream());
output.flush();
output.close(); return SUCCESS;
}
//生成的随机颜色
private 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);
}说明下吧,生成图片的代码肯定是没问题的了,跟这部分代码应该没关系的,问题应该是出在,return 类型这里,我试了下类似为流,也没成功,后来要认为,应该返回的类似为:org.apache.struts2.dispatcher.HttpHeaderResult 对象,httpheader,但感觉也不对,不知道那里出问题的了。
下面是我使用AJAX+Struts生成图片的代码。
在AJAX中使用Struts2生成图片显示在浏览器里:
1. 创建BufferedImage并在它上面进行绘制.
2. 取得response的output stream,然后使用ImageIO写入图片数据.
3. 关闭output stream,这样图片就会发送到浏览器端.
4. <img src="pic.action">: 设置img的src为Struts2里面action的名字即可.---------------------------------- strust.xml配置 -------------------------
<package name="stuts-test" extends="struts-default" namespace="/">
<action name="pic" class="action.PictureAction" method="createPicture"></action>
</package>
----------------------------------服务器端代码:PictureAction.java -------------------------
package action;import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;import org.apache.struts2.ServletActionContext;import com.opensymphony.xwork2.ActionSupport;@SuppressWarnings("serial")
public class PictureAction extends ActionSupport { public void createPicture() throws Exception {
BufferedImage image = new BufferedImage(200, 200, BufferedImage.TYPE_INT_RGB);
Graphics g = image.getGraphics();
g.setColor(Color.WHITE);
g.fillOval(50, 50, 100, 100); ServletActionContext.getResponse().setContentType("image/png");
ServletOutputStream out = ServletActionContext.getResponse().getOutputStream();
ImageIO.write(image, "png", out);
out.close();
}
}
----------------------------------浏览器端网页代码:pic.html --------------------------------
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Title</title> <script src="jquery.js"></script>
<script type="text/javascript">
$(function() {
$("#ajaxImg").attr("src", "pic.action");
});
</script>
</head><body>
<img id="ajaxImg" />
</body>
</html>
1. 需要的jar包: patchca.jar: http://code.google.com/p/patchca/
patchca使用LGPL协议: GNU Lesser General Public License
2. 请求验证码的 JSP: validate.jsp
3. 产生验证码的 Servlet: ValidationCode.java
4. 验证验证码的 Servlet: ValidateCode.java验证过程: validate.jsp请求验证码 -> ValidationCode.java生成验证码图片和相应的字符给validate.jsp -> 用户输入验证码 -> ValidateCode.java验证用户的验证码是否输入正确.
================================== validate.jsp ==================================
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head><body>
<img src="ValidationCode">
<form action="ValidateCode" method="post">
<input type="text" name="validateCode"/>
<input type="submit" value="Submit"/>
</form>
</body>
</html> ================================== ValidateCode.java ==================================import java.io.IOException;import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;/**
* Servlet implementation class Validate
*/
public class ValidateCode extends HttpServlet {
private static final long serialVersionUID = 1L; public ValidateCode() {
super();
} @Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,
IOException {
String validateCode = request.getParameter("validateCode");
HttpSession session = request.getSession();
// 从session中取得验证码与用户输入的验证码进行比较
String storedValidateCode = (String) session.getAttribute(session.getId());
response.setHeader("Content-type", "text/html; charset=UTF-8");
if (validateCode.equalsIgnoreCase(storedValidateCode)) {
response.getWriter().println("验证码输入正确: " + validateCode);
} else {
response.getWriter().println("验证码输入错误: " + validateCode);
}
} @Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,
IOException {
doGet(request, response);
}
}
================================== ValidationCode.java ==================================
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 javax.servlet.http.HttpSession;import org.patchca.color.GradientColorFactory;
import org.patchca.filter.predefined.CurvesRippleFilterFactory;
import org.patchca.filter.predefined.DiffuseRippleFilterFactory;
import org.patchca.filter.predefined.DoubleRippleFilterFactory;
import org.patchca.filter.predefined.MarbleRippleFilterFactory;
import org.patchca.filter.predefined.RippleFilterFactory;
import org.patchca.filter.predefined.WobbleRippleFilterFactory;
import org.patchca.service.Captcha;
import org.patchca.service.ConfigurableCaptchaService;/**
* Servlet implementation class ValidateCode
*/
public class ValidationCode extends HttpServlet {
private static final long serialVersionUID = 1L; public ValidationCode() {
super();
} // 关键之处,产生图片 @Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,
IOException {
response.setContentType("image/png");
ValidateEntry ve = new ValidateEntry(); HttpSession session = request.getSession();
session.setAttribute(session.getId(), ve.getCode()); // 验证码保存在session中 ServletOutputStream out = response.getOutputStream();
BufferedImage img = ve.getImage();
ImageIO.write(img, "png", out);
out.close();
} @Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,
IOException {
doGet(request, response);
} protected class ValidateEntry {
String code;
BufferedImage image; ValidateEntry() {
createEntry();
} public String getCode() {
return code;
} public BufferedImage getImage() {
return image;
} private void createEntry() {
ConfigurableCaptchaService cs = new ConfigurableCaptchaService();
cs.setColorFactory(new GradientColorFactory());
switch ((int) (System.currentTimeMillis() % 6)) {
case 0:
cs.setFilterFactory(new CurvesRippleFilterFactory(cs.getColorFactory()));
break;
case 1:
cs.setFilterFactory(new MarbleRippleFilterFactory());
break;
case 2:
cs.setFilterFactory(new DoubleRippleFilterFactory());
break;
case 3:
cs.setFilterFactory(new WobbleRippleFilterFactory());
break;
case 4:
cs.setFilterFactory(new DiffuseRippleFilterFactory());
break;
case 5:
cs.setFilterFactory(new RippleFilterFactory());
break;
} Captcha captcha = cs.getCaptcha();
code = captcha.getChallenge();
image = captcha.getImage();
}
}
}