`
dreamoftch
  • 浏览: 485034 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

通过servlet或者struts2生成验证码

阅读更多

简易版servlet(另外的方式其实类似):

package com.tch.excel;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class AuthImage extends HttpServlet {

	private static final long serialVersionUID = 1L;
	private static char[] codeArr = new char[] {'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','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'};
	private Random random = new Random();
	public void service(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		int length = codeArr.length;
		int width = 200;
		int height = 100;
		//存放生成的字符
		String code = "";
		//存放最终的字符组成的字符串验证码
		String validateCode = "";
		//构建BufferedImage对象,用来存储生成的验证码图片(临时存放在内存中)
		BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		//获取BufferedImage的Graphics对象,Graphics起着画笔的作用,用来写验证码及其它内容
		Graphics graphics = bufferedImage.getGraphics();
		//开始在BufferedImage对象上面涂背景色
		graphics.setColor(Color.white);
		graphics.fillRect(0, 0, width-1, height-1);
		//在BufferedImage对象上面画边框
		graphics.setColor(Color.black);
		graphics.drawRect(0, 0, width-1, height-1);
		//设置要画的字符串的字体
		graphics.setFont(new Font("Comic Sans MS",Font.PLAIN,70));
		for(int i=0;i<4;i++){
			//随机产生字符
			code=""+codeArr[random.nextInt(length)];
			//随机产生颜色
			graphics.setColor(getRandColor());
			//将字符写到BufferedImage对象上(Graphics最终是写到对应的BufferedImage对象上面)
			graphics.drawString(code, 5+i*50, 70);
			//添加到验证码字符串里面
			validateCode += code;
		}
		System.out.println("validateCode : "+validateCode);
		//释放画笔占用的资源
		graphics.dispose();
		//将生成的图片通过response的输出流返回给页面
		ImageIO.write(bufferedImage, "JPEG", response.getOutputStream());
	}
	//产生随机颜色
	private Color getRandColor() {
		Random random = new Random();
		Color color[] = new Color[10];
		color[0] = new Color(32, 158, 25);
		color[1] = new Color(218, 42, 19);
		color[2] = new Color(31, 75, 208);
		return new Color(random.nextInt(220), random.nextInt(220), random.nextInt(220));
	}

}

 

  

 

 

servlet:

package com.tch.excel;
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;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class AuthImage extends HttpServlet {
	
	private static final long serialVersionUID = 1L;
	private Font mFont = new Font("Arial Black", Font.PLAIN, 16);

	public void init() throws ServletException {
		super.init();
	}

	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);
	}

	public void service(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		int width = 60, height = 18;
		mFont = new Font("Times New Roman", Font.PLAIN, 23);

		// 阻止生成的页面内容被缓存,保证每次重新生成随机验证码
		response.setHeader("Pragma", "No-cache");
		response.setHeader("Cache-Control", "no-cache");
		response.setDateHeader("Expires", 0);
		response.setContentType("image/jpeg");

		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(1, 1, width - 1, height - 1);

		// 设定字体
		// g.setFont(new Font("Times New Roman",Font.PLAIN,18));

		// 画边框
		g.setColor(new Color(102, 102, 102));
		g.drawRect(0, 0, width - 1, height - 1);

		g.setFont(mFont);

		// 随机产生155条干扰线,使图象中的认证码不易被其它程序探测到
		g.setColor(getRandColor(160, 200));
		for (int i = 0; i < 200; i++) {
			int x = random.nextInt(width - 1);
			int y = random.nextInt(height - 1);
			int xl = random.nextInt(6) + 1;
			int yl = random.nextInt(12) + 1;
			g.drawLine(x, y, x + xl, y + yl);
		}
		for (int i = 0; i < 70; i++) {
			int x = random.nextInt(width - 1);
			int y = random.nextInt(height - 1);
			int xl = random.nextInt(12) + 1;
			int yl = random.nextInt(6) + 1;
			g.drawLine(x, y, x - xl, y - yl);
		}

		String sRand = "";
		for (int i = 0; i < 4; i++)// 4位验证码
		{
			String tmp = getRandomChar();
			// 将产生的四个随机数组合在一起
			sRand += tmp;
			// 用随机产生的颜色将验证码绘制到图像中
			g.setColor(new Color(20 + random.nextInt(110), 20 + random
					.nextInt(110), 20 + random.nextInt(110)));
			g.drawString(tmp, 12 * i + 5, 15);
		}
		g.dispose();
		
		request.getSession().setAttribute("validateCode", sRand);
		System.out.println("validateCode : "+sRand);
		// 将图像输出到Servlet输出流中
		OutputStream outputStream = response.getOutputStream();
		ImageIO.write(image, "JPEG", outputStream);
		outputStream.close();
	}

	private String getRandomChar() {
		int rand = (int) Math.round(Math.random() * 2);
		long itmp = 0;
		char ctmp = '\u0000';
		switch (rand) {
		case 1:
			itmp = Math.round(Math.random() * 25 + 65);
			ctmp = (char) itmp;
			return String.valueOf(ctmp);
		case 2:
			itmp = Math.round(Math.random() * 25 + 97);
			ctmp = (char) itmp;
			return String.valueOf(ctmp);
		default:
			itmp = Math.round(Math.random() * 9);
			return String.valueOf(itmp);
		}
	}
}

 

 

 

在页面中:

<a href="###"><img src="http://localhost:8080/xxx/servlet/authImage" width="180" height="40" onclick="refreshCode();"></a>
<script type="text/javascript" charset="utf-8">
			function refreshCode(obj){
				obj.src = 'http://localhost:8080/xxx/servlet/authImage?d='+(new Date().getTime());
			}
</script>

并且在web.xml中配置authImage这个servlet即可;

 

 

其中生成验证码的过程还可以用另外的方法:

SessionHelper.setValidCode(req, AuthImageYj.SIMPLE_CAPCHA_SESSION_KEY,
				test);

		/**
		 * 得到输出流
		 */
		JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(resp
				.getOutputStream());

		BufferedImage bi = new BufferedImage(ImageWidth + 10, ImageHeight,
				BufferedImage.TYPE_BYTE_INDEXED);

		Graphics2D graphics = bi.createGraphics();

		/**
		 * 设置背景色
		 */
		// graphics.setColor(Color.white);
		graphics.setColor(new Color(random.nextInt(100), random.nextInt(100),
				random.nextInt(200)));

		graphics.fillRect(0, 0, bi.getWidth(), bi.getHeight());

		graphics.setColor(Color.black);
		AttributedString attstr = new AttributedString(test);

		TextLayout textTl = new TextLayout(test, new Font("Courier", Font.BOLD,
				70), new FontRenderContext(null, true, false));
		AffineTransform textAt = graphics.getTransform();
		graphics.setFont(new Font("Courier", Font.BOLD, 70));
		graphics.setColor(this.getRandColor());
		graphics.drawString(test, 10, 70);
		// textTl.draw(graphics, 4, 60);
		int w = bi.getWidth();
		int h = bi.getHeight();
		shear(graphics, w, h, Color.white);
		// this.drawThickLine(graphics, 0, generator.nextInt(ImageHeight) + 1,
		// ImageWidth, generator.nextInt(ImageHeight) + 1, 4, Color.BLACK);

		resp.setContentType("image/jpg");

		encoder.encode(bi);

 

 

通过struts2:可以参考http://blog.csdn.net/Yao_Qinwei/article/details/8244115

(蛋疼,过程中struts.xml没有加 <param name="inputName">imageStream</param>

然后再action中使用 InputStream  inputName,不知道为什么一直不行,非要换个名字才行,很蛋疼,不住地为啥)

 

 

 

将生成验证码的代码,放到action类里面:

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Map;
import java.util.Random;

import org.apache.struts2.interceptor.SessionAware;

import sun.awt.image.ImageFormatException;

import com.opensymphony.xwork2.ActionSupport;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

public class SecurityCodeImageAction extends ActionSupport implements
		SessionAware {
	private static char[] captchars = new char[] { 'a', 'b', 'c', 'd', 'e',
			'2', '3', '4', '5', '6', '7', '8', 'g', 'f', 'y', 'n', 'm', 'n',
			'p', 'w', 'x' };
	private Random generator = new Random();

	// 图片流
	private ByteArrayInputStream imageStream;

	private ByteArrayInputStream inputName;

	// session域
	private Map<String, Object> session;

	private void drawThickLine(Graphics g, int x1, int y1, int x2, int y2,
			int thickness, Color c) {

		// The thick line is in fact a filled polygon
		g.setColor(c);
		int dX = x2 - x1;
		int dY = y2 - y1;
		// line length
		double lineLength = Math.sqrt(dX * dX + dY * dY);

		double scale = (double) (thickness) / (2 * lineLength);

		// The x and y increments from an endpoint needed to create a
		// rectangle...
		double ddx = -scale * (double) dY;
		double ddy = scale * (double) dX;
		ddx += (ddx > 0) ? 0.5 : -0.5;
		ddy += (ddy > 0) ? 0.5 : -0.5;
		int dx = (int) ddx;
		int dy = (int) ddy;

		// Now we can compute the corner points...
		int xPoints[] = new int[4];
		int yPoints[] = new int[4];

		xPoints[0] = x1 + dx;
		yPoints[0] = y1 + dy;
		xPoints[1] = x1 - dx;
		yPoints[1] = y1 - dy;
		xPoints[2] = x2 - dx;
		yPoints[2] = y2 - dy;
		xPoints[3] = x2 + dx;
		yPoints[3] = y2 + dy;

		g.fillPolygon(xPoints, yPoints, 4);
	}
	/**
	 * @throws IOException
	 * @throws ImageFormatException
	 * @see javax.servlet.http.HttpServlet#void
	 *      (javax.servlet.http.HttpServletRequest,
	 *      javax.servlet.http.HttpServletResponse)
	 */
	public String execute() {

		int ImageWidth = 200;
		int ImageHeight = 100;
		Random random = new Random();

		int car = captchars.length - 1;
		/**
		 * 产生随机字符串
		 */
		String test = "";
		for (int i = 0; i < 4; i++) {
			test += captchars[generator.nextInt(car) + 1];
		}
		System.out.println(test);
		/**
		 * 放放Session
		 */

		/**
		 * 得到输出流
		 */
		JPEGImageEncoder encoder = null;
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		encoder = JPEGCodec.createJPEGEncoder(bos);

		BufferedImage bi = new BufferedImage(ImageWidth + 10, ImageHeight,
				BufferedImage.TYPE_BYTE_INDEXED);

		Graphics2D graphics = bi.createGraphics();

		/**
		 * 设置背景色
		 */
		// graphics.setColor(Color.white);
		graphics.setColor(new Color(random.nextInt(100), random.nextInt(100),
				random.nextInt(200)));

		graphics.fillRect(0, 0, bi.getWidth(), bi.getHeight());

		graphics.setColor(Color.black);
		// AttributedString attstr = new AttributedString(test);
		//
		// TextLayout textTl = new TextLayout(test, new Font("Courier",
		// Font.BOLD,
		// 70), new FontRenderContext(null, true, false));
		// AffineTransform textAt = graphics.getTransform();
		graphics.setFont(new Font("Courier", Font.BOLD, 70));
		graphics.setColor(this.getRandColor());
		graphics.drawString(test, 10, 70);
		// textTl.draw(graphics, 4, 60);
		int w = bi.getWidth();
		int h = bi.getHeight();
		shear(graphics, w, h, Color.white);

		try {
			encoder.encode(bi);
		} catch (IOException e) {
			e.printStackTrace();
		}
		inputName = new ByteArrayInputStream(bos.toByteArray());
		return "success";
	}

	/**
	 * 产生随机字体
	 * 
	 * @return
	 */
	private Font getFont() {
		Random random = new Random();
		Font font[] = new Font[5];
		font[0] = new Font("Ravie", Font.PLAIN, 45);
		font[1] = new Font("Antique Olive Compact", Font.PLAIN, 45);
		font[2] = new Font("Forte", Font.PLAIN, 45);
		font[3] = new Font("Wide Latin", Font.PLAIN, 40);
		font[4] = new Font("Gill Sans Ultra Bold", Font.PLAIN, 45);
		return font[random.nextInt(5)];
	}

	public ByteArrayInputStream getImageStream() {
		return imageStream;
	}

	public ByteArrayInputStream getInputName() {
		return inputName;
	}

	/**
	 * 随机产生定义的颜色
	 * 
	 * @return
	 */
	private Color getRandColor() {
		Random random = new Random();
		Color color[] = new Color[10];
		color[0] = new Color(32, 158, 25);
		color[1] = new Color(218, 42, 19);
		color[2] = new Color(31, 75, 208);
		// return color[random.nextInt(3)];
		return new Color(random.nextInt(220), random.nextInt(220),
				random.nextInt(220));
	}

	public void setImageStream(ByteArrayInputStream imageStream) {
		this.imageStream = imageStream;
	}

	public void setInputName(ByteArrayInputStream inputName) {
		this.inputName = inputName;
	}

	public void setSession(Map<String, Object> session) {
		this.session = session;
	}

	private void shear(Graphics g, int w1, int h1, Color color) {

		shearX(g, w1, h1, color);
		shearY(g, w1, h1, color);
	}

	public void shearX(Graphics g, int w1, int h1, Color color) {

		int period = generator.nextInt(2);

		boolean borderGap = true;
		int frames = 1;
		int phase = generator.nextInt(2);

		for (int i = 0; i < h1; i++) {
			double d = (double) (period >> 1)
					* Math.sin((double) i / (double) period
							+ (6.2831853071795862D * (double) phase)
							/ (double) frames);
			g.copyArea(0, i, w1, 1, (int) d, 0);
			if (borderGap) {
				g.setColor(color);
				g.drawLine((int) d, i, 0, i);
				g.drawLine((int) d + w1, i, w1, i);
			}
		}

	}

	public void shearY(Graphics g, int w1, int h1, Color color) {

		int period = generator.nextInt(40) + 10; // 50;

		boolean borderGap = true;
		int frames = 20;
		int phase = 7;
		for (int i = 0; i < w1; i++) {
			double d = (double) (period >> 1)
					* Math.sin((double) i / (double) period
							+ (6.2831853071795862D * (double) phase)
							/ (double) frames);
			g.copyArea(i, 0, 1, h1, 0, (int) d);
			if (borderGap) {
				g.setColor(color);
				g.drawLine(i, (int) d, i, 0);
				g.drawLine(i, (int) d + h1, i, h1);
			}

		}

	}

}

 

struts.xml代码加入:

 

<action name="SecurityCodeImageAction" class="SecurityCodeImageAction">
            <result name="success" type="stream">
                 <param name="contentType">image/jpeg</param>
                 <param name="inputName">imageStream</param>
                 <param name="bufferSize">2048</param>
             </result>
         </action>

 

页面:

 

<html>
<head>
<script type="text/javascript">
	function cl2(a) {
		a.src = 'http://localhost:8090/WebTest/SecurityCodeImageAction.action?t="'
				+ new Date()
	}
</script>
</head>
<body>
	<s:a href="download.action">下载</s:a>
	<a href="###"><image
			src="/Struts2_10/SecurityCodeImageAction.action" width="180"
			height="40" onclick="cl2(this);"></image>
	</a>
</body>
</html>

 OK。

分享到:
评论

相关推荐

    Servlet和Struts2两种方法生成及校验验证吗

    Servlet和Struts2两种方法生成及校验验证吗,包含所有源码,下载就可以用。

    数字验证码(Servlet形式)

    生成验证码,本验证码为Servlet形式,可以凭开发经验,例如在Struts中,将其写在Action的方法中(void类型)从而转为Struts形式,调用时只需使img标签的src属性= 1.(servletname) 2.(methodname_actionname.action)

    汉字验证码(Servlet形式)

    生成验证码,本验证码为Servlet形式,可以凭开发经验,例如在Struts中,将其写在Action的方法中(void类型)从而转为Struts形式,调用时只需使img标签的src属性= 1.(servletname) 2.(methodname_actionname.action)

    java web加法验证码实例

    采用简单servlet生成加法验证码实例,可合并到struts、ssh2、mybatis等框架项目中,希望对你们有所帮助

    随即数字验证码的生成(源码)

    本人用java语言编写的《随即数字验证码的生成》源码,希望能给大家带来帮助,更多的了解java的编程思想,祝初学者成功!!!

    FreeMarke实例代码

    FreeMarker允许Java servlet保持图形设计同应用程序逻辑的...FreeMarker同样可以应用于非Web应用程序环境 FreeMarker更适合作为Model2框架(如Struts)的视图组件,你也可以在模板中使用JSP标记库 FreeMarker是免费的

    JAVA WEB典型模块与项目实战大全

    第19章 生成报表(struts 2.x+hibernate+jxl)  19.1 生成报表原理  19.2 下载jxl组件  19.3 生成报表前期准备  19.4 生成报表具体开发——持久层和服务层  19.5 生成报表具体开发——表示层  19.6 多学...

    JAVA程序开发大全---上半部分

    20.5.4 生成随机验证码的imgNum类 358 20.5.5 用户登录页面index.jsp 359 20.5.6 验证用户登录信息的Servlet类login 360 20.6 显示宠物信息模块的实现 363 20.6.1 对应宠物的实体类User 363 20.6.2 定义对宠物信息...

    java开源包2

    Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (&lt;jcaptcha:image label="Type the text "/&gt; ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码图片。 Java 命令行解析...

    Java学习笔记-个人整理的

    \contentsline {chapter}{Contents}{2}{section*.1} {1}Java基础}{17}{chapter.1} {1.1}基本语法}{17}{section.1.1} {1.2}数字表达方式}{17}{section.1.2} {1.3}补码}{19}{section.1.3} {1.3.1}总结}{23}{...

    java开源包1

    Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (&lt;jcaptcha:image label="Type the text "/&gt; ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码图片。 Java 命令行解析...

    java开源包11

    Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (&lt;jcaptcha:image label="Type the text "/&gt; ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码图片。 Java 命令行解析...

    java开源包3

    Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (&lt;jcaptcha:image label="Type the text "/&gt; ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码图片。 Java 命令行解析...

    java开源包6

    Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (&lt;jcaptcha:image label="Type the text "/&gt; ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码图片。 Java 命令行解析...

    java开源包5

    Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (&lt;jcaptcha:image label="Type the text "/&gt; ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码图片。 Java 命令行解析...

    java开源包10

    Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (&lt;jcaptcha:image label="Type the text "/&gt; ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码图片。 Java 命令行解析...

    java开源包4

    Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (&lt;jcaptcha:image label="Type the text "/&gt; ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码图片。 Java 命令行解析...

    java开源包8

    Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (&lt;jcaptcha:image label="Type the text "/&gt; ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码图片。 Java 命令行解析...

    java开源包7

    Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (&lt;jcaptcha:image label="Type the text "/&gt; ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码图片。 Java 命令行解析...

    java开源包9

    Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (&lt;jcaptcha:image label="Type the text "/&gt; ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码图片。 Java 命令行解析...

Global site tag (gtag.js) - Google Analytics