Java 生成中文验证码的方法
Java Web中生成中文验证码,首先随机拿到几个汉字,然后将获取到的汉字利用Graphics画在图片上面(也不知道我的这个说法对否,我是这么理解的)。具体的实现代码如下,仅作为参考!
package com.bkybk.tools; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.io.IOException; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.List; 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; import javax.servlet.http.HttpSession; public class CheckcodeServlet extends HttpServlet { private static final long serialVersionUID = 1L; /** * * 旋转和缩放文字 * * 必须要使用Graphics2d类 */ public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //生成一个消息头(content-type),告诉客户端(浏览器),返回的数据类型。 response.setContentType("text/html;charset=gbk"); Random r = new Random(); String strSession = ""; // 第一步:生成一张图片 int width = 88; int height = 22; // 创建一个内存映像对象 BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); // 获得画笔 Graphics g = image.getGraphics(); // 给笔上颜色(随机的一个颜色),设置背景颜色 g.setColor(new Color(255,255,255)); //设置画布的大小 g.fillRect(0, 0, width, height); //设置显示字体的样式大小 g.setFont(new Font("宋体", Font.PLAIN, 17)); //设置绘画位置 int startSize = 5; List<String> list = create(); //获得随机文字 for (int i = 0; i < 4; i++) { // 开始绘图 g.setColor(new Color(r.nextInt(200), r.nextInt(200), r.nextInt(200))); g.drawString(list.get(i), startSize, 18); startSize += 20; strSession += list.get(i); } HttpSession session = request.getSession(); // 将随机文字绑订到session对象上 session.setAttribute("checkCode", strSession); // 第二步,将图片压缩,并输出到时客户端 // 设置正确的消息头,告诉浏览器返回的是图片 response.setContentType("image/jpeg"); // 获得一个字节输出流 OutputStream ops = response.getOutputStream(); // 压缩并输出 javax.imageio.ImageIO.write(image, "jpeg", ops); } /** * * 原理是从汉字区位码找到汉字。在汉字区位码中分 高位与底位, 且其中简体又有繁体。位数越前生 成的汉字繁体的机率越大。 * * 所以在本例中高位从171取,底位从161取, 去掉大部 分的繁体和生僻字。但仍然会有!! * * */ public static List<String> create() { List<String> strList = new ArrayList<String>(); for (int i = 0; i < 4; i++) { try { // 定义高低位 int hightPos, lowPos; Random random = new Random(); // 获取高位值 hightPos = (176 + Math.abs(random.nextInt(39))); // 获取低位值 lowPos = (161 + Math.abs(random.nextInt(93))); byte[] b = new byte[2]; b[0] = (new Integer(hightPos).byteValue()); b[1] = (new Integer(lowPos).byteValue()); String str = new String(b, "GBK"); strList.add(str); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } return strList; } }