下面将使用Servlet输出图片验证码。图片验证码的原理是,服务器生成一个包含随机的字符串的图片发给客户端,客户端提交数据时需要填写字符串作为验证。由于字符串保存在图片中,因此机器很难识别,从而达到防止有人使用计算机程序恶意发送信息的目的。
注:Servlet输出图片时,需要调用getOutputStream输出图片,而不是getWriter
package com.fly.servlet; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.Random; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.sun.image.codec.jpeg.JPEGCodec; import com.sun.image.codec.jpeg.JPEGImageEncoder; public class IdentityServlet extends HttpServlet { private static final long serialVersionUID = 1L; //随即字符字典 public static final char[] CHARS = {'1','2','3','4','5','6','7','8','9','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'}; public static Random random = new Random();//随机数 //获取六位随机数 public static String getRandomString(){ StringBuffer buffer = new StringBuffer(); for(int i=0;i<6;++i){ buffer.append(CHARS[random.nextInt(CHARS.length)]); } return buffer.toString(); } //获取随机颜色 public static Color getRandomColor(){ return new Color(random.nextInt(255),random.nextInt(255),random.nextInt(255)); } //获取某颜色的反色 public static Color getReverseColor(Color c){ return new Color(255-c.getRed(),255-c.getGreen(),255-c.getBlue()); } public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{ response.setContentType("image/jpeg");//设置输出类型 String randomString = getRandomString();//随机字符串 request.getSession(true).setAttribute("randomString", randomString); int width = 100;//图片宽度 int height = 30;//图片高度 Color color = getRandomColor(); Color reverseColor = getReverseColor(color); //创建一个彩色图片 BufferedImage bi = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB); Graphics2D g = bi.createGraphics();//获取绘图对象 g.setFont(new Font(Font.SANS_SERIF,Font.BOLD,16));//设置字体 g.setColor(color);//设置颜色 g.fillRect(0, 0, width, height); g.setColor(reverseColor);//设置颜色 g.drawString(randomString, 18, 20); //画最多100个噪音点 for(int i=0,n=random.nextInt(100);i<n;++i){ //随机噪音点 g.drawRect(random.nextInt(width), random.nextInt(width), 1, 1); } //转成JPEG格式 ServletOutputStream out = response.getOutputStream(); //编码器 JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out); encoder.encode(bi);//对图片进行编码 out.flush();//输出到客户端 } }
该Servlet在web.xml中的配置如下:<?xml version="1.0" encoding="UTF-8"?><web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <servlet> <servlet-name>identityServlet</servlet-name> <servlet-class>com.fly.servlet.IdentityServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>identityServlet</servlet-name> <url-pattern>/identity</url-pattern> </servlet-mapping> </web-app>
然后就可以直接访问该Servlet,浏览图片了。为了方便演示,下面给出一个HTML文件引用这个图片验证码,代码如下:<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>identity.html</title> <script type="text/javascript"> function reloadImage(){ //document.getElementById('btn').disabled = true; document.getElementById('identityimg').src = 'identity?ts='+new Date().getTime(); } </script> </head> <body> <img src="identity" id="identityimg" onclick="btn.disabled=false"/> <input type=button value="换个图片" onclick="reloadImage()" id="btn"/> </body> </html>
这样就可以访问该html页面,浏览验证码图片了。效果如图所示:![]()