分享

【Java】生成图形验证码

 昵称67046736 2020-07-30

生成验证码工具类

package com.util;

import java.awt.Color;

import java.awt.Font;

import java.awt.Graphics;

import java.awt.Graphics2D;

import java.awt.RenderingHints;

import java.awt.geom.AffineTransform;

import java.awt.image.BufferedImage;

import java.io.File;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.OutputStream;

import java.util.Arrays;

import java.util.Random;

import javax.imageio.ImageIO;

public class VerifyCodeUtils {

    //使用到Algerian字体,系统里没有的话需要安装字体,字体只显示大写,

去掉了1,0,i,o几个容易混淆的字符

    public static final String VERIFY_CODES = 

"23456789ABCDEFGHJKLMNPQRSTUVWXYZ";

    private static Random random = new Random();

    /**

     * 使用系统默认字符源生成验证码

     * @param verifySize    验证码长度

     * @return

     */

    public static String generateVerifyCode(int verifySize){

        return generateVerifyCode(verifySize, VERIFY_CODES);

    }

    /**

     * 使用指定源生成验证码

     * @param verifySize    验证码长度

     * @param sources   验证码字符源

     * @return

     */

    public static String generateVerifyCode(int verifySize, String 

sources){

        if(sources == null || sources.length() == 0){

            sources = VERIFY_CODES;

        }

        int codesLen = sources.length();

        Random rand = new Random(System.currentTimeMillis());

        StringBuilder verifyCode = new StringBuilder(verifySize);

        for(int i = 0; i < verifySize; i++){

            verifyCode.append(sources.charAt(rand.nextInt(codesLen-

1)));

        }

        return verifyCode.toString();

    }

    /**

     * 生成随机验证码文件,并返回验证码值

     * @param w

     * @param h

     * @param outputFile

     * @param verifySize

     * @return

     * @throws IOException

     */

    public static String outputVerifyImage(int w, int h, File 

outputFile, int verifySize) throws IOException{

        String verifyCode = generateVerifyCode(verifySize);

        outputImage(w, h, outputFile, verifyCode);

        return verifyCode;

    }

    /**

     * 输出随机验证码图片流,并返回验证码值

     * @param w

     * @param h

     * @param os

     * @param verifySize

     * @return

     * @throws IOException

     */

    public static String outputVerifyImage(int w, int h, OutputStream 

os, int verifySize) throws IOException{

        String verifyCode = generateVerifyCode(verifySize);

        outputImage(w, h, os, verifyCode);

        return verifyCode;

    }

    /**

     * 生成指定验证码图像文件

     * @param w

     * @param h

     * @param outputFile

     * @param code

     * @throws IOException

     */

    public static void outputImage(int w, int h, File outputFile, 

String code) throws IOException{

        if(outputFile == null){

            return;

        }

        File dir = outputFile.getParentFile();

        if(!dir.exists()){

            dir.mkdirs();

        }

        try{

            outputFile.createNewFile();

            FileOutputStream fos = new FileOutputStream(outputFile);

            outputImage(w, h, fos, code);

            fos.close();

        } catch(IOException e){

            throw e;

        }

    }

    /**

     * 输出指定验证码图片流

     * @param w

     * @param h

     * @param os

     * @param code

     * @throws IOException

     */

    public static void outputImage(int w, int h, OutputStream os, 

String code) throws IOException{

        int verifySize = code.length();

        BufferedImage image = new BufferedImage(w, h, 

BufferedImage.TYPE_INT_RGB);

        Random rand = new Random();

        Graphics2D g2 = image.createGraphics();

        g2.setRenderingHint

(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);

        Color[] colors = new Color[5];

        Color[] colorSpaces = new Color[] { Color.WHITE, Color.CYAN,

                Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA, 

Color.ORANGE,

                Color.PINK, Color.YELLOW };

        float[] fractions = new float[colors.length];

        for(int i = 0; i < colors.length; i++){

            colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)];

            fractions[i] = rand.nextFloat();

        }

        Arrays.sort(fractions);

        g2.setColor(Color.GRAY);// 设置边框色

        g2.fillRect(0, 0, w, h);

        Color c = getRandColor(200, 250);

        g2.setColor(c);// 设置背景色

        g2.fillRect(0, 2, w, h-4);

        //绘制干扰线

        Random random = new Random();

        g2.setColor(getRandColor(160, 200));// 设置线条的颜色

        for (int i = 0; i < 20; i++) {

            int x = random.nextInt(w - 1);

            int y = random.nextInt(h - 1);

            int xl = random.nextInt(6) + 1;

            int yl = random.nextInt(12) + 1;

            g2.drawLine(x, y, x + xl + 40, y + yl + 20);

        }

        // 添加噪点

        float yawpRate = 0.05f;// 噪声率

        int area = (int) (yawpRate * w * h);

        for (int i = 0; i < area; i++) {

            int x = random.nextInt(w);

            int y = random.nextInt(h);

            int rgb = getRandomIntColor();

            image.setRGB(x, y, rgb);

        }

        shear(g2, w, h, c);// 使图片扭曲

        g2.setColor(getRandColor(100, 160));

        int fontSize = h-4;

        Font font = new Font("Algerian", Font.ITALIC, fontSize);

        g2.setFont(font);

        char[] chars = code.toCharArray();

        for(int i = 0; i < verifySize; i++){

            AffineTransform affine = new AffineTransform();

            affine.setToRotation(Math.PI / 4 * rand.nextDouble() * 

(rand.nextBoolean() ? 1 : -1), (w / verifySize) * i + fontSize/2, 

h/2);

            g2.setTransform(affine);

            g2.drawChars(chars, i, 1, ((w-10) / verifySize) * i + 5, 

h/2 + fontSize/2 - 10);

        }

        g2.dispose();

        ImageIO.write(image, "png", os);

    }

    private static Color getRandColor(int fc, int bc) {

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

    }

    private static int getRandomIntColor() {

        int[] rgb = getRandomRgb();

        int color = 0;

        for (int c : rgb) {

            color = color << 8;

            color = color | c;

        }

        return color;

    }

    private static int[] getRandomRgb() {

        int[] rgb = new int[3];

        for (int i = 0; i < 3; i++) {

            rgb[i] = random.nextInt(255);

        }

        return rgb;

    }

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

{

        shearX(g, w1, h1, color);

        shearY(g, w1, h1, color);

    }

    private static void shearX(Graphics g, int w1, int h1, Color 

color) {

        int period = random.nextInt(2);

        boolean borderGap = true;

        int frames = 1;

        int phase = random.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);

            }

        }

    }

    private static void shearY(Graphics g, int w1, int h1, Color 

color) {

        int period = random.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);

            }

        }

    }

    public static void main(String[] args) throws IOException{

        File dir = new File("C:/Users/H__D/Desktop/");

        int w = 200, h = 80;

        String verifyCode = generateVerifyCode(4);

        File file = new File(dir, verifyCode + ".jpg");

        outputImage(w, h, file, verifyCode);

    }

}

使用图形验证码

1、使用流程

技术图片

2、服务器端生成验证码servlet

package com.servlet;

import java.io.IOException;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import com.util.VerifyCodeUtils;

public class CreateCodeServlet extends HttpServlet {

    @Override

    protected void doGet(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {

        resp.setHeader("Pragma", "No-cache");  

        resp.setHeader("Cache-Control", "no-cache");  

        resp.setDateHeader("Expires", 0);  

        resp.setContentType("image/jpeg");  

        //生成随机字串  

        String verifyCode = VerifyCodeUtils.generateVerifyCode(4);  

        //存入会话session  

        req.getSession().setAttribute("CODE", verifyCode.toLowerCase

());  

        //生成图片  

        int width = 100;//宽

        int height = 40;//高  

        VerifyCodeUtils.outputImage(width, height, 

resp.getOutputStream(), verifyCode);  

    }

    @Override

    protected void doPost(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {

        // TODO Auto-generated method stub

        doGet(req, resp);

    }

}

3、服务器端验证验证码servlet

package com.servlet;

import java.io.IOException;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import com.util.VerifyCodeUtils;

public class VerifyCodeServlet extends HttpServlet {

    @Override

    protected void doGet(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {

        String code = req.getParameter("code");

        String key = (String) req.getSession().getAttribute("CODE");

        if(code != null && code.equalsIgnoreCase(key)){

            req.getSession().removeAttribute("CODE");

            resp.getWriter().println(true);

        }else{

            resp.getWriter().println(false);

        }

    }

    @Override

    protected void doPost(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {

        // TODO Auto-generated method stub

        super.doGet(req, resp);

    }

}

4、servet的注册,web.xml文件

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="http://生成验证码工具类

package com.util;

import java.awt.Color;

import java.awt.Font;

import java.awt.Graphics;

import java.awt.Graphics2D;

import java.awt.RenderingHints;

import java.awt.geom.AffineTransform;

import java.awt.image.BufferedImage;

import java.io.File;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.OutputStream;

import java.util.Arrays;

import java.util.Random;

import javax.imageio.ImageIO;

public class VerifyCodeUtils {

    //使用到Algerian字体,系统里没有的话需要安装字体,字体只显示大写,

去掉了1,0,i,o几个容易混淆的字符

    public static final String VERIFY_CODES = 

"23456789ABCDEFGHJKLMNPQRSTUVWXYZ";

    private static Random random = new Random();

    /**

     * 使用系统默认字符源生成验证码

     * @param verifySize    验证码长度

     * @return

     */

    public static String generateVerifyCode(int verifySize){

        return generateVerifyCode(verifySize, VERIFY_CODES);

    }

    /**

     * 使用指定源生成验证码

     * @param verifySize    验证码长度

     * @param sources   验证码字符源

     * @return

     */

    public static String generateVerifyCode(int verifySize, String 

sources){

        if(sources == null || sources.length() == 0){

            sources = VERIFY_CODES;

        }

        int codesLen = sources.length();

        Random rand = new Random(System.currentTimeMillis());

        StringBuilder verifyCode = new StringBuilder(verifySize);

        for(int i = 0; i < verifySize; i++){

            verifyCode.append(sources.charAt(rand.nextInt(codesLen-

1)));

        }

        return verifyCode.toString();

    }

    /**

     * 生成随机验证码文件,并返回验证码值

     * @param w

     * @param h

     * @param outputFile

     * @param verifySize

     * @return

     * @throws IOException

     */

    public static String outputVerifyImage(int w, int h, File 

outputFile, int verifySize) throws IOException{

        String verifyCode = generateVerifyCode(verifySize);

        outputImage(w, h, outputFile, verifyCode);

        return verifyCode;

    }

    /**

     * 输出随机验证码图片流,并返回验证码值

     * @param w

     * @param h

     * @param os

     * @param verifySize

     * @return

     * @throws IOException

     */

    public static String outputVerifyImage(int w, int h, OutputStream 

os, int verifySize) throws IOException{

        String verifyCode = generateVerifyCode(verifySize);

        outputImage(w, h, os, verifyCode);

        return verifyCode;

    }

    /**

     * 生成指定验证码图像文件

     * @param w

     * @param h

     * @param outputFile

     * @param code

     * @throws IOException

     */

    public static void outputImage(int w, int h, File outputFile, 

String code) throws IOException{

        if(outputFile == null){

            return;

        }

        File dir = outputFile.getParentFile();

        if(!dir.exists()){

            dir.mkdirs();

        }

        try{

            outputFile.createNewFile();

            FileOutputStream fos = new FileOutputStream(outputFile);

            outputImage(w, h, fos, code);

            fos.close();

        } catch(IOException e){

            throw e;

        }

    }

    /**

     * 输出指定验证码图片流

     * @param w

     * @param h

     * @param os

     * @param code

     * @throws IOException

     */

    public static void outputImage(int w, int h, OutputStream os, 

String code) throws IOException{

        int verifySize = code.length();

        BufferedImage image = new BufferedImage(w, h, 

BufferedImage.TYPE_INT_RGB);

        Random rand = new Random();

        Graphics2D g2 = image.createGraphics();

        g2.setRenderingHint

(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);

        Color[] colors = new Color[5];

        Color[] colorSpaces = new Color[] { Color.WHITE, Color.CYAN,

                Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA, 

Color.ORANGE,

                Color.PINK, Color.YELLOW };

        float[] fractions = new float[colors.length];

        for(int i = 0; i < colors.length; i++){

            colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)];

            fractions[i] = rand.nextFloat();

        }

        Arrays.sort(fractions);

        g2.setColor(Color.GRAY);// 设置边框色

        g2.fillRect(0, 0, w, h);

        Color c = getRandColor(200, 250);

        g2.setColor(c);// 设置背景色

        g2.fillRect(0, 2, w, h-4);

        //绘制干扰线

        Random random = new Random();

        g2.setColor(getRandColor(160, 200));// 设置线条的颜色

        for (int i = 0; i < 20; i++) {

            int x = random.nextInt(w - 1);

            int y = random.nextInt(h - 1);

            int xl = random.nextInt(6) + 1;

            int yl = random.nextInt(12) + 1;

            g2.drawLine(x, y, x + xl + 40, y + yl + 20);

        }

        // 添加噪点

        float yawpRate = 0.05f;// 噪声率

        int area = (int) (yawpRate * w * h);

        for (int i = 0; i < area; i++) {

            int x = random.nextInt(w);

            int y = random.nextInt(h);

            int rgb = getRandomIntColor();

            image.setRGB(x, y, rgb);

        }

        shear(g2, w, h, c);// 使图片扭曲

        g2.setColor(getRandColor(100, 160));

        int fontSize = h-4;

        Font font = new Font("Algerian", Font.ITALIC, fontSize);

        g2.setFont(font);

        char[] chars = code.toCharArray();

        for(int i = 0; i < verifySize; i++){

            AffineTransform affine = new AffineTransform();

            affine.setToRotation(Math.PI / 4 * rand.nextDouble() * 

(rand.nextBoolean() ? 1 : -1), (w / verifySize) * i + fontSize/2, 

h/2);

            g2.setTransform(affine);

            g2.drawChars(chars, i, 1, ((w-10) / verifySize) * i + 5, 

h/2 + fontSize/2 - 10);

        }

        g2.dispose();

        ImageIO.write(image, "png", os);

    }

    private static Color getRandColor(int fc, int bc) {

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

    }

    private static int getRandomIntColor() {

        int[] rgb = getRandomRgb();

        int color = 0;

        for (int c : rgb) {

            color = color << 8;

            color = color | c;

        }

        return color;

    }

    private static int[] getRandomRgb() {

        int[] rgb = new int[3];

        for (int i = 0; i < 3; i++) {

            rgb[i] = random.nextInt(255);

        }

        return rgb;

    }

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

{

        shearX(g, w1, h1, color);

        shearY(g, w1, h1, color);

    }

    private static void shearX(Graphics g, int w1, int h1, Color 

color) {

        int period = random.nextInt(2);

        boolean borderGap = true;

        int frames = 1;

        int phase = random.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);

            }

        }

    }

    private static void shearY(Graphics g, int w1, int h1, Color 

color) {

        int period = random.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);

            }

        }

    }

    public static void main(String[] args) throws IOException{

        File dir = new File("C:/Users/H__D/Desktop/");

        int w = 200, h = 80;

        String verifyCode = generateVerifyCode(4);

        File file = new File(dir, verifyCode + ".jpg");

        outputImage(w, h, file, verifyCode);

    }

}

使用图形验证码

1、使用流程

技术图片

2、服务器端生成验证码servlet

package com.servlet;

import java.io.IOException;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import com.util.VerifyCodeUtils;

public class CreateCodeServlet extends HttpServlet {

    @Override

    protected void doGet(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {

        resp.setHeader("Pragma", "No-cache");  

        resp.setHeader("Cache-Control", "no-cache");  

        resp.setDateHeader("Expires", 0);  

        resp.setContentType("image/jpeg");  

        //生成随机字串  

        String verifyCode = VerifyCodeUtils.generateVerifyCode(4);  

        //存入会话session  

        req.getSession().setAttribute("CODE", verifyCode.toLowerCase

());  

        //生成图片  

        int width = 100;//宽

        int height = 40;//高  

        VerifyCodeUtils.outputImage(width, height, 

resp.getOutputStream(), verifyCode);  

    }

    @Override

    protected void doPost(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {

        // TODO Auto-generated method stub

        doGet(req, resp);

    }

}

3、服务器端验证验证码servlet

package com.servlet;

import java.io.IOException;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import com.util.VerifyCodeUtils;

public class VerifyCodeServlet extends HttpServlet {

    @Override

    protected void doGet(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {

        String code = req.getParameter("code");

        String key = (String) req.getSession().getAttribute("CODE");

        if(code != null && code.equalsIgnoreCase(key)){

            req.getSession().removeAttribute("CODE");

            resp.getWriter().println(true);

        }else{

            resp.getWriter().println(false);

        }

    }

    @Override

    protected void doPost(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {

        // TODO Auto-generated method stub

        super.doGet(req, resp);

    }

}

4、servet的注册,web.xml文件

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="http://www.-instance" 

xmlns="http://java./xml/ns/javaee" 

xsi:schemaLocation="http://java./xml/ns/javaee 

http://java./xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" 

version="3.0">

  <display-name>test-captcha</display-name>

  <servlet>

      <servlet-name>CreateCodeServlet</servlet-name>

      <servlet-class>com.servlet.CreateCodeServlet</servlet-class>

  </servlet>

  <servlet-mapping>

      <servlet-name>CreateCodeServlet</servlet-name>

      <url-pattern>/createCode</url-pattern>

  </servlet-mapping>

   <servlet>

      <servlet-name>VerifyCodeServlet</servlet-name>

      <servlet-class>com.servlet.VerifyCodeServlet</servlet-class>

  </servlet>

  <servlet-mapping>

      <servlet-name>VerifyCodeServlet</servlet-name>

      <url-pattern>/verifyCode</url-pattern>

  </servlet-mapping>

  <welcome-file-list>

    <welcome-file>index.jsp</welcome-file>

  </welcome-file-list>

</web-app>

5、前端html文件

<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//深圳市博纳网络信息技术有限公司//DTD HTML 4.01 Transitional//EN" 

"http://生成验证码工具类

package com.util;

import java.awt.Color;

import java.awt.Font;

import java.awt.Graphics;

import java.awt.Graphics2D;

import java.awt.RenderingHints;

import java.awt.geom.AffineTransform;

import java.awt.image.BufferedImage;

import java.io.File;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.OutputStream;

import java.util.Arrays;

import java.util.Random;

import javax.imageio.ImageIO;

public class VerifyCodeUtils {

    //使用到Algerian字体,系统里没有的话需要安装字体,字体只显示大写,

去掉了1,0,i,o几个容易混淆的字符

    public static final String VERIFY_CODES = 

"23456789ABCDEFGHJKLMNPQRSTUVWXYZ";

    private static Random random = new Random();

    /**

     * 使用系统默认字符源生成验证码

     * @param verifySize    验证码长度

     * @return

     */

    public static String generateVerifyCode(int verifySize){

        return generateVerifyCode(verifySize, VERIFY_CODES);

    }

    /**

     * 使用指定源生成验证码

     * @param verifySize    验证码长度

     * @param sources   验证码字符源

     * @return

     */

    public static String generateVerifyCode(int verifySize, String 

sources){

        if(sources == null || sources.length() == 0){

            sources = VERIFY_CODES;

        }

        int codesLen = sources.length();

        Random rand = new Random(System.currentTimeMillis());

        StringBuilder verifyCode = new StringBuilder(verifySize);

        for(int i = 0; i < verifySize; i++){

            verifyCode.append(sources.charAt(rand.nextInt(codesLen-

1)));

        }

        return verifyCode.toString();

    }

    /**

     * 生成随机验证码文件,并返回验证码值

     * @param w

     * @param h

     * @param outputFile

     * @param verifySize

     * @return

     * @throws IOException

     */

    public static String outputVerifyImage(int w, int h, File 

outputFile, int verifySize) throws IOException{

        String verifyCode = generateVerifyCode(verifySize);

        outputImage(w, h, outputFile, verifyCode);

        return verifyCode;

    }

    /**

     * 输出随机验证码图片流,并返回验证码值

     * @param w

     * @param h

     * @param os

     * @param verifySize

     * @return

     * @throws IOException

     */

    public static String outputVerifyImage(int w, int h, OutputStream 

os, int verifySize) throws IOException{

        String verifyCode = generateVerifyCode(verifySize);

        outputImage(w, h, os, verifyCode);

        return verifyCode;

    }

    /**

     * 生成指定验证码图像文件

     * @param w

     * @param h

     * @param outputFile

     * @param code

     * @throws IOException

     */

    public static void outputImage(int w, int h, File outputFile, 

String code) throws IOException{

        if(outputFile == null){

            return;

        }

        File dir = outputFile.getParentFile();

        if(!dir.exists()){

            dir.mkdirs();

        }

        try{

            outputFile.createNewFile();

            FileOutputStream fos = new FileOutputStream(outputFile);

            outputImage(w, h, fos, code);

            fos.close();

        } catch(IOException e){

            throw e;

        }

    }

    /**

     * 输出指定验证码图片流

     * @param w

     * @param h

     * @param os

     * @param code

     * @throws IOException

     */

    public static void outputImage(int w, int h, OutputStream os, 

String code) throws IOException{

        int verifySize = code.length();

        BufferedImage image = new BufferedImage(w, h, 

BufferedImage.TYPE_INT_RGB);

        Random rand = new Random();

        Graphics2D g2 = image.createGraphics();

        g2.setRenderingHint

(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);

        Color[] colors = new Color[5];

        Color[] colorSpaces = new Color[] { Color.WHITE, Color.CYAN,

                Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA, 

Color.ORANGE,

                Color.PINK, Color.YELLOW };

        float[] fractions = new float[colors.length];

        for(int i = 0; i < colors.length; i++){

            colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)];

            fractions[i] = rand.nextFloat();

        }

        Arrays.sort(fractions);

        g2.setColor(Color.GRAY);// 设置边框色

        g2.fillRect(0, 0, w, h);

        Color c = getRandColor(200, 250);

        g2.setColor(c);// 设置背景色

        g2.fillRect(0, 2, w, h-4);

        //绘制干扰线

        Random random = new Random();

        g2.setColor(getRandColor(160, 200));// 设置线条的颜色

        for (int i = 0; i < 20; i++) {

            int x = random.nextInt(w - 1);

            int y = random.nextInt(h - 1);

            int xl = random.nextInt(6) + 1;

            int yl = random.nextInt(12) + 1;

            g2.drawLine(x, y, x + xl + 40, y + yl + 20);

        }

        // 添加噪点

        float yawpRate = 0.05f;// 噪声率

        int area = (int) (yawpRate * w * h);

        for (int i = 0; i < area; i++) {

            int x = random.nextInt(w);

            int y = random.nextInt(h);

            int rgb = getRandomIntColor();

            image.setRGB(x, y, rgb);

        }

        shear(g2, w, h, c);// 使图片扭曲

        g2.setColor(getRandColor(100, 160));

        int fontSize = h-4;

        Font font = new Font("Algerian", Font.ITALIC, fontSize);

        g2.setFont(font);

        char[] chars = code.toCharArray();

        for(int i = 0; i < verifySize; i++){

            AffineTransform affine = new AffineTransform();

            affine.setToRotation(Math.PI / 4 * rand.nextDouble() * 

(rand.nextBoolean() ? 1 : -1), (w / verifySize) * i + fontSize/2, 

h/2);

            g2.setTransform(affine);

            g2.drawChars(chars, i, 1, ((w-10) / verifySize) * i + 5, 

h/2 + fontSize/2 - 10);

        }

        g2.dispose();

        ImageIO.write(image, "png", os);

    }

    private static Color getRandColor(int fc, int bc) {

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

    }

    private static int getRandomIntColor() {

        int[] rgb = getRandomRgb();

        int color = 0;

        for (int c : rgb) {

            color = color << 8;

            color = color | c;

        }

        return color;

    }

    private static int[] getRandomRgb() {

        int[] rgb = new int[3];

        for (int i = 0; i < 3; i++) {

            rgb[i] = random.nextInt(255);

        }

        return rgb;

    }

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

{

        shearX(g, w1, h1, color);

        shearY(g, w1, h1, color);

    }

    private static void shearX(Graphics g, int w1, int h1, Color 

color) {

        int period = random.nextInt(2);

        boolean borderGap = true;

        int frames = 1;

        int phase = random.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);

            }

        }

    }

    private static void shearY(Graphics g, int w1, int h1, Color 

color) {

        int period = random.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);

            }

        }

    }

    public static void main(String[] args) throws IOException{

        File dir = new File("C:/Users/H__D/Desktop/");

        int w = 200, h = 80;

        String verifyCode = generateVerifyCode(4);

        File file = new File(dir, verifyCode + ".jpg");

        outputImage(w, h, file, verifyCode);

    }

}

使用图形验证码

1、使用流程

技术图片

2、服务器端生成验证码servlet

package com.servlet;

import java.io.IOException;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import com.util.VerifyCodeUtils;

public class CreateCodeServlet extends HttpServlet {

    @Override

    protected void doGet(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {

        resp.setHeader("Pragma", "No-cache");  

        resp.setHeader("Cache-Control", "no-cache");  

        resp.setDateHeader("Expires", 0);  

        resp.setContentType("image/jpeg");  

        //生成随机字串  

        String verifyCode = VerifyCodeUtils.generateVerifyCode(4);  

        //存入会话session  

        req.getSession().setAttribute("CODE", verifyCode.toLowerCase

());  

        //生成图片  

        int width = 100;//宽

        int height = 40;//高  

        VerifyCodeUtils.outputImage(width, height, 

resp.getOutputStream(), verifyCode);  

    }

    @Override

    protected void doPost(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {

        // TODO Auto-generated method stub

        doGet(req, resp);

    }

}

3、服务器端验证验证码servlet

package com.servlet;

import java.io.IOException;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import com.util.VerifyCodeUtils;

public class VerifyCodeServlet extends HttpServlet {

    @Override

    protected void doGet(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {

        String code = req.getParameter("code");

        String key = (String) req.getSession().getAttribute("CODE");

        if(code != null && code.equalsIgnoreCase(key)){

            req.getSession().removeAttribute("CODE");

            resp.getWriter().println(true);

        }else{

            resp.getWriter().println(false);

        }

    }

    @Override

    protected void doPost(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {

        // TODO Auto-generated method stub

        super.doGet(req, resp);

    }

}

4、servet的注册,web.xml文件

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="http://www.-instance" 

xmlns="http://java./xml/ns/javaee" 

xsi:schemaLocation="http://java./xml/ns/javaee 

http://java./xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" 

version="3.0">

  <display-name>test-captcha</display-name>

  <servlet>

      <servlet-name>CreateCodeServlet</servlet-name>

      <servlet-class>com.servlet.CreateCodeServlet</servlet-class>

  </servlet>

  <servlet-mapping>

      <servlet-name>CreateCodeServlet</servlet-name>

      <url-pattern>/createCode</url-pattern>

  </servlet-mapping>

   <servlet>

      <servlet-name>VerifyCodeServlet</servlet-name>

      <servlet-class>com.servlet.VerifyCodeServlet</servlet-class>

  </servlet>

  <servlet-mapping>

      <servlet-name>VerifyCodeServlet</servlet-name>

      <url-pattern>/verifyCode</url-pattern>

  </servlet-mapping>

  <welcome-file-list>

    <welcome-file>index.jsp</welcome-file>

  </welcome-file-list>

</web-app>

5、前端html文件

<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//深圳市博纳网络信息技术有限公司//DTD HTML 4.01 Transitional//EN" 

"http://生成验证码工具类

package com.util;

import java.awt.Color;

import java.awt.Font;

import java.awt.Graphics;

import java.awt.Graphics2D;

import java.awt.RenderingHints;

import java.awt.geom.AffineTransform;

import java.awt.image.BufferedImage;

import java.io.File;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.OutputStream;

import java.util.Arrays;

import java.util.Random;

import javax.imageio.ImageIO;

public class VerifyCodeUtils {

    //使用到Algerian字体,系统里没有的话需要安装字体,字体只显示大写,

去掉了1,0,i,o几个容易混淆的字符

    public static final String VERIFY_CODES = 

"23456789ABCDEFGHJKLMNPQRSTUVWXYZ";

    private static Random random = new Random();

    /**

     * 使用系统默认字符源生成验证码

     * @param verifySize    验证码长度

     * @return

     */

    public static String generateVerifyCode(int verifySize){

        return generateVerifyCode(verifySize, VERIFY_CODES);

    }

    /**

     * 使用指定源生成验证码

     * @param verifySize    验证码长度

     * @param sources   验证码字符源

     * @return

     */

    public static String generateVerifyCode(int verifySize, String 

sources){

        if(sources == null || sources.length() == 0){

            sources = VERIFY_CODES;

        }

        int codesLen = sources.length();

        Random rand = new Random(System.currentTimeMillis());

        StringBuilder verifyCode = new StringBuilder(verifySize);

        for(int i = 0; i < verifySize; i++){

            verifyCode.append(sources.charAt(rand.nextInt(codesLen-

1)));

        }

        return verifyCode.toString();

    }

    /**

     * 生成随机验证码文件,并返回验证码值

     * @param w

     * @param h

     * @param outputFile

     * @param verifySize

     * @return

     * @throws IOException

     */

    public static String outputVerifyImage(int w, int h, File 

outputFile, int verifySize) throws IOException{

        String verifyCode = generateVerifyCode(verifySize);

        outputImage(w, h, outputFile, verifyCode);

        return verifyCode;

    }

    /**

     * 输出随机验证码图片流,并返回验证码值

     * @param w

     * @param h

     * @param os

     * @param verifySize

     * @return

     * @throws IOException

     */

    public static String outputVerifyImage(int w, int h, OutputStream 

os, int verifySize) throws IOException{

        String verifyCode = generateVerifyCode(verifySize);

        outputImage(w, h, os, verifyCode);

        return verifyCode;

    }

    /**

     * 生成指定验证码图像文件

     * @param w

     * @param h

     * @param outputFile

     * @param code

     * @throws IOException

     */

    public static void outputImage(int w, int h, File outputFile, 

String code) throws IOException{

        if(outputFile == null){

            return;

        }

        File dir = outputFile.getParentFile();

        if(!dir.exists()){

            dir.mkdirs();

        }

        try{

            outputFile.createNewFile();

            FileOutputStream fos = new FileOutputStream(outputFile);

            outputImage(w, h, fos, code);

            fos.close();

        } catch(IOException e){

            throw e;

        }

    }

    /**

     * 输出指定验证码图片流

     * @param w

     * @param h

     * @param os

     * @param code

     * @throws IOException

     */

    public static void outputImage(int w, int h, OutputStream os, 

String code) throws IOException{

        int verifySize = code.length();

        BufferedImage image = new BufferedImage(w, h, 

BufferedImage.TYPE_INT_RGB);

        Random rand = new Random();

        Graphics2D g2 = image.createGraphics();

        g2.setRenderingHint

(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);

        Color[] colors = new Color[5];

        Color[] colorSpaces = new Color[] { Color.WHITE, Color.CYAN,

                Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA, 

Color.ORANGE,

                Color.PINK, Color.YELLOW };

        float[] fractions = new float[colors.length];

        for(int i = 0; i < colors.length; i++){

            colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)];

            fractions[i] = rand.nextFloat();

        }

        Arrays.sort(fractions);

        g2.setColor(Color.GRAY);// 设置边框色

        g2.fillRect(0, 0, w, h);

        Color c = getRandColor(200, 250);

        g2.setColor(c);// 设置背景色

        g2.fillRect(0, 2, w, h-4);

        //绘制干扰线

        Random random = new Random();

        g2.setColor(getRandColor(160, 200));// 设置线条的颜色

        for (int i = 0; i < 20; i++) {

            int x = random.nextInt(w - 1);

            int y = random.nextInt(h - 1);

            int xl = random.nextInt(6) + 1;

            int yl = random.nextInt(12) + 1;

            g2.drawLine(x, y, x + xl + 40, y + yl + 20);

        }

        // 添加噪点

        float yawpRate = 0.05f;// 噪声率

        int area = (int) (yawpRate * w * h);

        for (int i = 0; i < area; i++) {

            int x = random.nextInt(w);

            int y = random.nextInt(h);

            int rgb = getRandomIntColor();

            image.setRGB(x, y, rgb);

        }

        shear(g2, w, h, c);// 使图片扭曲

        g2.setColor(getRandColor(100, 160));

        int fontSize = h-4;

        Font font = new Font("Algerian", Font.ITALIC, fontSize);

        g2.setFont(font);

        char[] chars = code.toCharArray();

        for(int i = 0; i < verifySize; i++){

            AffineTransform affine = new AffineTransform();

            affine.setToRotation(Math.PI / 4 * rand.nextDouble() * 

(rand.nextBoolean() ? 1 : -1), (w / verifySize) * i + fontSize/2, 

h/2);

            g2.setTransform(affine);

            g2.drawChars(chars, i, 1, ((w-10) / verifySize) * i + 5, 

h/2 + fontSize/2 - 10);

        }

        g2.dispose();

        ImageIO.write(image, "png", os);

    }

    private static Color getRandColor(int fc, int bc) {

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

    }

    private static int getRandomIntColor() {

        int[] rgb = getRandomRgb();

        int color = 0;

        for (int c : rgb) {

            color = color << 8;

            color = color | c;

        }

        return color;

    }

    private static int[] getRandomRgb() {

        int[] rgb = new int[3];

        for (int i = 0; i < 3; i++) {

            rgb[i] = random.nextInt(255);

        }

        return rgb;

    }

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

{

        shearX(g, w1, h1, color);

        shearY(g, w1, h1, color);

    }

    private static void shearX(Graphics g, int w1, int h1, Color 

color) {

        int period = random.nextInt(2);

        boolean borderGap = true;

        int frames = 1;

        int phase = random.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);

            }

        }

    }

    private static void shearY(Graphics g, int w1, int h1, Color 

color) {

        int period = random.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);

            }

        }

    }

    public static void main(String[] args) throws IOException{

        File dir = new File("C:/Users/H__D/Desktop/");

        int w = 200, h = 80;

        String verifyCode = generateVerifyCode(4);

        File file = new File(dir, verifyCode + ".jpg");

        outputImage(w, h, file, verifyCode);

    }

}

使用图形验证码

1、使用流程

技术图片

2、服务器端生成验证码servlet

package com.servlet;

import java.io.IOException;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import com.util.VerifyCodeUtils;

public class CreateCodeServlet extends HttpServlet {

    @Override

    protected void doGet(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {

        resp.setHeader("Pragma", "No-cache");  

        resp.setHeader("Cache-Control", "no-cache");  

        resp.setDateHeader("Expires", 0);  

        resp.setContentType("image/jpeg");  

        //生成随机字串  

        String verifyCode = VerifyCodeUtils.generateVerifyCode(4);  

        //存入会话session  

        req.getSession().setAttribute("CODE", verifyCode.toLowerCase

());  

        //生成图片  

        int width = 100;//宽

        int height = 40;//高  

        VerifyCodeUtils.outputImage(width, height, 

resp.getOutputStream(), verifyCode);  

    }

    @Override

    protected void doPost(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {

        // TODO Auto-generated method stub

        doGet(req, resp);

    }

}

3、服务器端验证验证码servlet

package com.servlet;

import java.io.IOException;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import com.util.VerifyCodeUtils;

public class VerifyCodeServlet extends HttpServlet {

    @Override

    protected void doGet(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {

        String code = req.getParameter("code");

        String key = (String) req.getSession().getAttribute("CODE");

        if(code != null && code.equalsIgnoreCase(key)){

            req.getSession().removeAttribute("CODE");

            resp.getWriter().println(true);

        }else{

            resp.getWriter().println(false);

        }

    }

    @Override

    protected void doPost(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {

        // TODO Auto-generated method stub

        super.doGet(req, resp);

    }

}

4、servet的注册,web.xml文件

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="http://生成验证码工具类

package com.util;

import java.awt.Color;

import java.awt.Font;

import java.awt.Graphics;

import java.awt.Graphics2D;

import java.awt.RenderingHints;

import java.awt.geom.AffineTransform;

import java.awt.image.BufferedImage;

import java.io.File;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.OutputStream;

import java.util.Arrays;

import java.util.Random;

import javax.imageio.ImageIO;

public class VerifyCodeUtils {

    //使用到Algerian字体,系统里没有的话需要安装字体,字体只显示大写,

去掉了1,0,i,o几个容易混淆的字符

    public static final String VERIFY_CODES = 

"23456789ABCDEFGHJKLMNPQRSTUVWXYZ";

    private static Random random = new Random();

    /**

     * 使用系统默认字符源生成验证码

     * @param verifySize    验证码长度

     * @return

     */

    public static String generateVerifyCode(int verifySize){

        return generateVerifyCode(verifySize, VERIFY_CODES);

    }

    /**

     * 使用指定源生成验证码

     * @param verifySize    验证码长度

     * @param sources   验证码字符源

     * @return

     */

    public static String generateVerifyCode(int verifySize, String 

sources){

        if(sources == null || sources.length() == 0){

            sources = VERIFY_CODES;

        }

        int codesLen = sources.length();

        Random rand = new Random(System.currentTimeMillis());

        StringBuilder verifyCode = new StringBuilder(verifySize);

        for(int i = 0; i < verifySize; i++){

            verifyCode.append(sources.charAt(rand.nextInt(codesLen-

1)));

        }

        return verifyCode.toString();

    }

    /**

     * 生成随机验证码文件,并返回验证码值

     * @param w

     * @param h

     * @param outputFile

     * @param verifySize

     * @return

     * @throws IOException

     */

    public static String outputVerifyImage(int w, int h, File 

outputFile, int verifySize) throws IOException{

        String verifyCode = generateVerifyCode(verifySize);

        outputImage(w, h, outputFile, verifyCode);

        return verifyCode;

    }

    /**

     * 输出随机验证码图片流,并返回验证码值

     * @param w

     * @param h

     * @param os

     * @param verifySize

     * @return

     * @throws IOException

     */

    public static String outputVerifyImage(int w, int h, OutputStream 

os, int verifySize) throws IOException{

        String verifyCode = generateVerifyCode(verifySize);

        outputImage(w, h, os, verifyCode);

        return verifyCode;

    }

    /**

     * 生成指定验证码图像文件

     * @param w

     * @param h

     * @param outputFile

     * @param code

     * @throws IOException

     */

    public static void outputImage(int w, int h, File outputFile, 

String code) throws IOException{

        if(outputFile == null){

            return;

        }

        File dir = outputFile.getParentFile();

        if(!dir.exists()){

            dir.mkdirs();

        }

        try{

            outputFile.createNewFile();

            FileOutputStream fos = new FileOutputStream(outputFile);

            outputImage(w, h, fos, code);

            fos.close();

        } catch(IOException e){

            throw e;

        }

    }

    /**

     * 输出指定验证码图片流

     * @param w

     * @param h

     * @param os

     * @param code

     * @throws IOException

     */

    public static void outputImage(int w, int h, OutputStream os, 

String code) throws IOException{

        int verifySize = code.length();

        BufferedImage image = new BufferedImage(w, h, 

BufferedImage.TYPE_INT_RGB);

        Random rand = new Random();

        Graphics2D g2 = image.createGraphics();

        g2.setRenderingHint

(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);

        Color[] colors = new Color[5];

        Color[] colorSpaces = new Color[] { Color.WHITE, Color.CYAN,

                Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA, 

Color.ORANGE,

                Color.PINK, Color.YELLOW };

        float[] fractions = new float[colors.length];

        for(int i = 0; i < colors.length; i++){

            colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)];

            fractions[i] = rand.nextFloat();

        }

        Arrays.sort(fractions);

        g2.setColor(Color.GRAY);// 设置边框色

        g2.fillRect(0, 0, w, h);

        Color c = getRandColor(200, 250);

        g2.setColor(c);// 设置背景色

        g2.fillRect(0, 2, w, h-4);

        //绘制干扰线

        Random random = new Random();

        g2.setColor(getRandColor(160, 200));// 设置线条的颜色

        for (int i = 0; i < 20; i++) {

            int x = random.nextInt(w - 1);

            int y = random.nextInt(h - 1);

            int xl = random.nextInt(6) + 1;

            int yl = random.nextInt(12) + 1;

            g2.drawLine(x, y, x + xl + 40, y + yl + 20);

        }

        // 添加噪点

        float yawpRate = 0.05f;// 噪声率

        int area = (int) (yawpRate * w * h);

        for (int i = 0; i < area; i++) {

            int x = random.nextInt(w);

            int y = random.nextInt(h);

            int rgb = getRandomIntColor();

            image.setRGB(x, y, rgb);

        }

        shear(g2, w, h, c);// 使图片扭曲

        g2.setColor(getRandColor(100, 160));

        int fontSize = h-4;

        Font font = new Font("Algerian", Font.ITALIC, fontSize);

        g2.setFont(font);

        char[] chars = code.toCharArray();

        for(int i = 0; i < verifySize; i++){

            AffineTransform affine = new AffineTransform();

            affine.setToRotation(Math.PI / 4 * rand.nextDouble() * 

(rand.nextBoolean() ? 1 : -1), (w / verifySize) * i + fontSize/2, 

h/2);

            g2.setTransform(affine);

            g2.drawChars(chars, i, 1, ((w-10) / verifySize) * i + 5, 

h/2 + fontSize/2 - 10);

        }

        g2.dispose();

        ImageIO.write(image, "png", os);

    }

    private static Color getRandColor(int fc, int bc) {

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

    }

    private static int getRandomIntColor() {

        int[] rgb = getRandomRgb();

        int color = 0;

        for (int c : rgb) {

            color = color << 8;

            color = color | c;

        }

        return color;

    }

    private static int[] getRandomRgb() {

        int[] rgb = new int[3];

        for (int i = 0; i < 3; i++) {

            rgb[i] = random.nextInt(255);

        }

        return rgb;

    }

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

{

        shearX(g, w1, h1, color);

        shearY(g, w1, h1, color);

    }

    private static void shearX(Graphics g, int w1, int h1, Color 

color) {

        int period = random.nextInt(2);

        boolean borderGap = true;

        int frames = 1;

        int phase = random.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);

            }

        }

    }

    private static void shearY(Graphics g, int w1, int h1, Color 

color) {

        int period = random.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);

            }

        }

    }

    public static void main(String[] args) throws IOException{

        File dir = new File("C:/Users/H__D/Desktop/");

        int w = 200, h = 80;

        String verifyCode = generateVerifyCode(4);

        File file = new File(dir, verifyCode + ".jpg");

        outputImage(w, h, file, verifyCode);

    }

}

使用图形验证码

1、使用流程

技术图片

2、服务器端生成验证码servlet

package com.servlet;

import java.io.IOException;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import com.util.VerifyCodeUtils;

public class CreateCodeServlet extends HttpServlet {

    @Override

    protected void doGet(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {

        resp.setHeader("Pragma", "No-cache");  

        resp.setHeader("Cache-Control", "no-cache");  

        resp.setDateHeader("Expires", 0);  

        resp.setContentType("image/jpeg");  

        //生成随机字串  

        String verifyCode = VerifyCodeUtils.generateVerifyCode(4);  

        //存入会话session  

        req.getSession().setAttribute("CODE", verifyCode.toLowerCase

());  

        //生成图片  

        int width = 100;//宽

        int height = 40;//高  

        VerifyCodeUtils.outputImage(width, height, 

resp.getOutputStream(), verifyCode);  

    }

    @Override

    protected void doPost(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {

        // TODO Auto-generated method stub

        doGet(req, resp);

    }

}

3、服务器端验证验证码servlet

package com.servlet;

import java.io.IOException;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import com.util.VerifyCodeUtils;

public class VerifyCodeServlet extends HttpServlet {

    @Override

    protected void doGet(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {

        String code = req.getParameter("code");

        String key = (String) req.getSession().getAttribute("CODE");

        if(code != null && code.equalsIgnoreCase(key)){

            req.getSession().removeAttribute("CODE");

            resp.getWriter().println(true);

        }else{

            resp.getWriter().println(false);

        }

    }

    @Override

    protected void doPost(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {

        // TODO Auto-generated method stub

        super.doGet(req, resp);

    }

}

4、servet的注册,web.xml文件

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="http://www.-instance" 

xmlns="http://java./xml/ns/javaee" 

xsi:schemaLocation="http://java./xml/ns/javaee 

http://java./xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" 

version="3.0">

  <display-name>test-captcha</display-name>

  <servlet>

      <servlet-name>CreateCodeServlet</servlet-name>

      <servlet-class>com.servlet.CreateCodeServlet</servlet-class>

  </servlet>

  <servlet-mapping>

      <servlet-name>CreateCodeServlet</servlet-name>

      <url-pattern>/createCode</url-pattern>

  </servlet-mapping>

   <servlet>

      <servlet-name>VerifyCodeServlet</servlet-name>

      <servlet-class>com.servlet.VerifyCodeServlet</servlet-class>

  </servlet>

  <servlet-mapping>

      <servlet-name>VerifyCodeServlet</servlet-name>

      <url-pattern>/verifyCode</url-pattern>

  </servlet-mapping>

  <welcome-file-list>

    <welcome-file>index.jsp</welcome-file>

  </welcome-file-list>

</web-app>

5、前端html文件

<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 

"http://www.www.">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Insert title here</title>

</head>

<body>

    <h2>测试验证码:</h2>

    请输入验证码:<input type="text" name="code" /><img id="codeimg" 

src="${pageContext.request.contextPath }/createCode" 

onclick="changeImg()"><a href="javascript:void(0);" 

onclick="changeImg()">看不清,换一张</a>

    <button onclick="submit()">提交</button>

    <script type="text/javascript">

        //改变验证码事件

        function changeImg(){

            var img = document.getElementById(‘codeimg‘);

            img.src = "${pageContext.request.contextPath 

}/createCode?x=" + Math.floor(Math.random()*100)

        }

        //提交验证并验证验证码

        function submit(){

            var input = document.getElementsByTagName(‘input‘)[0];

            //ajax提交

            var xhr = new XMLHttpRequest();

            xhr.onreadystatechange = function(){

                if(xhr.readyState == 4 && xhr.status == 200) {

                    alert(xhr.responseText);

                }  

            }

            xhr.open(‘get‘,‘${pageContext.request.contextPath 

}/verifyCode?code=‘ + input.value);

            xhr.send(null);

        }

    </script>

</body>

</html>-instance" xmlns="http://java./xml/ns/javaee" 

xsi:schemaLocation="http://java./xml/ns/javaee 

http://java./xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" 

version="3.0">

  <display-name>test-captcha</display-name>

  <servlet>

      <servlet-name>CreateCodeServlet</servlet-name>

      <servlet-class>com.servlet.CreateCodeServlet</servlet-class>

  </servlet>

  <servlet-mapping>

      <servlet-name>CreateCodeServlet</servlet-name>

      <url-pattern>/createCode</url-pattern>

  </servlet-mapping>

   <servlet>

      <servlet-name>VerifyCodeServlet</servlet-name>

      <servlet-class>com.servlet.VerifyCodeServlet</servlet-class>

  </servlet>

  <servlet-mapping>

      <servlet-name>VerifyCodeServlet</servlet-name>

      <url-pattern>/verifyCode</url-pattern>

  </servlet-mapping>

  <welcome-file-list>

    <welcome-file>index.jsp</welcome-file>

  </welcome-file-list>

</web-app>

5、前端html文件

<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//深圳市博纳网络信息技术有限公司//DTD HTML 

4.01 Transitional//EN" "http://生成验证码工具类

package com.util;

import java.awt.Color;

import java.awt.Font;

import java.awt.Graphics;

import java.awt.Graphics2D;

import java.awt.RenderingHints;

import java.awt.geom.AffineTransform;

import java.awt.image.BufferedImage;

import java.io.File;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.OutputStream;

import java.util.Arrays;

import java.util.Random;

import javax.imageio.ImageIO;

public class VerifyCodeUtils {

    //使用到Algerian字体,系统里没有的话需要安装字体,字体只显示大写,

去掉了1,0,i,o几个容易混淆的字符

    public static final String VERIFY_CODES = 

"23456789ABCDEFGHJKLMNPQRSTUVWXYZ";

    private static Random random = new Random();

    /**

     * 使用系统默认字符源生成验证码

     * @param verifySize    验证码长度

     * @return

     */

    public static String generateVerifyCode(int verifySize){

        return generateVerifyCode(verifySize, VERIFY_CODES);

    }

    /**

     * 使用指定源生成验证码

     * @param verifySize    验证码长度

     * @param sources   验证码字符源

     * @return

     */

    public static String generateVerifyCode(int verifySize, String 

sources){

        if(sources == null || sources.length() == 0){

            sources = VERIFY_CODES;

        }

        int codesLen = sources.length();

        Random rand = new Random(System.currentTimeMillis());

        StringBuilder verifyCode = new StringBuilder(verifySize);

        for(int i = 0; i < verifySize; i++){

            verifyCode.append(sources.charAt(rand.nextInt(codesLen-

1)));

        }

        return verifyCode.toString();

    }

    /**

     * 生成随机验证码文件,并返回验证码值

     * @param w

     * @param h

     * @param outputFile

     * @param verifySize

     * @return

     * @throws IOException

     */

    public static String outputVerifyImage(int w, int h, File 

outputFile, int verifySize) throws IOException{

        String verifyCode = generateVerifyCode(verifySize);

        outputImage(w, h, outputFile, verifyCode);

        return verifyCode;

    }

    /**

     * 输出随机验证码图片流,并返回验证码值

     * @param w

     * @param h

     * @param os

     * @param verifySize

     * @return

     * @throws IOException

     */

    public static String outputVerifyImage(int w, int h, OutputStream 

os, int verifySize) throws IOException{

        String verifyCode = generateVerifyCode(verifySize);

        outputImage(w, h, os, verifyCode);

        return verifyCode;

    }

    /**

     * 生成指定验证码图像文件

     * @param w

     * @param h

     * @param outputFile

     * @param code

     * @throws IOException

     */

    public static void outputImage(int w, int h, File outputFile, 

String code) throws IOException{

        if(outputFile == null){

            return;

        }

        File dir = outputFile.getParentFile();

        if(!dir.exists()){

            dir.mkdirs();

        }

        try{

            outputFile.createNewFile();

            FileOutputStream fos = new FileOutputStream(outputFile);

            outputImage(w, h, fos, code);

            fos.close();

        } catch(IOException e){

            throw e;

        }

    }

    /**

     * 输出指定验证码图片流

     * @param w

     * @param h

     * @param os

     * @param code

     * @throws IOException

     */

    public static void outputImage(int w, int h, OutputStream os, 

String code) throws IOException{

        int verifySize = code.length();

        BufferedImage image = new BufferedImage(w, h, 

BufferedImage.TYPE_INT_RGB);

        Random rand = new Random();

        Graphics2D g2 = image.createGraphics();

        g2.setRenderingHint

(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);

        Color[] colors = new Color[5];

        Color[] colorSpaces = new Color[] { Color.WHITE, Color.CYAN,

                Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA, 

Color.ORANGE,

                Color.PINK, Color.YELLOW };

        float[] fractions = new float[colors.length];

        for(int i = 0; i < colors.length; i++){

            colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)];

            fractions[i] = rand.nextFloat();

        }

        Arrays.sort(fractions);

        g2.setColor(Color.GRAY);// 设置边框色

        g2.fillRect(0, 0, w, h);

        Color c = getRandColor(200, 250);

        g2.setColor(c);// 设置背景色

        g2.fillRect(0, 2, w, h-4);

        //绘制干扰线

        Random random = new Random();

        g2.setColor(getRandColor(160, 200));// 设置线条的颜色

        for (int i = 0; i < 20; i++) {

            int x = random.nextInt(w - 1);

            int y = random.nextInt(h - 1);

            int xl = random.nextInt(6) + 1;

            int yl = random.nextInt(12) + 1;

            g2.drawLine(x, y, x + xl + 40, y + yl + 20);

        }

        // 添加噪点

        float yawpRate = 0.05f;// 噪声率

        int area = (int) (yawpRate * w * h);

        for (int i = 0; i < area; i++) {

            int x = random.nextInt(w);

            int y = random.nextInt(h);

            int rgb = getRandomIntColor();

            image.setRGB(x, y, rgb);

        }

        shear(g2, w, h, c);// 使图片扭曲

        g2.setColor(getRandColor(100, 160));

        int fontSize = h-4;

        Font font = new Font("Algerian", Font.ITALIC, fontSize);

        g2.setFont(font);

        char[] chars = code.toCharArray();

        for(int i = 0; i < verifySize; i++){

            AffineTransform affine = new AffineTransform();

            affine.setToRotation(Math.PI / 4 * rand.nextDouble() * 

(rand.nextBoolean() ? 1 : -1), (w / verifySize) * i + fontSize/2, 

h/2);

            g2.setTransform(affine);

            g2.drawChars(chars, i, 1, ((w-10) / verifySize) * i + 5, 

h/2 + fontSize/2 - 10);

        }

        g2.dispose();

        ImageIO.write(image, "png", os);

    }

    private static Color getRandColor(int fc, int bc) {

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

    }

    private static int getRandomIntColor() {

        int[] rgb = getRandomRgb();

        int color = 0;

        for (int c : rgb) {

            color = color << 8;

            color = color | c;

        }

        return color;

    }

    private static int[] getRandomRgb() {

        int[] rgb = new int[3];

        for (int i = 0; i < 3; i++) {

            rgb[i] = random.nextInt(255);

        }

        return rgb;

    }

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

{

        shearX(g, w1, h1, color);

        shearY(g, w1, h1, color);

    }

    private static void shearX(Graphics g, int w1, int h1, Color 

color) {

        int period = random.nextInt(2);

        boolean borderGap = true;

        int frames = 1;

        int phase = random.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);

            }

        }

    }

    private static void shearY(Graphics g, int w1, int h1, Color 

color) {

        int period = random.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);

            }

        }

    }

    public static void main(String[] args) throws IOException{

        File dir = new File("C:/Users/H__D/Desktop/");

        int w = 200, h = 80;

        String verifyCode = generateVerifyCode(4);

        File file = new File(dir, verifyCode + ".jpg");

        outputImage(w, h, file, verifyCode);

    }

}

使用图形验证码

1、使用流程

技术图片

2、服务器端生成验证码servlet

package com.servlet;

import java.io.IOException;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import com.util.VerifyCodeUtils;

public class CreateCodeServlet extends HttpServlet {

    @Override

    protected void doGet(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {

        resp.setHeader("Pragma", "No-cache");  

        resp.setHeader("Cache-Control", "no-cache");  

        resp.setDateHeader("Expires", 0);  

        resp.setContentType("image/jpeg");  

        //生成随机字串  

        String verifyCode = VerifyCodeUtils.generateVerifyCode(4);  

        //存入会话session  

        req.getSession().setAttribute("CODE", verifyCode.toLowerCase

());  

        //生成图片  

        int width = 100;//宽

        int height = 40;//高  

        VerifyCodeUtils.outputImage(width, height, 

resp.getOutputStream(), verifyCode);  

    }

    @Override

    protected void doPost(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {

        // TODO Auto-generated method stub

        doGet(req, resp);

    }

}

3、服务器端验证验证码servlet

package com.servlet;

import java.io.IOException;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import com.util.VerifyCodeUtils;

public class VerifyCodeServlet extends HttpServlet {

    @Override

    protected void doGet(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {

        String code = req.getParameter("code");

        String key = (String) req.getSession().getAttribute("CODE");

        if(code != null && code.equalsIgnoreCase(key)){

            req.getSession().removeAttribute("CODE");

            resp.getWriter().println(true);

        }else{

            resp.getWriter().println(false);

        }

    }

    @Override

    protected void doPost(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {

        // TODO Auto-generated method stub

        super.doGet(req, resp);

    }

}

4、servet的注册,web.xml文件

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="http://www.-instance" 

xmlns="http://java./xml/ns/javaee" 

xsi:schemaLocation="http://java./xml/ns/javaee 

http://java./xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" 

version="3.0">

  <display-name>test-captcha</display-name>

  <servlet>

      <servlet-name>CreateCodeServlet</servlet-name>

      <servlet-class>com.servlet.CreateCodeServlet</servlet-class>

  </servlet>

  <servlet-mapping>

      <servlet-name>CreateCodeServlet</servlet-name>

      <url-pattern>/createCode</url-pattern>

  </servlet-mapping>

   <servlet>

      <servlet-name>VerifyCodeServlet</servlet-name>

      <servlet-class>com.servlet.VerifyCodeServlet</servlet-class>

  </servlet>

  <servlet-mapping>

      <servlet-name>VerifyCodeServlet</servlet-name>

      <url-pattern>/verifyCode</url-pattern>

  </servlet-mapping>

  <welcome-file-list>

    <welcome-file>index.jsp</welcome-file>

  </welcome-file-list>

</web-app>

5、前端html文件

<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//深圳市博纳网络信息技术有限公司//DTD HTML 

4.01 Transitional//EN" "http://www.">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Insert title here</title>

</head>

<body>

    <h2>测试验证码:</h2>

    请输入验证码:<input type="text" name="code" /><img id="codeimg" 

src="${pageContext.request.contextPath }/createCode" 

onclick="changeImg()"><a href="javascript:void(0);" 

onclick="changeImg()">看不清,换一张</a>

    <button onclick="submit()">提交</button>

    <script type="text/javascript">

        //改变验证码事件

        function changeImg(){

            var img = document.getElementById(‘codeimg‘);

            img.src = "${pageContext.request.contextPath 

}/createCode?x=" + Math.floor(Math.random()*100)

        }

        //提交验证并验证验证码

        function submit(){

            var input = document.getElementsByTagName(‘input‘)[0];

            //ajax提交

            var xhr = new XMLHttpRequest();

            xhr.onreadystatechange = function(){

                if(xhr.readyState == 4 && xhr.status == 200) {

                    alert(xhr.responseText);

                }  

            }

            xhr.open(‘get‘,‘${pageContext.request.contextPath 

}/verifyCode?code=‘ + input.value);

            xhr.send(null);

        }

    </script>

</body>

</html>">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Insert title here</title>

</head>

<body>

    <h2>测试验证码:</h2>

    请输入验证码:<input type="text" name="code" /><img id="codeimg" 

src="${pageContext.request.contextPath }/createCode" 

onclick="changeImg()"><a href="javascript:void(0);" 

onclick="changeImg()">看不清,换一张</a>

    <button onclick="submit()">提交</button>

    <script type="text/javascript">

        //改变验证码事件

        function changeImg(){

            var img = document.getElementById(‘codeimg‘);

            img.src = "${pageContext.request.contextPath 

}/createCode?x=" + Math.floor(Math.random()*100)

        }

        //提交验证并验证验证码

        function submit(){

            var input = document.getElementsByTagName(‘input‘)[0];

            //ajax提交

            var xhr = new XMLHttpRequest();

            xhr.onreadystatechange = function(){

                if(xhr.readyState == 4 && xhr.status == 200) {

                    alert(xhr.responseText);

                }  

            }

            xhr.open(‘get‘,‘${pageContext.request.contextPath 

}/verifyCode?code=‘ + input.value);

            xhr.send(null);

        }

    </script>

</body>

</html>">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Insert title here</title>

</head>

<body>

    <h2>测试验证码:</h2>

    请输入验证码:<input type="text" name="code" /><img id="codeimg" 

src="${pageContext.request.contextPath }/createCode" 

onclick="changeImg()"><a href="javascript:void(0);" 

onclick="changeImg()">看不清,换一张</a>

    <button onclick="submit()">提交</button>

    <script type="text/javascript">

        //改变验证码事件

        function changeImg(){

            var img = document.getElementById(‘codeimg‘);

            img.src = "${pageContext.request.contextPath 

}/createCode?x=" + Math.floor(Math.random()*100)

        }

        //提交验证并验证验证码

        function submit(){

            var input = document.getElementsByTagName(‘input‘)[0];

            //ajax提交

            var xhr = new XMLHttpRequest();

            xhr.onreadystatechange = function(){

                if(xhr.readyState == 4 && xhr.status == 200) {

                    alert(xhr.responseText);

                }  

            }

            xhr.open(‘get‘,‘${pageContext.request.contextPath 

}/verifyCode?code=‘ + input.value);

            xhr.send(null);

        }

    </script>

</body>

</html>">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Insert title here</title>

</head>

<body>

    <h2>测试验证码:</h2>

    请输入验证码:<input type="text" name="code" /><img id="codeimg" 

src="${pageContext.request.contextPath }/createCode" 

onclick="changeImg()"><a href="javascript:void(0);" 

onclick="changeImg()">看不清,换一张</a>

    <button onclick="submit()">提交</button>

    <script type="text/javascript">

        //改变验证码事件

        function changeImg(){

            var img = document.getElementById(‘codeimg‘);

            img.src = "${pageContext.request.contextPath 

}/createCode?x=" + Math.floor(Math.random()*100)

        }

        //提交验证并验证验证码

        function submit(){

            var input = document.getElementsByTagName(‘input‘)[0];

            //ajax提交

            var xhr = new XMLHttpRequest();

            xhr.onreadystatechange = function(){

                if(xhr.readyState == 4 && xhr.status == 200) {

                    alert(xhr.responseText);

                }  

            }

            xhr.open(‘get‘,‘${pageContext.request.contextPath 

}/verifyCode?code=‘ + input.value);

            xhr.send(null);

        }

    </script>

</body>

</html>-instance" xmlns="http://java./xml/ns/javaee" 

xsi:schemaLocation="http://java./xml/ns/javaee 

http://java./xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" 

version="3.0">

  <display-name>test-captcha</display-name>

  <servlet>

      <servlet-name>CreateCodeServlet</servlet-name>

      <servlet-class>com.servlet.CreateCodeServlet</servlet-class>

  </servlet>

  <servlet-mapping>

      <servlet-name>CreateCodeServlet</servlet-name>

      <url-pattern>/createCode</url-pattern>

  </servlet-mapping>

   <servlet>

      <servlet-name>VerifyCodeServlet</servlet-name>

      <servlet-class>com.servlet.VerifyCodeServlet</servlet-class>

  </servlet>

  <servlet-mapping>

      <servlet-name>VerifyCodeServlet</servlet-name>

      <url-pattern>/verifyCode</url-pattern>

  </servlet-mapping>

  <welcome-file-list>

    <welcome-file>index.jsp</welcome-file>

  </welcome-file-list>

</web-app>

5、前端html文件

<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//深圳市博纳网络信息技术有限公司//DTD HTML 

4.01 Transitional//EN" "http://www.">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Insert title here</title>

</head>

<body>

    <h2>测试验证码:</h2>

    请输入验证码:<input type="text" name="code" /><img id="codeimg" 

src="${pageContext.request.contextPath }/createCode" 

onclick="changeImg()"><a href="javascript:void(0);" 

onclick="changeImg()">看不清,换一张</a>

    <button onclick="submit()">提交</button>

    <script type="text/javascript">

        //改变验证码事件

        function changeImg(){

            var img = document.getElementById(‘codeimg‘);

            img.src = "${pageContext.request.contextPath 

}/createCode?x=" + Math.floor(Math.random()*100)

        }

        //提交验证并验证验证码

        function submit(){

            var input = document.getElementsByTagName(‘input‘)[0];

            //ajax提交

            var xhr = new XMLHttpRequest();

            xhr.onreadystatechange = function(){

                if(xhr.readyState == 4 && xhr.status == 200) {

                    alert(xhr.responseText);

                }  

            }

            xhr.open(‘get‘,‘${pageContext.request.contextPath 

}/verifyCode?code=‘ + input.value);

            xhr.send(null);

        }

    </script>

</body>

</html>

生成验证码工具类
package com.util;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Random;
 
import javax.imageio.ImageIO;


public class VerifyCodeUtils {
     
    //使用到Algerian字体,系统里没有的话需要安装字体,字体只显示大写,

去掉了1,0,i,o几个容易混淆的字符
    public static final String VERIFY_CODES = 

"23456789ABCDEFGHJKLMNPQRSTUVWXYZ";
    private static Random random = new Random();
 
 
    /**
     * 使用系统默认字符源生成验证码
     * @param verifySize    验证码长度
     * @return
     */
    public static String generateVerifyCode(int verifySize){
        return generateVerifyCode(verifySize, VERIFY_CODES);
    }
    
    /**
     * 使用指定源生成验证码
     * @param verifySize    验证码长度
     * @param sources   验证码字符源
     * @return
     */
    public static String generateVerifyCode(int verifySize, String 

sources){
        if(sources == null || sources.length() == 0){
            sources = VERIFY_CODES;
        }
        int codesLen = sources.length();
        Random rand = new Random(System.currentTimeMillis());
        StringBuilder verifyCode = new StringBuilder(verifySize);
        for(int i = 0; i < verifySize; i++){
            verifyCode.append(sources.charAt(rand.nextInt(codesLen-

1)));
        }
        return verifyCode.toString();
    }
     
    /**
     * 生成随机验证码文件,并返回验证码值
     * @param w
     * @param h
     * @param outputFile
     * @param verifySize
     * @return
     * @throws IOException
     */
    public static String outputVerifyImage(int w, int h, File 

outputFile, int verifySize) throws IOException{
        String verifyCode = generateVerifyCode(verifySize);
        outputImage(w, h, outputFile, verifyCode);
        return verifyCode;
    }
     
    /**
     * 输出随机验证码图片流,并返回验证码值
     * @param w
     * @param h
     * @param os
     * @param verifySize
     * @return
     * @throws IOException
     */
    public static String outputVerifyImage(int w, int h, OutputStream 

os, int verifySize) throws IOException{
        String verifyCode = generateVerifyCode(verifySize);
        outputImage(w, h, os, verifyCode);
        return verifyCode;
    }
     
    /**
     * 生成指定验证码图像文件
     * @param w
     * @param h
     * @param outputFile
     * @param code
     * @throws IOException
     */
    public static void outputImage(int w, int h, File outputFile, 

String code) throws IOException{
        if(outputFile == null){
            return;
        }
        File dir = outputFile.getParentFile();
        if(!dir.exists()){
            dir.mkdirs();
        }
        try{
            outputFile.createNewFile();
            FileOutputStream fos = new FileOutputStream(outputFile);
            outputImage(w, h, fos, code);
            fos.close();
        } catch(IOException e){
            throw e;
        }
    }
     
    /**
     * 输出指定验证码图片流
     * @param w
     * @param h
     * @param os
     * @param code
     * @throws IOException
     */
    public static void outputImage(int w, int h, OutputStream os, 

String code) throws IOException{
        int verifySize = code.length();
        BufferedImage image = new BufferedImage(w, h, 

BufferedImage.TYPE_INT_RGB);
        Random rand = new Random();
        Graphics2D g2 = image.createGraphics();
        g2.setRenderingHint

(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
        Color[] colors = new Color[5];
        Color[] colorSpaces = new Color[] { Color.WHITE, Color.CYAN,
                Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA, 

Color.ORANGE,
                Color.PINK, Color.YELLOW };
        float[] fractions = new float[colors.length];
        for(int i = 0; i < colors.length; i++){
            colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)];
            fractions[i] = rand.nextFloat();
        }
        Arrays.sort(fractions);
         
        g2.setColor(Color.GRAY);// 设置边框色
        g2.fillRect(0, 0, w, h);
         
        Color c = getRandColor(200, 250);
        g2.setColor(c);// 设置背景色
        g2.fillRect(0, 2, w, h-4);
         
        //绘制干扰线
        Random random = new Random();
        g2.setColor(getRandColor(160, 200));// 设置线条的颜色
        for (int i = 0; i < 20; i++) {
            int x = random.nextInt(w - 1);
            int y = random.nextInt(h - 1);
            int xl = random.nextInt(6) + 1;
            int yl = random.nextInt(12) + 1;
            g2.drawLine(x, y, x + xl + 40, y + yl + 20);
        }
         
        // 添加噪点
        float yawpRate = 0.05f;// 噪声率
        int area = (int) (yawpRate * w * h);
        for (int i = 0; i < area; i++) {
            int x = random.nextInt(w);
            int y = random.nextInt(h);
            int rgb = getRandomIntColor();
            image.setRGB(x, y, rgb);
        }
         
        shear(g2, w, h, c);// 使图片扭曲
 
        g2.setColor(getRandColor(100, 160));
        int fontSize = h-4;
        Font font = new Font("Algerian", Font.ITALIC, fontSize);
        g2.setFont(font);
        char[] chars = code.toCharArray();
        for(int i = 0; i < verifySize; i++){
            AffineTransform affine = new AffineTransform();
            affine.setToRotation(Math.PI / 4 * rand.nextDouble() * 

(rand.nextBoolean() ? 1 : -1), (w / verifySize) * i + fontSize/2, 

h/2);
            g2.setTransform(affine);
            g2.drawChars(chars, i, 1, ((w-10) / verifySize) * i + 5, 

h/2 + fontSize/2 - 10);
        }
         
        g2.dispose();
        ImageIO.write(image, "png", os);
    }
     
    private static Color getRandColor(int fc, int bc) {
        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);
    }
     
    private static int getRandomIntColor() {
        int[] rgb = getRandomRgb();
        int color = 0;
        for (int c : rgb) {
            color = color << 8;
            color = color | c;
        }
        return color;
    }
     
    private static int[] getRandomRgb() {
        int[] rgb = new int[3];
        for (int i = 0; i < 3; i++) {
            rgb[i] = random.nextInt(255);
        }
        return rgb;
    }
 
    private static void shear(Graphics g, int w1, int h1, Color color) 

{
        shearX(g, w1, h1, color);
        shearY(g, w1, h1, color);
    }
     
    private static void shearX(Graphics g, int w1, int h1, Color 

color) {
 
        int period = random.nextInt(2);
 
        boolean borderGap = true;
        int frames = 1;
        int phase = random.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);
            }
        }
 
    }
 
    private static void shearY(Graphics g, int w1, int h1, Color 

color) {
 
        int period = random.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);
            }
 
        }
    }
    public static void main(String[] args) throws IOException{
        File dir = new File("C:/Users/H__D/Desktop/");
        int w = 200, h = 80;
        String verifyCode = generateVerifyCode(4);
        File file = new File(dir, verifyCode + ".jpg");
        outputImage(w, h, file, verifyCode);
    }
}
 

使用图形验证码
 

1、使用流程

 

技术图片

 

2、服务器端生成验证码servlet

package com.servlet;

import java.io.IOException;

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

import com.util.VerifyCodeUtils;


public class CreateCodeServlet extends HttpServlet {
    
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {
        resp.setHeader("Pragma", "No-cache");  
        resp.setHeader("Cache-Control", "no-cache");  
        resp.setDateHeader("Expires", 0);  
        resp.setContentType("image/jpeg");  
          
        //生成随机字串  
        String verifyCode = VerifyCodeUtils.generateVerifyCode(4);  
        //存入会话session  
        req.getSession().setAttribute("CODE", verifyCode.toLowerCase

());  
        
        //生成图片  
        int width = 100;//宽
        int height = 40;//高  
        VerifyCodeUtils.outputImage(width, height, 

resp.getOutputStream(), verifyCode);  
        
    }
    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {
        // TODO Auto-generated method stub
        doGet(req, resp);
    }
}
3、服务器端验证验证码servlet

 

package com.servlet;

import java.io.IOException;

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

import com.util.VerifyCodeUtils;


public class VerifyCodeServlet extends HttpServlet {
    
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {
        
        String code = req.getParameter("code");
        String key = (String) req.getSession().getAttribute("CODE");
        if(code != null && code.equalsIgnoreCase(key)){
            req.getSession().removeAttribute("CODE");
            resp.getWriter().println(true);
        }else{
            resp.getWriter().println(false);
        }
    }
    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {
        // TODO Auto-generated method stub
        super.doGet(req, resp);
    }
}
4、servet的注册,web.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://生成验证码工具类
package com.util;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Random;
 
import javax.imageio.ImageIO;


public class VerifyCodeUtils {
     
    //使用到Algerian字体,系统里没有的话需要安装字体,字体只显示大写,

去掉了1,0,i,o几个容易混淆的字符
    public static final String VERIFY_CODES = 

"23456789ABCDEFGHJKLMNPQRSTUVWXYZ";
    private static Random random = new Random();
 
 
    /**
     * 使用系统默认字符源生成验证码
     * @param verifySize    验证码长度
     * @return
     */
    public static String generateVerifyCode(int verifySize){
        return generateVerifyCode(verifySize, VERIFY_CODES);
    }
    
    /**
     * 使用指定源生成验证码
     * @param verifySize    验证码长度
     * @param sources   验证码字符源
     * @return
     */
    public static String generateVerifyCode(int verifySize, String 

sources){
        if(sources == null || sources.length() == 0){
            sources = VERIFY_CODES;
        }
        int codesLen = sources.length();
        Random rand = new Random(System.currentTimeMillis());
        StringBuilder verifyCode = new StringBuilder(verifySize);
        for(int i = 0; i < verifySize; i++){
            verifyCode.append(sources.charAt(rand.nextInt(codesLen-

1)));
        }
        return verifyCode.toString();
    }
     
    /**
     * 生成随机验证码文件,并返回验证码值
     * @param w
     * @param h
     * @param outputFile
     * @param verifySize
     * @return
     * @throws IOException
     */
    public static String outputVerifyImage(int w, int h, File 

outputFile, int verifySize) throws IOException{
        String verifyCode = generateVerifyCode(verifySize);
        outputImage(w, h, outputFile, verifyCode);
        return verifyCode;
    }
     
    /**
     * 输出随机验证码图片流,并返回验证码值
     * @param w
     * @param h
     * @param os
     * @param verifySize
     * @return
     * @throws IOException
     */
    public static String outputVerifyImage(int w, int h, OutputStream 

os, int verifySize) throws IOException{
        String verifyCode = generateVerifyCode(verifySize);
        outputImage(w, h, os, verifyCode);
        return verifyCode;
    }
     
    /**
     * 生成指定验证码图像文件
     * @param w
     * @param h
     * @param outputFile
     * @param code
     * @throws IOException
     */
    public static void outputImage(int w, int h, File outputFile, 

String code) throws IOException{
        if(outputFile == null){
            return;
        }
        File dir = outputFile.getParentFile();
        if(!dir.exists()){
            dir.mkdirs();
        }
        try{
            outputFile.createNewFile();
            FileOutputStream fos = new FileOutputStream(outputFile);
            outputImage(w, h, fos, code);
            fos.close();
        } catch(IOException e){
            throw e;
        }
    }
     
    /**
     * 输出指定验证码图片流
     * @param w
     * @param h
     * @param os
     * @param code
     * @throws IOException
     */
    public static void outputImage(int w, int h, OutputStream os, 

String code) throws IOException{
        int verifySize = code.length();
        BufferedImage image = new BufferedImage(w, h, 

BufferedImage.TYPE_INT_RGB);
        Random rand = new Random();
        Graphics2D g2 = image.createGraphics();
        g2.setRenderingHint

(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
        Color[] colors = new Color[5];
        Color[] colorSpaces = new Color[] { Color.WHITE, Color.CYAN,
                Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA, 

Color.ORANGE,
                Color.PINK, Color.YELLOW };
        float[] fractions = new float[colors.length];
        for(int i = 0; i < colors.length; i++){
            colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)];
            fractions[i] = rand.nextFloat();
        }
        Arrays.sort(fractions);
         
        g2.setColor(Color.GRAY);// 设置边框色
        g2.fillRect(0, 0, w, h);
         
        Color c = getRandColor(200, 250);
        g2.setColor(c);// 设置背景色
        g2.fillRect(0, 2, w, h-4);
         
        //绘制干扰线
        Random random = new Random();
        g2.setColor(getRandColor(160, 200));// 设置线条的颜色
        for (int i = 0; i < 20; i++) {
            int x = random.nextInt(w - 1);
            int y = random.nextInt(h - 1);
            int xl = random.nextInt(6) + 1;
            int yl = random.nextInt(12) + 1;
            g2.drawLine(x, y, x + xl + 40, y + yl + 20);
        }
         
        // 添加噪点
        float yawpRate = 0.05f;// 噪声率
        int area = (int) (yawpRate * w * h);
        for (int i = 0; i < area; i++) {
            int x = random.nextInt(w);
            int y = random.nextInt(h);
            int rgb = getRandomIntColor();
            image.setRGB(x, y, rgb);
        }
         
        shear(g2, w, h, c);// 使图片扭曲
 
        g2.setColor(getRandColor(100, 160));
        int fontSize = h-4;
        Font font = new Font("Algerian", Font.ITALIC, fontSize);
        g2.setFont(font);
        char[] chars = code.toCharArray();
        for(int i = 0; i < verifySize; i++){
            AffineTransform affine = new AffineTransform();
            affine.setToRotation(Math.PI / 4 * rand.nextDouble() * 

(rand.nextBoolean() ? 1 : -1), (w / verifySize) * i + fontSize/2, 

h/2);
            g2.setTransform(affine);
            g2.drawChars(chars, i, 1, ((w-10) / verifySize) * i + 5, 

h/2 + fontSize/2 - 10);
        }
         
        g2.dispose();
        ImageIO.write(image, "png", os);
    }
     
    private static Color getRandColor(int fc, int bc) {
        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);
    }
     
    private static int getRandomIntColor() {
        int[] rgb = getRandomRgb();
        int color = 0;
        for (int c : rgb) {
            color = color << 8;
            color = color | c;
        }
        return color;
    }
     
    private static int[] getRandomRgb() {
        int[] rgb = new int[3];
        for (int i = 0; i < 3; i++) {
            rgb[i] = random.nextInt(255);
        }
        return rgb;
    }
 
    private static void shear(Graphics g, int w1, int h1, Color color) 

{
        shearX(g, w1, h1, color);
        shearY(g, w1, h1, color);
    }
     
    private static void shearX(Graphics g, int w1, int h1, Color 

color) {
 
        int period = random.nextInt(2);
 
        boolean borderGap = true;
        int frames = 1;
        int phase = random.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);
            }
        }
 
    }
 
    private static void shearY(Graphics g, int w1, int h1, Color 

color) {
 
        int period = random.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);
            }
 
        }
    }
    public static void main(String[] args) throws IOException{
        File dir = new File("C:/Users/H__D/Desktop/");
        int w = 200, h = 80;
        String verifyCode = generateVerifyCode(4);
        File file = new File(dir, verifyCode + ".jpg");
        outputImage(w, h, file, verifyCode);
    }
}
 

使用图形验证码
 

1、使用流程

 

技术图片

 

2、服务器端生成验证码servlet

package com.servlet;

import java.io.IOException;

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

import com.util.VerifyCodeUtils;


public class CreateCodeServlet extends HttpServlet {
    
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {
        resp.setHeader("Pragma", "No-cache");  
        resp.setHeader("Cache-Control", "no-cache");  
        resp.setDateHeader("Expires", 0);  
        resp.setContentType("image/jpeg");  
          
        //生成随机字串  
        String verifyCode = VerifyCodeUtils.generateVerifyCode(4);  
        //存入会话session  
        req.getSession().setAttribute("CODE", verifyCode.toLowerCase

());  
        
        //生成图片  
        int width = 100;//宽
        int height = 40;//高  
        VerifyCodeUtils.outputImage(width, height, 

resp.getOutputStream(), verifyCode);  
        
    }
    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {
        // TODO Auto-generated method stub
        doGet(req, resp);
    }
}
3、服务器端验证验证码servlet

 

package com.servlet;

import java.io.IOException;

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

import com.util.VerifyCodeUtils;


public class VerifyCodeServlet extends HttpServlet {
    
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {
        
        String code = req.getParameter("code");
        String key = (String) req.getSession().getAttribute("CODE");
        if(code != null && code.equalsIgnoreCase(key)){
            req.getSession().removeAttribute("CODE");
            resp.getWriter().println(true);
        }else{
            resp.getWriter().println(false);
        }
    }
    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {
        // TODO Auto-generated method stub
        super.doGet(req, resp);
    }
}
4、servet的注册,web.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.-instance" 

xmlns="http://java./xml/ns/javaee" 

xsi:schemaLocation="http://java./xml/ns/javaee 

http://java./xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" 

version="3.0">
  <display-name>test-captcha</display-name>
  
  
  <servlet>
      <servlet-name>CreateCodeServlet</servlet-name>
      <servlet-class>com.servlet.CreateCodeServlet</servlet-class>
  </servlet>
  <servlet-mapping>
      <servlet-name>CreateCodeServlet</servlet-name>
      <url-pattern>/createCode</url-pattern>
  </servlet-mapping>
  
   <servlet>
      <servlet-name>VerifyCodeServlet</servlet-name>
      <servlet-class>com.servlet.VerifyCodeServlet</servlet-class>
  </servlet>
  <servlet-mapping>
      <servlet-name>VerifyCodeServlet</servlet-name>
      <url-pattern>/verifyCode</url-pattern>
  </servlet-mapping>

  
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>
 

5、前端html文件

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//深圳市博纳网络信息技术有限公司//DTD HTML 4.01 Transitional//EN" 

"http://生成验证码工具类
package com.util;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Random;
 
import javax.imageio.ImageIO;


public class VerifyCodeUtils {
     
    //使用到Algerian字体,系统里没有的话需要安装字体,字体只显示大写,

去掉了1,0,i,o几个容易混淆的字符
    public static final String VERIFY_CODES = 

"23456789ABCDEFGHJKLMNPQRSTUVWXYZ";
    private static Random random = new Random();
 
 
    /**
     * 使用系统默认字符源生成验证码
     * @param verifySize    验证码长度
     * @return
     */
    public static String generateVerifyCode(int verifySize){
        return generateVerifyCode(verifySize, VERIFY_CODES);
    }
    
    /**
     * 使用指定源生成验证码
     * @param verifySize    验证码长度
     * @param sources   验证码字符源
     * @return
     */
    public static String generateVerifyCode(int verifySize, String 

sources){
        if(sources == null || sources.length() == 0){
            sources = VERIFY_CODES;
        }
        int codesLen = sources.length();
        Random rand = new Random(System.currentTimeMillis());
        StringBuilder verifyCode = new StringBuilder(verifySize);
        for(int i = 0; i < verifySize; i++){
            verifyCode.append(sources.charAt(rand.nextInt(codesLen-

1)));
        }
        return verifyCode.toString();
    }
     
    /**
     * 生成随机验证码文件,并返回验证码值
     * @param w
     * @param h
     * @param outputFile
     * @param verifySize
     * @return
     * @throws IOException
     */
    public static String outputVerifyImage(int w, int h, File 

outputFile, int verifySize) throws IOException{
        String verifyCode = generateVerifyCode(verifySize);
        outputImage(w, h, outputFile, verifyCode);
        return verifyCode;
    }
     
    /**
     * 输出随机验证码图片流,并返回验证码值
     * @param w
     * @param h
     * @param os
     * @param verifySize
     * @return
     * @throws IOException
     */
    public static String outputVerifyImage(int w, int h, OutputStream 

os, int verifySize) throws IOException{
        String verifyCode = generateVerifyCode(verifySize);
        outputImage(w, h, os, verifyCode);
        return verifyCode;
    }
     
    /**
     * 生成指定验证码图像文件
     * @param w
     * @param h
     * @param outputFile
     * @param code
     * @throws IOException
     */
    public static void outputImage(int w, int h, File outputFile, 

String code) throws IOException{
        if(outputFile == null){
            return;
        }
        File dir = outputFile.getParentFile();
        if(!dir.exists()){
            dir.mkdirs();
        }
        try{
            outputFile.createNewFile();
            FileOutputStream fos = new FileOutputStream(outputFile);
            outputImage(w, h, fos, code);
            fos.close();
        } catch(IOException e){
            throw e;
        }
    }
     
    /**
     * 输出指定验证码图片流
     * @param w
     * @param h
     * @param os
     * @param code
     * @throws IOException
     */
    public static void outputImage(int w, int h, OutputStream os, 

String code) throws IOException{
        int verifySize = code.length();
        BufferedImage image = new BufferedImage(w, h, 

BufferedImage.TYPE_INT_RGB);
        Random rand = new Random();
        Graphics2D g2 = image.createGraphics();
        g2.setRenderingHint

(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
        Color[] colors = new Color[5];
        Color[] colorSpaces = new Color[] { Color.WHITE, Color.CYAN,
                Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA, 

Color.ORANGE,
                Color.PINK, Color.YELLOW };
        float[] fractions = new float[colors.length];
        for(int i = 0; i < colors.length; i++){
            colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)];
            fractions[i] = rand.nextFloat();
        }
        Arrays.sort(fractions);
         
        g2.setColor(Color.GRAY);// 设置边框色
        g2.fillRect(0, 0, w, h);
         
        Color c = getRandColor(200, 250);
        g2.setColor(c);// 设置背景色
        g2.fillRect(0, 2, w, h-4);
         
        //绘制干扰线
        Random random = new Random();
        g2.setColor(getRandColor(160, 200));// 设置线条的颜色
        for (int i = 0; i < 20; i++) {
            int x = random.nextInt(w - 1);
            int y = random.nextInt(h - 1);
            int xl = random.nextInt(6) + 1;
            int yl = random.nextInt(12) + 1;
            g2.drawLine(x, y, x + xl + 40, y + yl + 20);
        }
         
        // 添加噪点
        float yawpRate = 0.05f;// 噪声率
        int area = (int) (yawpRate * w * h);
        for (int i = 0; i < area; i++) {
            int x = random.nextInt(w);
            int y = random.nextInt(h);
            int rgb = getRandomIntColor();
            image.setRGB(x, y, rgb);
        }
         
        shear(g2, w, h, c);// 使图片扭曲
 
        g2.setColor(getRandColor(100, 160));
        int fontSize = h-4;
        Font font = new Font("Algerian", Font.ITALIC, fontSize);
        g2.setFont(font);
        char[] chars = code.toCharArray();
        for(int i = 0; i < verifySize; i++){
            AffineTransform affine = new AffineTransform();
            affine.setToRotation(Math.PI / 4 * rand.nextDouble() * 

(rand.nextBoolean() ? 1 : -1), (w / verifySize) * i + fontSize/2, 

h/2);
            g2.setTransform(affine);
            g2.drawChars(chars, i, 1, ((w-10) / verifySize) * i + 5, 

h/2 + fontSize/2 - 10);
        }
         
        g2.dispose();
        ImageIO.write(image, "png", os);
    }
     
    private static Color getRandColor(int fc, int bc) {
        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);
    }
     
    private static int getRandomIntColor() {
        int[] rgb = getRandomRgb();
        int color = 0;
        for (int c : rgb) {
            color = color << 8;
            color = color | c;
        }
        return color;
    }
     
    private static int[] getRandomRgb() {
        int[] rgb = new int[3];
        for (int i = 0; i < 3; i++) {
            rgb[i] = random.nextInt(255);
        }
        return rgb;
    }
 
    private static void shear(Graphics g, int w1, int h1, Color color) 

{
        shearX(g, w1, h1, color);
        shearY(g, w1, h1, color);
    }
     
    private static void shearX(Graphics g, int w1, int h1, Color 

color) {
 
        int period = random.nextInt(2);
 
        boolean borderGap = true;
        int frames = 1;
        int phase = random.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);
            }
        }
 
    }
 
    private static void shearY(Graphics g, int w1, int h1, Color 

color) {
 
        int period = random.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);
            }
 
        }
    }
    public static void main(String[] args) throws IOException{
        File dir = new File("C:/Users/H__D/Desktop/");
        int w = 200, h = 80;
        String verifyCode = generateVerifyCode(4);
        File file = new File(dir, verifyCode + ".jpg");
        outputImage(w, h, file, verifyCode);
    }
}
 

使用图形验证码
 

1、使用流程

 

技术图片

 

2、服务器端生成验证码servlet

package com.servlet;

import java.io.IOException;

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

import com.util.VerifyCodeUtils;


public class CreateCodeServlet extends HttpServlet {
    
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {
        resp.setHeader("Pragma", "No-cache");  
        resp.setHeader("Cache-Control", "no-cache");  
        resp.setDateHeader("Expires", 0);  
        resp.setContentType("image/jpeg");  
          
        //生成随机字串  
        String verifyCode = VerifyCodeUtils.generateVerifyCode(4);  
        //存入会话session  
        req.getSession().setAttribute("CODE", verifyCode.toLowerCase

());  
        
        //生成图片  
        int width = 100;//宽
        int height = 40;//高  
        VerifyCodeUtils.outputImage(width, height, 

resp.getOutputStream(), verifyCode);  
        
    }
    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {
        // TODO Auto-generated method stub
        doGet(req, resp);
    }
}
3、服务器端验证验证码servlet

 

package com.servlet;

import java.io.IOException;

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

import com.util.VerifyCodeUtils;


public class VerifyCodeServlet extends HttpServlet {
    
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {
        
        String code = req.getParameter("code");
        String key = (String) req.getSession().getAttribute("CODE");
        if(code != null && code.equalsIgnoreCase(key)){
            req.getSession().removeAttribute("CODE");
            resp.getWriter().println(true);
        }else{
            resp.getWriter().println(false);
        }
    }
    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {
        // TODO Auto-generated method stub
        super.doGet(req, resp);
    }
}
4、servet的注册,web.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.-instance" 

xmlns="http://java./xml/ns/javaee" 

xsi:schemaLocation="http://java./xml/ns/javaee 

http://java./xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" 

version="3.0">
  <display-name>test-captcha</display-name>
  
  
  <servlet>
      <servlet-name>CreateCodeServlet</servlet-name>
      <servlet-class>com.servlet.CreateCodeServlet</servlet-class>
  </servlet>
  <servlet-mapping>
      <servlet-name>CreateCodeServlet</servlet-name>
      <url-pattern>/createCode</url-pattern>
  </servlet-mapping>
  
   <servlet>
      <servlet-name>VerifyCodeServlet</servlet-name>
      <servlet-class>com.servlet.VerifyCodeServlet</servlet-class>
  </servlet>
  <servlet-mapping>
      <servlet-name>VerifyCodeServlet</servlet-name>
      <url-pattern>/verifyCode</url-pattern>
  </servlet-mapping>

  
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>
 

5、前端html文件

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//深圳市博纳网络信息技术有限公司//DTD HTML 4.01 Transitional//EN" 

"http://生成验证码工具类
package com.util;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Random;
 
import javax.imageio.ImageIO;


public class VerifyCodeUtils {
     
    //使用到Algerian字体,系统里没有的话需要安装字体,字体只显示大写,

去掉了1,0,i,o几个容易混淆的字符
    public static final String VERIFY_CODES = 

"23456789ABCDEFGHJKLMNPQRSTUVWXYZ";
    private static Random random = new Random();
 
 
    /**
     * 使用系统默认字符源生成验证码
     * @param verifySize    验证码长度
     * @return
     */
    public static String generateVerifyCode(int verifySize){
        return generateVerifyCode(verifySize, VERIFY_CODES);
    }
    
    /**
     * 使用指定源生成验证码
     * @param verifySize    验证码长度
     * @param sources   验证码字符源
     * @return
     */
    public static String generateVerifyCode(int verifySize, String 

sources){
        if(sources == null || sources.length() == 0){
            sources = VERIFY_CODES;
        }
        int codesLen = sources.length();
        Random rand = new Random(System.currentTimeMillis());
        StringBuilder verifyCode = new StringBuilder(verifySize);
        for(int i = 0; i < verifySize; i++){
            verifyCode.append(sources.charAt(rand.nextInt(codesLen-

1)));
        }
        return verifyCode.toString();
    }
     
    /**
     * 生成随机验证码文件,并返回验证码值
     * @param w
     * @param h
     * @param outputFile
     * @param verifySize
     * @return
     * @throws IOException
     */
    public static String outputVerifyImage(int w, int h, File 

outputFile, int verifySize) throws IOException{
        String verifyCode = generateVerifyCode(verifySize);
        outputImage(w, h, outputFile, verifyCode);
        return verifyCode;
    }
     
    /**
     * 输出随机验证码图片流,并返回验证码值
     * @param w
     * @param h
     * @param os
     * @param verifySize
     * @return
     * @throws IOException
     */
    public static String outputVerifyImage(int w, int h, OutputStream 

os, int verifySize) throws IOException{
        String verifyCode = generateVerifyCode(verifySize);
        outputImage(w, h, os, verifyCode);
        return verifyCode;
    }
     
    /**
     * 生成指定验证码图像文件
     * @param w
     * @param h
     * @param outputFile
     * @param code
     * @throws IOException
     */
    public static void outputImage(int w, int h, File outputFile, 

String code) throws IOException{
        if(outputFile == null){
            return;
        }
        File dir = outputFile.getParentFile();
        if(!dir.exists()){
            dir.mkdirs();
        }
        try{
            outputFile.createNewFile();
            FileOutputStream fos = new FileOutputStream(outputFile);
            outputImage(w, h, fos, code);
            fos.close();
        } catch(IOException e){
            throw e;
        }
    }
     
    /**
     * 输出指定验证码图片流
     * @param w
     * @param h
     * @param os
     * @param code
     * @throws IOException
     */
    public static void outputImage(int w, int h, OutputStream os, 

String code) throws IOException{
        int verifySize = code.length();
        BufferedImage image = new BufferedImage(w, h, 

BufferedImage.TYPE_INT_RGB);
        Random rand = new Random();
        Graphics2D g2 = image.createGraphics();
        g2.setRenderingHint

(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
        Color[] colors = new Color[5];
        Color[] colorSpaces = new Color[] { Color.WHITE, Color.CYAN,
                Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA, 

Color.ORANGE,
                Color.PINK, Color.YELLOW };
        float[] fractions = new float[colors.length];
        for(int i = 0; i < colors.length; i++){
            colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)];
            fractions[i] = rand.nextFloat();
        }
        Arrays.sort(fractions);
         
        g2.setColor(Color.GRAY);// 设置边框色
        g2.fillRect(0, 0, w, h);
         
        Color c = getRandColor(200, 250);
        g2.setColor(c);// 设置背景色
        g2.fillRect(0, 2, w, h-4);
         
        //绘制干扰线
        Random random = new Random();
        g2.setColor(getRandColor(160, 200));// 设置线条的颜色
        for (int i = 0; i < 20; i++) {
            int x = random.nextInt(w - 1);
            int y = random.nextInt(h - 1);
            int xl = random.nextInt(6) + 1;
            int yl = random.nextInt(12) + 1;
            g2.drawLine(x, y, x + xl + 40, y + yl + 20);
        }
         
        // 添加噪点
        float yawpRate = 0.05f;// 噪声率
        int area = (int) (yawpRate * w * h);
        for (int i = 0; i < area; i++) {
            int x = random.nextInt(w);
            int y = random.nextInt(h);
            int rgb = getRandomIntColor();
            image.setRGB(x, y, rgb);
        }
         
        shear(g2, w, h, c);// 使图片扭曲
 
        g2.setColor(getRandColor(100, 160));
        int fontSize = h-4;
        Font font = new Font("Algerian", Font.ITALIC, fontSize);
        g2.setFont(font);
        char[] chars = code.toCharArray();
        for(int i = 0; i < verifySize; i++){
            AffineTransform affine = new AffineTransform();
            affine.setToRotation(Math.PI / 4 * rand.nextDouble() * 

(rand.nextBoolean() ? 1 : -1), (w / verifySize) * i + fontSize/2, 

h/2);
            g2.setTransform(affine);
            g2.drawChars(chars, i, 1, ((w-10) / verifySize) * i + 5, 

h/2 + fontSize/2 - 10);
        }
         
        g2.dispose();
        ImageIO.write(image, "png", os);
    }
     
    private static Color getRandColor(int fc, int bc) {
        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);
    }
     
    private static int getRandomIntColor() {
        int[] rgb = getRandomRgb();
        int color = 0;
        for (int c : rgb) {
            color = color << 8;
            color = color | c;
        }
        return color;
    }
     
    private static int[] getRandomRgb() {
        int[] rgb = new int[3];
        for (int i = 0; i < 3; i++) {
            rgb[i] = random.nextInt(255);
        }
        return rgb;
    }
 
    private static void shear(Graphics g, int w1, int h1, Color color) 

{
        shearX(g, w1, h1, color);
        shearY(g, w1, h1, color);
    }
     
    private static void shearX(Graphics g, int w1, int h1, Color 

color) {
 
        int period = random.nextInt(2);
 
        boolean borderGap = true;
        int frames = 1;
        int phase = random.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);
            }
        }
 
    }
 
    private static void shearY(Graphics g, int w1, int h1, Color 

color) {
 
        int period = random.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);
            }
 
        }
    }
    public static void main(String[] args) throws IOException{
        File dir = new File("C:/Users/H__D/Desktop/");
        int w = 200, h = 80;
        String verifyCode = generateVerifyCode(4);
        File file = new File(dir, verifyCode + ".jpg");
        outputImage(w, h, file, verifyCode);
    }
}
 

使用图形验证码
 

1、使用流程

 

技术图片

 

2、服务器端生成验证码servlet

package com.servlet;

import java.io.IOException;

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

import com.util.VerifyCodeUtils;


public class CreateCodeServlet extends HttpServlet {
    
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {
        resp.setHeader("Pragma", "No-cache");  
        resp.setHeader("Cache-Control", "no-cache");  
        resp.setDateHeader("Expires", 0);  
        resp.setContentType("image/jpeg");  
          
        //生成随机字串  
        String verifyCode = VerifyCodeUtils.generateVerifyCode(4);  
        //存入会话session  
        req.getSession().setAttribute("CODE", verifyCode.toLowerCase

());  
        
        //生成图片  
        int width = 100;//宽
        int height = 40;//高  
        VerifyCodeUtils.outputImage(width, height, 

resp.getOutputStream(), verifyCode);  
        
    }
    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {
        // TODO Auto-generated method stub
        doGet(req, resp);
    }
}
3、服务器端验证验证码servlet

 

package com.servlet;

import java.io.IOException;

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

import com.util.VerifyCodeUtils;


public class VerifyCodeServlet extends HttpServlet {
    
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {
        
        String code = req.getParameter("code");
        String key = (String) req.getSession().getAttribute("CODE");
        if(code != null && code.equalsIgnoreCase(key)){
            req.getSession().removeAttribute("CODE");
            resp.getWriter().println(true);
        }else{
            resp.getWriter().println(false);
        }
    }
    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {
        // TODO Auto-generated method stub
        super.doGet(req, resp);
    }
}
4、servet的注册,web.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://生成验证码工具类
package com.util;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Random;
 
import javax.imageio.ImageIO;


public class VerifyCodeUtils {
     
    //使用到Algerian字体,系统里没有的话需要安装字体,字体只显示大写,

去掉了1,0,i,o几个容易混淆的字符
    public static final String VERIFY_CODES = 

"23456789ABCDEFGHJKLMNPQRSTUVWXYZ";
    private static Random random = new Random();
 
 
    /**
     * 使用系统默认字符源生成验证码
     * @param verifySize    验证码长度
     * @return
     */
    public static String generateVerifyCode(int verifySize){
        return generateVerifyCode(verifySize, VERIFY_CODES);
    }
    
    /**
     * 使用指定源生成验证码
     * @param verifySize    验证码长度
     * @param sources   验证码字符源
     * @return
     */
    public static String generateVerifyCode(int verifySize, String 

sources){
        if(sources == null || sources.length() == 0){
            sources = VERIFY_CODES;
        }
        int codesLen = sources.length();
        Random rand = new Random(System.currentTimeMillis());
        StringBuilder verifyCode = new StringBuilder(verifySize);
        for(int i = 0; i < verifySize; i++){
            verifyCode.append(sources.charAt(rand.nextInt(codesLen-

1)));
        }
        return verifyCode.toString();
    }
     
    /**
     * 生成随机验证码文件,并返回验证码值
     * @param w
     * @param h
     * @param outputFile
     * @param verifySize
     * @return
     * @throws IOException
     */
    public static String outputVerifyImage(int w, int h, File 

outputFile, int verifySize) throws IOException{
        String verifyCode = generateVerifyCode(verifySize);
        outputImage(w, h, outputFile, verifyCode);
        return verifyCode;
    }
     
    /**
     * 输出随机验证码图片流,并返回验证码值
     * @param w
     * @param h
     * @param os
     * @param verifySize
     * @return
     * @throws IOException
     */
    public static String outputVerifyImage(int w, int h, OutputStream 

os, int verifySize) throws IOException{
        String verifyCode = generateVerifyCode(verifySize);
        outputImage(w, h, os, verifyCode);
        return verifyCode;
    }
     
    /**
     * 生成指定验证码图像文件
     * @param w
     * @param h
     * @param outputFile
     * @param code
     * @throws IOException
     */
    public static void outputImage(int w, int h, File outputFile, 

String code) throws IOException{
        if(outputFile == null){
            return;
        }
        File dir = outputFile.getParentFile();
        if(!dir.exists()){
            dir.mkdirs();
        }
        try{
            outputFile.createNewFile();
            FileOutputStream fos = new FileOutputStream(outputFile);
            outputImage(w, h, fos, code);
            fos.close();
        } catch(IOException e){
            throw e;
        }
    }
     
    /**
     * 输出指定验证码图片流
     * @param w
     * @param h
     * @param os
     * @param code
     * @throws IOException
     */
    public static void outputImage(int w, int h, OutputStream os, 

String code) throws IOException{
        int verifySize = code.length();
        BufferedImage image = new BufferedImage(w, h, 

BufferedImage.TYPE_INT_RGB);
        Random rand = new Random();
        Graphics2D g2 = image.createGraphics();
        g2.setRenderingHint

(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
        Color[] colors = new Color[5];
        Color[] colorSpaces = new Color[] { Color.WHITE, Color.CYAN,
                Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA, 

Color.ORANGE,
                Color.PINK, Color.YELLOW };
        float[] fractions = new float[colors.length];
        for(int i = 0; i < colors.length; i++){
            colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)];
            fractions[i] = rand.nextFloat();
        }
        Arrays.sort(fractions);
         
        g2.setColor(Color.GRAY);// 设置边框色
        g2.fillRect(0, 0, w, h);
         
        Color c = getRandColor(200, 250);
        g2.setColor(c);// 设置背景色
        g2.fillRect(0, 2, w, h-4);
         
        //绘制干扰线
        Random random = new Random();
        g2.setColor(getRandColor(160, 200));// 设置线条的颜色
        for (int i = 0; i < 20; i++) {
            int x = random.nextInt(w - 1);
            int y = random.nextInt(h - 1);
            int xl = random.nextInt(6) + 1;
            int yl = random.nextInt(12) + 1;
            g2.drawLine(x, y, x + xl + 40, y + yl + 20);
        }
         
        // 添加噪点
        float yawpRate = 0.05f;// 噪声率
        int area = (int) (yawpRate * w * h);
        for (int i = 0; i < area; i++) {
            int x = random.nextInt(w);
            int y = random.nextInt(h);
            int rgb = getRandomIntColor();
            image.setRGB(x, y, rgb);
        }
         
        shear(g2, w, h, c);// 使图片扭曲
 
        g2.setColor(getRandColor(100, 160));
        int fontSize = h-4;
        Font font = new Font("Algerian", Font.ITALIC, fontSize);
        g2.setFont(font);
        char[] chars = code.toCharArray();
        for(int i = 0; i < verifySize; i++){
            AffineTransform affine = new AffineTransform();
            affine.setToRotation(Math.PI / 4 * rand.nextDouble() * 

(rand.nextBoolean() ? 1 : -1), (w / verifySize) * i + fontSize/2, 

h/2);
            g2.setTransform(affine);
            g2.drawChars(chars, i, 1, ((w-10) / verifySize) * i + 5, 

h/2 + fontSize/2 - 10);
        }
         
        g2.dispose();
        ImageIO.write(image, "png", os);
    }
     
    private static Color getRandColor(int fc, int bc) {
        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);
    }
     
    private static int getRandomIntColor() {
        int[] rgb = getRandomRgb();
        int color = 0;
        for (int c : rgb) {
            color = color << 8;
            color = color | c;
        }
        return color;
    }
     
    private static int[] getRandomRgb() {
        int[] rgb = new int[3];
        for (int i = 0; i < 3; i++) {
            rgb[i] = random.nextInt(255);
        }
        return rgb;
    }
 
    private static void shear(Graphics g, int w1, int h1, Color color) 

{
        shearX(g, w1, h1, color);
        shearY(g, w1, h1, color);
    }
     
    private static void shearX(Graphics g, int w1, int h1, Color 

color) {
 
        int period = random.nextInt(2);
 
        boolean borderGap = true;
        int frames = 1;
        int phase = random.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);
            }
        }
 
    }
 
    private static void shearY(Graphics g, int w1, int h1, Color 

color) {
 
        int period = random.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);
            }
 
        }
    }
    public static void main(String[] args) throws IOException{
        File dir = new File("C:/Users/H__D/Desktop/");
        int w = 200, h = 80;
        String verifyCode = generateVerifyCode(4);
        File file = new File(dir, verifyCode + ".jpg");
        outputImage(w, h, file, verifyCode);
    }
}
 

使用图形验证码
 

1、使用流程

 

技术图片

 

2、服务器端生成验证码servlet

package com.servlet;

import java.io.IOException;

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

import com.util.VerifyCodeUtils;


public class CreateCodeServlet extends HttpServlet {
    
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {
        resp.setHeader("Pragma", "No-cache");  
        resp.setHeader("Cache-Control", "no-cache");  
        resp.setDateHeader("Expires", 0);  
        resp.setContentType("image/jpeg");  
          
        //生成随机字串  
        String verifyCode = VerifyCodeUtils.generateVerifyCode(4);  
        //存入会话session  
        req.getSession().setAttribute("CODE", verifyCode.toLowerCase

());  
        
        //生成图片  
        int width = 100;//宽
        int height = 40;//高  
        VerifyCodeUtils.outputImage(width, height, 

resp.getOutputStream(), verifyCode);  
        
    }
    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {
        // TODO Auto-generated method stub
        doGet(req, resp);
    }
}
3、服务器端验证验证码servlet

 

package com.servlet;

import java.io.IOException;

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

import com.util.VerifyCodeUtils;


public class VerifyCodeServlet extends HttpServlet {
    
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {
        
        String code = req.getParameter("code");
        String key = (String) req.getSession().getAttribute("CODE");
        if(code != null && code.equalsIgnoreCase(key)){
            req.getSession().removeAttribute("CODE");
            resp.getWriter().println(true);
        }else{
            resp.getWriter().println(false);
        }
    }
    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {
        // TODO Auto-generated method stub
        super.doGet(req, resp);
    }
}
4、servet的注册,web.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.-instance" 

xmlns="http://java./xml/ns/javaee" 

xsi:schemaLocation="http://java./xml/ns/javaee 

http://java./xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" 

version="3.0">
  <display-name>test-captcha</display-name>
  
  
  <servlet>
      <servlet-name>CreateCodeServlet</servlet-name>
      <servlet-class>com.servlet.CreateCodeServlet</servlet-class>
  </servlet>
  <servlet-mapping>
      <servlet-name>CreateCodeServlet</servlet-name>
      <url-pattern>/createCode</url-pattern>
  </servlet-mapping>
  
   <servlet>
      <servlet-name>VerifyCodeServlet</servlet-name>
      <servlet-class>com.servlet.VerifyCodeServlet</servlet-class>
  </servlet>
  <servlet-mapping>
      <servlet-name>VerifyCodeServlet</servlet-name>
      <url-pattern>/verifyCode</url-pattern>
  </servlet-mapping>

  
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>
 

5、前端html文件

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 

"http://www.www.">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <h2>测试验证码:</h2>
    请输入验证码:<input type="text" name="code" /><img id="codeimg" 

src="${pageContext.request.contextPath }/createCode" 

onclick="changeImg()"><a href="javascript:void(0);" 

onclick="changeImg()">看不清,换一张</a>
    <button onclick="submit()">提交</button>
    <script type="text/javascript">
    
        //改变验证码事件
        function changeImg(){
            var img = document.getElementById(‘codeimg‘);
            img.src = "${pageContext.request.contextPath 

}/createCode?x=" + Math.floor(Math.random()*100)
        }
        
        //提交验证并验证验证码
        function submit(){
            var input = document.getElementsByTagName(‘input‘)[0];
            
            //ajax提交
            var xhr = new XMLHttpRequest();
            
            xhr.onreadystatechange = function(){
                if(xhr.readyState == 4 && xhr.status == 200) {
                    alert(xhr.responseText);
                }  
            }
            
            xhr.open(‘get‘,‘${pageContext.request.contextPath 

}/verifyCode?code=‘ + input.value);
            xhr.send(null);
            
        }
        
        
        
    </script>
</body>
</html>-instance" xmlns="http://java./xml/ns/javaee" 

xsi:schemaLocation="http://java./xml/ns/javaee 

http://java./xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" 

version="3.0">
  <display-name>test-captcha</display-name>
  
  
  <servlet>
      <servlet-name>CreateCodeServlet</servlet-name>
      <servlet-class>com.servlet.CreateCodeServlet</servlet-class>
  </servlet>
  <servlet-mapping>
      <servlet-name>CreateCodeServlet</servlet-name>
      <url-pattern>/createCode</url-pattern>
  </servlet-mapping>
  
   <servlet>
      <servlet-name>VerifyCodeServlet</servlet-name>
      <servlet-class>com.servlet.VerifyCodeServlet</servlet-class>
  </servlet>
  <servlet-mapping>
      <servlet-name>VerifyCodeServlet</servlet-name>
      <url-pattern>/verifyCode</url-pattern>
  </servlet-mapping>

  
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>
 

5、前端html文件

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//深圳市博纳网络信息技术有限公司//DTD HTML 

4.01 Transitional//EN" "http://生成验证码工具类
package com.util;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Random;
 
import javax.imageio.ImageIO;


public class VerifyCodeUtils {
     
    //使用到Algerian字体,系统里没有的话需要安装字体,字体只显示大写,

去掉了1,0,i,o几个容易混淆的字符
    public static final String VERIFY_CODES = 

"23456789ABCDEFGHJKLMNPQRSTUVWXYZ";
    private static Random random = new Random();
 
 
    /**
     * 使用系统默认字符源生成验证码
     * @param verifySize    验证码长度
     * @return
     */
    public static String generateVerifyCode(int verifySize){
        return generateVerifyCode(verifySize, VERIFY_CODES);
    }
    
    /**
     * 使用指定源生成验证码
     * @param verifySize    验证码长度
     * @param sources   验证码字符源
     * @return
     */
    public static String generateVerifyCode(int verifySize, String 

sources){
        if(sources == null || sources.length() == 0){
            sources = VERIFY_CODES;
        }
        int codesLen = sources.length();
        Random rand = new Random(System.currentTimeMillis());
        StringBuilder verifyCode = new StringBuilder(verifySize);
        for(int i = 0; i < verifySize; i++){
            verifyCode.append(sources.charAt(rand.nextInt(codesLen-

1)));
        }
        return verifyCode.toString();
    }
     
    /**
     * 生成随机验证码文件,并返回验证码值
     * @param w
     * @param h
     * @param outputFile
     * @param verifySize
     * @return
     * @throws IOException
     */
    public static String outputVerifyImage(int w, int h, File 

outputFile, int verifySize) throws IOException{
        String verifyCode = generateVerifyCode(verifySize);
        outputImage(w, h, outputFile, verifyCode);
        return verifyCode;
    }
     
    /**
     * 输出随机验证码图片流,并返回验证码值
     * @param w
     * @param h
     * @param os
     * @param verifySize
     * @return
     * @throws IOException
     */
    public static String outputVerifyImage(int w, int h, OutputStream 

os, int verifySize) throws IOException{
        String verifyCode = generateVerifyCode(verifySize);
        outputImage(w, h, os, verifyCode);
        return verifyCode;
    }
     
    /**
     * 生成指定验证码图像文件
     * @param w
     * @param h
     * @param outputFile
     * @param code
     * @throws IOException
     */
    public static void outputImage(int w, int h, File outputFile, 

String code) throws IOException{
        if(outputFile == null){
            return;
        }
        File dir = outputFile.getParentFile();
        if(!dir.exists()){
            dir.mkdirs();
        }
        try{
            outputFile.createNewFile();
            FileOutputStream fos = new FileOutputStream(outputFile);
            outputImage(w, h, fos, code);
            fos.close();
        } catch(IOException e){
            throw e;
        }
    }
     
    /**
     * 输出指定验证码图片流
     * @param w
     * @param h
     * @param os
     * @param code
     * @throws IOException
     */
    public static void outputImage(int w, int h, OutputStream os, 

String code) throws IOException{
        int verifySize = code.length();
        BufferedImage image = new BufferedImage(w, h, 

BufferedImage.TYPE_INT_RGB);
        Random rand = new Random();
        Graphics2D g2 = image.createGraphics();
        g2.setRenderingHint

(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
        Color[] colors = new Color[5];
        Color[] colorSpaces = new Color[] { Color.WHITE, Color.CYAN,
                Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA, 

Color.ORANGE,
                Color.PINK, Color.YELLOW };
        float[] fractions = new float[colors.length];
        for(int i = 0; i < colors.length; i++){
            colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)];
            fractions[i] = rand.nextFloat();
        }
        Arrays.sort(fractions);
         
        g2.setColor(Color.GRAY);// 设置边框色
        g2.fillRect(0, 0, w, h);
         
        Color c = getRandColor(200, 250);
        g2.setColor(c);// 设置背景色
        g2.fillRect(0, 2, w, h-4);
         
        //绘制干扰线
        Random random = new Random();
        g2.setColor(getRandColor(160, 200));// 设置线条的颜色
        for (int i = 0; i < 20; i++) {
            int x = random.nextInt(w - 1);
            int y = random.nextInt(h - 1);
            int xl = random.nextInt(6) + 1;
            int yl = random.nextInt(12) + 1;
            g2.drawLine(x, y, x + xl + 40, y + yl + 20);
        }
         
        // 添加噪点
        float yawpRate = 0.05f;// 噪声率
        int area = (int) (yawpRate * w * h);
        for (int i = 0; i < area; i++) {
            int x = random.nextInt(w);
            int y = random.nextInt(h);
            int rgb = getRandomIntColor();
            image.setRGB(x, y, rgb);
        }
         
        shear(g2, w, h, c);// 使图片扭曲
 
        g2.setColor(getRandColor(100, 160));
        int fontSize = h-4;
        Font font = new Font("Algerian", Font.ITALIC, fontSize);
        g2.setFont(font);
        char[] chars = code.toCharArray();
        for(int i = 0; i < verifySize; i++){
            AffineTransform affine = new AffineTransform();
            affine.setToRotation(Math.PI / 4 * rand.nextDouble() * 

(rand.nextBoolean() ? 1 : -1), (w / verifySize) * i + fontSize/2, 

h/2);
            g2.setTransform(affine);
            g2.drawChars(chars, i, 1, ((w-10) / verifySize) * i + 5, 

h/2 + fontSize/2 - 10);
        }
         
        g2.dispose();
        ImageIO.write(image, "png", os);
    }
     
    private static Color getRandColor(int fc, int bc) {
        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);
    }
     
    private static int getRandomIntColor() {
        int[] rgb = getRandomRgb();
        int color = 0;
        for (int c : rgb) {
            color = color << 8;
            color = color | c;
        }
        return color;
    }
     
    private static int[] getRandomRgb() {
        int[] rgb = new int[3];
        for (int i = 0; i < 3; i++) {
            rgb[i] = random.nextInt(255);
        }
        return rgb;
    }
 
    private static void shear(Graphics g, int w1, int h1, Color color) 

{
        shearX(g, w1, h1, color);
        shearY(g, w1, h1, color);
    }
     
    private static void shearX(Graphics g, int w1, int h1, Color 

color) {
 
        int period = random.nextInt(2);
 
        boolean borderGap = true;
        int frames = 1;
        int phase = random.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);
            }
        }
 
    }
 
    private static void shearY(Graphics g, int w1, int h1, Color 

color) {
 
        int period = random.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);
            }
 
        }
    }
    public static void main(String[] args) throws IOException{
        File dir = new File("C:/Users/H__D/Desktop/");
        int w = 200, h = 80;
        String verifyCode = generateVerifyCode(4);
        File file = new File(dir, verifyCode + ".jpg");
        outputImage(w, h, file, verifyCode);
    }
}
 

使用图形验证码
 

1、使用流程

 

技术图片

 

2、服务器端生成验证码servlet

package com.servlet;

import java.io.IOException;

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

import com.util.VerifyCodeUtils;


public class CreateCodeServlet extends HttpServlet {
    
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {
        resp.setHeader("Pragma", "No-cache");  
        resp.setHeader("Cache-Control", "no-cache");  
        resp.setDateHeader("Expires", 0);  
        resp.setContentType("image/jpeg");  
          
        //生成随机字串  
        String verifyCode = VerifyCodeUtils.generateVerifyCode(4);  
        //存入会话session  
        req.getSession().setAttribute("CODE", verifyCode.toLowerCase

());  
        
        //生成图片  
        int width = 100;//宽
        int height = 40;//高  
        VerifyCodeUtils.outputImage(width, height, 

resp.getOutputStream(), verifyCode);  
        
    }
    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {
        // TODO Auto-generated method stub
        doGet(req, resp);
    }
}
3、服务器端验证验证码servlet

 

package com.servlet;

import java.io.IOException;

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

import com.util.VerifyCodeUtils;


public class VerifyCodeServlet extends HttpServlet {
    
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {
        
        String code = req.getParameter("code");
        String key = (String) req.getSession().getAttribute("CODE");
        if(code != null && code.equalsIgnoreCase(key)){
            req.getSession().removeAttribute("CODE");
            resp.getWriter().println(true);
        }else{
            resp.getWriter().println(false);
        }
    }
    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse 

resp) throws ServletException, IOException {
        // TODO Auto-generated method stub
        super.doGet(req, resp);
    }
}
4、servet的注册,web.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.-instance" 

xmlns="http://java./xml/ns/javaee" 

xsi:schemaLocation="http://java./xml/ns/javaee 

http://java./xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" 

version="3.0">
  <display-name>test-captcha</display-name>
  
  
  <servlet>
      <servlet-name>CreateCodeServlet</servlet-name>
      <servlet-class>com.servlet.CreateCodeServlet</servlet-class>
  </servlet>
  <servlet-mapping>
      <servlet-name>CreateCodeServlet</servlet-name>
      <url-pattern>/createCode</url-pattern>
  </servlet-mapping>
  
   <servlet>
      <servlet-name>VerifyCodeServlet</servlet-name>
      <servlet-class>com.servlet.VerifyCodeServlet</servlet-class>
  </servlet>
  <servlet-mapping>
      <servlet-name>VerifyCodeServlet</servlet-name>
      <url-pattern>/verifyCode</url-pattern>
  </servlet-mapping>

  
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>
 

5、前端html文件

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//深圳市博纳网络信息技术有限公司//DTD HTML 

4.01 Transitional//EN" "http://www.">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <h2>测试验证码:</h2>
    请输入验证码:<input type="text" name="code" /><img id="codeimg" 

src="${pageContext.request.contextPath }/createCode" 

onclick="changeImg()"><a href="javascript:void(0);" 

onclick="changeImg()">看不清,换一张</a>
    <button onclick="submit()">提交</button>
    <script type="text/javascript">
    
        //改变验证码事件
        function changeImg(){
            var img = document.getElementById(‘codeimg‘);
            img.src = "${pageContext.request.contextPath 

}/createCode?x=" + Math.floor(Math.random()*100)
        }
        
        //提交验证并验证验证码
        function submit(){
            var input = document.getElementsByTagName(‘input‘)[0];
            
            //ajax提交
            var xhr = new XMLHttpRequest();
            
            xhr.onreadystatechange = function(){
                if(xhr.readyState == 4 && xhr.status == 200) {
                    alert(xhr.responseText);
                }  
            }
            
            xhr.open(‘get‘,‘${pageContext.request.contextPath 

}/verifyCode?code=‘ + input.value);
            xhr.send(null);
            
        }
        
        
        
    </script>
</body>
</html>">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <h2>测试验证码:</h2>
    请输入验证码:<input type="text" name="code" /><img id="codeimg" 

src="${pageContext.request.contextPath }/createCode" 

onclick="changeImg()"><a href="javascript:void(0);" 

onclick="changeImg()">看不清,换一张</a>
    <button onclick="submit()">提交</button>
    <script type="text/javascript">
    
        //改变验证码事件
        function changeImg(){
            var img = document.getElementById(‘codeimg‘);
            img.src = "${pageContext.request.contextPath 

}/createCode?x=" + Math.floor(Math.random()*100)
        }
        
        //提交验证并验证验证码
        function submit(){
            var input = document.getElementsByTagName(‘input‘)[0];
            
            //ajax提交
            var xhr = new XMLHttpRequest();
            
            xhr.onreadystatechange = function(){
                if(xhr.readyState == 4 && xhr.status == 200) {
                    alert(xhr.responseText);
                }  
            }
            
            xhr.open(‘get‘,‘${pageContext.request.contextPath 

}/verifyCode?code=‘ + input.value);
            xhr.send(null);
            
        }
        
        
        
    </script>
</body>
</html>">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <h2>测试验证码:</h2>
    请输入验证码:<input type="text" name="code" /><img id="codeimg" 

src="${pageContext.request.contextPath }/createCode" 

onclick="changeImg()"><a href="javascript:void(0);" 

onclick="changeImg()">看不清,换一张</a>
    <button onclick="submit()">提交</button>
    <script type="text/javascript">
    
        //改变验证码事件
        function changeImg(){
            var img = document.getElementById(‘codeimg‘);
            img.src = "${pageContext.request.contextPath 

}/createCode?x=" + Math.floor(Math.random()*100)
        }
        
        //提交验证并验证验证码
        function submit(){
            var input = document.getElementsByTagName(‘input‘)[0];
            
            //ajax提交
            var xhr = new XMLHttpRequest();
            
            xhr.onreadystatechange = function(){
                if(xhr.readyState == 4 && xhr.status == 200) {
                    alert(xhr.responseText);
                }  
            }
            
            xhr.open(‘get‘,‘${pageContext.request.contextPath 

}/verifyCode?code=‘ + input.value);
            xhr.send(null);
            
        }
        
        
        
    </script>
</body>
</html>">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <h2>测试验证码:</h2>
    请输入验证码:<input type="text" name="code" /><img id="codeimg" 

src="${pageContext.request.contextPath }/createCode" 

onclick="changeImg()"><a href="javascript:void(0);" 

onclick="changeImg()">看不清,换一张</a>
    <button onclick="submit()">提交</button>
    <script type="text/javascript">
    
        //改变验证码事件
        function changeImg(){
            var img = document.getElementById(‘codeimg‘);
            img.src = "${pageContext.request.contextPath 

}/createCode?x=" + Math.floor(Math.random()*100)
        }
        
        //提交验证并验证验证码
        function submit(){
            var input = document.getElementsByTagName(‘input‘)[0];
            
            //ajax提交
            var xhr = new XMLHttpRequest();
            
            xhr.onreadystatechange = function(){
                if(xhr.readyState == 4 && xhr.status == 200) {
                    alert(xhr.responseText);
                }  
            }
            
            xhr.open(‘get‘,‘${pageContext.request.contextPath 

}/verifyCode?code=‘ + input.value);
            xhr.send(null);
            
        }
        
        
        
    </script>
</body>
</html>-instance" xmlns="http://java./xml/ns/javaee" 

xsi:schemaLocation="http://java./xml/ns/javaee 

http://java./xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" 

version="3.0">
  <display-name>test-captcha</display-name>
  
  
  <servlet>
      <servlet-name>CreateCodeServlet</servlet-name>
      <servlet-class>com.servlet.CreateCodeServlet</servlet-class>
  </servlet>
  <servlet-mapping>
      <servlet-name>CreateCodeServlet</servlet-name>
      <url-pattern>/createCode</url-pattern>
  </servlet-mapping>
  
   <servlet>
      <servlet-name>VerifyCodeServlet</servlet-name>
      <servlet-class>com.servlet.VerifyCodeServlet</servlet-class>
  </servlet>
  <servlet-mapping>
      <servlet-name>VerifyCodeServlet</servlet-name>
      <url-pattern>/verifyCode</url-pattern>
  </servlet-mapping>

  
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>
 

5、前端html文件

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//深圳市博纳网络信息技术有限公司//DTD HTML 

4.01 Transitional//EN" "http://www.">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <h2>测试验证码:</h2>
    请输入验证码:<input type="text" name="code" /><img id="codeimg" 

src="${pageContext.request.contextPath }/createCode" 

onclick="changeImg()"><a href="javascript:void(0);" 

onclick="changeImg()">看不清,换一张</a>
    <button onclick="submit()">提交</button>
    <script type="text/javascript">
    
        //改变验证码事件
        function changeImg(){
            var img = document.getElementById(‘codeimg‘);
            img.src = "${pageContext.request.contextPath 

}/createCode?x=" + Math.floor(Math.random()*100)
        }
        
        //提交验证并验证验证码
        function submit(){
            var input = document.getElementsByTagName(‘input‘)[0];
            
            //ajax提交
            var xhr = new XMLHttpRequest();
            
            xhr.onreadystatechange = function(){
                if(xhr.readyState == 4 && xhr.status == 200) {
                    alert(xhr.responseText);
                }  
            }
            
            xhr.open(‘get‘,‘${pageContext.request.contextPath 

}/verifyCode?code=‘ + input.value);
            xhr.send(null);
            
        }
        
        
        
    </script>
</body>
</html>

生成验证码工具类

package com.util;


import java.awt.Color;

import java.awt.Font;

import java.awt.Graphics;

import java.awt.Graphics2D;

import java.awt.RenderingHints;

import java.awt.geom.AffineTransform;

import java.awt.image.BufferedImage;

import java.io.File;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.OutputStream;

import java.util.Arrays;

import java.util.Random;

 

import javax.imageio.ImageIO;



public class VerifyCodeUtils {

     

    //使用到Algerian字体,系统里没有的话需要安装字体,字体只显示大写,


去掉了1,0,i,o几个容易混淆的字符

    public static final String VERIFY_CODES = 


"23456789ABCDEFGHJKLMNPQRSTUVWXYZ";

    private static Random random = new Random();

 

 

    /**

     * 使用系统默认字符源生成验证码

     * @param verifySize    验证码长度

     * @return

     */

    public static String generateVerifyCode(int verifySize){

        return generateVerifyCode(verifySize, VERIFY_CODES);

    }

    

    /**

     * 使用指定源生成验证码

     * @param verifySize    验证码长度

     * @param sources   验证码字符源

     * @return

     */

    public static String generateVerifyCode(int verifySize, String 


sources){

        if(sources == null || sources.length() == 0){

            sources = VERIFY_CODES;

        }

        int codesLen = sources.length();

        Random rand = new Random(System.currentTimeMillis());

        StringBuilder verifyCode = new StringBuilder(verifySize);

        for(int i = 0; i < verifySize; i++){

            verifyCode.append(sources.charAt(rand.nextInt(codesLen-


1)));

        }

        return verifyCode.toString();

    }

     

    /**

     * 生成随机验证码文件,并返回验证码值

     * @param w

     * @param h

     * @param outputFile

     * @param verifySize

     * @return

     * @throws IOException

     */

    public static String outputVerifyImage(int w, int h, File 


outputFile, int verifySize) throws IOException{

        String verifyCode = generateVerifyCode(verifySize);

        outputImage(w, h, outputFile, verifyCode);

        return verifyCode;

    }

     

    /**

     * 输出随机验证码图片流,并返回验证码值

     * @param w

     * @param h

     * @param os

     * @param verifySize

     * @return

     * @throws IOException

     */

    public static String outputVerifyImage(int w, int h, OutputStream 


os, int verifySize) throws IOException{

        String verifyCode = generateVerifyCode(verifySize);

        outputImage(w, h, os, verifyCode);

        return verifyCode;

    }

     

    /**

     * 生成指定验证码图像文件

     * @param w

     * @param h

     * @param outputFile

     * @param code

     * @throws IOException

     */

    public static void outputImage(int w, int h, File outputFile, 


String code) throws IOException{

        if(outputFile == null){

            return;

        }

        File dir = outputFile.getParentFile();

        if(!dir.exists()){

            dir.mkdirs();

        }

        try{

            outputFile.createNewFile();

            FileOutputStream fos = new FileOutputStream(outputFile);

            outputImage(w, h, fos, code);

            fos.close();

        } catch(IOException e){

            throw e;

        }

    }

     

    /**

     * 输出指定验证码图片流

     * @param w

     * @param h

     * @param os

     * @param code

     * @throws IOException

     */

    public static void outputImage(int w, int h, OutputStream os, 


String code) throws IOException{

        int verifySize = code.length();

        BufferedImage image = new BufferedImage(w, h, 


BufferedImage.TYPE_INT_RGB);

        Random rand = new Random();

        Graphics2D g2 = image.createGraphics();

        g2.setRenderingHint


(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);

        Color[] colors = new Color[5];

        Color[] colorSpaces = new Color[] { Color.WHITE, Color.CYAN,

                Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA, 


Color.ORANGE,

                Color.PINK, Color.YELLOW };

        float[] fractions = new float[colors.length];

        for(int i = 0; i < colors.length; i++){

            colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)];

            fractions[i] = rand.nextFloat();

        }

        Arrays.sort(fractions);

         

        g2.setColor(Color.GRAY);// 设置边框色

        g2.fillRect(0, 0, w, h);

         

        Color c = getRandColor(200, 250);

        g2.setColor(c);// 设置背景色

        g2.fillRect(0, 2, w, h-4);

         

        //绘制干扰线

        Random random = new Random();

        g2.setColor(getRandColor(160, 200));// 设置线条的颜色

        for (int i = 0; i < 20; i++) {

            int x = random.nextInt(w - 1);

            int y = random.nextInt(h - 1);

            int xl = random.nextInt(6) + 1;

            int yl = random.nextInt(12) + 1;

            g2.drawLine(x, y, x + xl + 40, y + yl + 20);

        }

         

        // 添加噪点

        float yawpRate = 0.05f;// 噪声率

        int area = (int) (yawpRate * w * h);

        for (int i = 0; i < area; i++) {

            int x = random.nextInt(w);

            int y = random.nextInt(h);

            int rgb = getRandomIntColor();

            image.setRGB(x, y, rgb);

        }

         

        shear(g2, w, h, c);// 使图片扭曲

 

        g2.setColor(getRandColor(100, 160));

        int fontSize = h-4;

        Font font = new Font("Algerian", Font.ITALIC, fontSize);

        g2.setFont(font);

        char[] chars = code.toCharArray();

        for(int i = 0; i < verifySize; i++){

            AffineTransform affine = new AffineTransform();

            affine.setToRotation(Math.PI / 4 * rand.nextDouble() * 


(rand.nextBoolean() ? 1 : -1), (w / verifySize) * i + fontSize/2, 


h/2);

            g2.setTransform(affine);

            g2.drawChars(chars, i, 1, ((w-10) / verifySize) * i + 5, 


h/2 + fontSize/2 - 10);

        }

         

        g2.dispose();

        ImageIO.write(image, "png", os);

    }

     

    private static Color getRandColor(int fc, int bc) {

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

    }

     

    private static int getRandomIntColor() {

        int[] rgb = getRandomRgb();

        int color = 0;

        for (int c : rgb) {

            color = color << 8;

            color = color | c;

        }

        return color;

    }

     

    private static int[] getRandomRgb() {

        int[] rgb = new int[3];

        for (int i = 0; i < 3; i++) {

            rgb[i] = random.nextInt(255);

        }

        return rgb;

    }

 

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


{

        shearX(g, w1, h1, color);

        shearY(g, w1, h1, color);

    }

     

    private static void shearX(Graphics g, int w1, int h1, Color 


color) {

 

        int period = random.nextInt(2);

 

        boolean borderGap = true;

        int frames = 1;

        int phase = random.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);

            }

        }

 

    }

 

    private static void shearY(Graphics g, int w1, int h1, Color 


color) {

 

        int period = random.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);

            }

 

        }

    }

    public static void main(String[] args) throws IOException{

        File dir = new File("C:/Users/H__D/Desktop/");

        int w = 200, h = 80;

        String verifyCode = generateVerifyCode(4);

        File file = new File(dir, verifyCode + ".jpg");

        outputImage(w, h, file, verifyCode);

    }

}

 


使用图形验证码

 


1、使用流程


 


技术图片


 


2、服务器端生成验证码servlet


package com.servlet;


import java.io.IOException;


import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;


import com.util.VerifyCodeUtils;



public class CreateCodeServlet extends HttpServlet {

    

    

    @Override

    protected void doGet(HttpServletRequest req, HttpServletResponse 


resp) throws ServletException, IOException {

        resp.setHeader("Pragma", "No-cache");  

        resp.setHeader("Cache-Control", "no-cache");  

        resp.setDateHeader("Expires", 0);  

        resp.setContentType("image/jpeg");  

          

        //生成随机字串  

        String verifyCode = VerifyCodeUtils.generateVerifyCode(4);  

        //存入会话session  

        req.getSession().setAttribute("CODE", verifyCode.toLowerCase


());  

        

        //生成图片  

        int width = 100;//宽

        int height = 40;//高  

        VerifyCodeUtils.outputImage(width, height, 


resp.getOutputStream(), verifyCode);  

        

    }

    

    @Override

    protected void doPost(HttpServletRequest req, HttpServletResponse 


resp) throws ServletException, IOException {

        // TODO Auto-generated method stub

        doGet(req, resp);

    }

}

3、服务器端验证验证码servlet


 


package com.servlet;


import java.io.IOException;


import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;


import com.util.VerifyCodeUtils;



public class VerifyCodeServlet extends HttpServlet {

    

    

    @Override

    protected void doGet(HttpServletRequest req, HttpServletResponse 


resp) throws ServletException, IOException {

        

        String code = req.getParameter("code");

        String key = (String) req.getSession().getAttribute("CODE");

        if(code != null && code.equalsIgnoreCase(key)){

            req.getSession().removeAttribute("CODE");

            resp.getWriter().println(true);

        }else{

            resp.getWriter().println(false);

        }

    }

    

    @Override

    protected void doPost(HttpServletRequest req, HttpServletResponse 


resp) throws ServletException, IOException {

        // TODO Auto-generated method stub

        super.doGet(req, resp);

    }

}

4、servet的注册,web.xml文件


<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="http://生成验证码工具类

package com.util;


import java.awt.Color;

import java.awt.Font;

import java.awt.Graphics;

import java.awt.Graphics2D;

import java.awt.RenderingHints;

import java.awt.geom.AffineTransform;

import java.awt.image.BufferedImage;

import java.io.File;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.OutputStream;

import java.util.Arrays;

import java.util.Random;

 

import javax.imageio.ImageIO;



public class VerifyCodeUtils {

     

    //使用到Algerian字体,系统里没有的话需要安装字体,字体只显示大写,


去掉了1,0,i,o几个容易混淆的字符

    public static final String VERIFY_CODES = 


"23456789ABCDEFGHJKLMNPQRSTUVWXYZ";

    private static Random random = new Random();

 

 

    /**

     * 使用系统默认字符源生成验证码

     * @param verifySize    验证码长度

     * @return

     */

    public static String generateVerifyCode(int verifySize){

        return generateVerifyCode(verifySize, VERIFY_CODES);

    }

    

    /**

     * 使用指定源生成验证码

     * @param verifySize    验证码长度

     * @param sources   验证码字符源

     * @return

     */

    public static String generateVerifyCode(int verifySize, String 


sources){

        if(sources == null || sources.length() == 0){

            sources = VERIFY_CODES;

        }

        int codesLen = sources.length();

        Random rand = new Random(System.currentTimeMillis());

        StringBuilder verifyCode = new StringBuilder(verifySize);

        for(int i = 0; i < verifySize; i++){

            verifyCode.append(sources.charAt(rand.nextInt(codesLen-


1)));

        }

        return verifyCode.toString();

    }

     

    /**

     * 生成随机验证码文件,并返回验证码值

     * @param w

     * @param h

     * @param outputFile

     * @param verifySize

     * @return

     * @throws IOException

     */

    public static String outputVerifyImage(int w, int h, File 


outputFile, int verifySize) throws IOException{

        String verifyCode = generateVerifyCode(verifySize);

        outputImage(w, h, outputFile, verifyCode);

        return verifyCode;

    }

     

    /**

     * 输出随机验证码图片流,并返回验证码值

     * @param w

     * @param h

     * @param os

     * @param verifySize

     * @return

     * @throws IOException

     */

    public static String outputVerifyImage(int w, int h, OutputStream 


os, int verifySize) throws IOException{

        String verifyCode = generateVerifyCode(verifySize);

        outputImage(w, h, os, verifyCode);

        return verifyCode;

    }

     

    /**

     * 生成指定验证码图像文件

     * @param w

     * @param h

     * @param outputFile

     * @param code

     * @throws IOException

     */

    public static void outputImage(int w, int h, File outputFile, 


String code) throws IOException{

        if(outputFile == null){

            return;

        }

        File dir = outputFile.getParentFile();

        if(!dir.exists()){

            dir.mkdirs();

        }

        try{

            outputFile.createNewFile();

            FileOutputStream fos = new FileOutputStream(outputFile);

            outputImage(w, h, fos, code);

            fos.close();

        } catch(IOException e){

            throw e;

        }

    }

     

    /**

     * 输出指定验证码图片流

     * @param w

     * @param h

     * @param os

     * @param code

     * @throws IOException

     */

    public static void outputImage(int w, int h, OutputStream os, 


String code) throws IOException{

        int verifySize = code.length();

        BufferedImage image = new BufferedImage(w, h, 


BufferedImage.TYPE_INT_RGB);

        Random rand = new Random();

        Graphics2D g2 = image.createGraphics();

        g2.setRenderingHint


(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);

        Color[] colors = new Color[5];

        Color[] colorSpaces = new Color[] { Color.WHITE, Color.CYAN,

                Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA, 


Color.ORANGE,

                Color.PINK, Color.YELLOW };

        float[] fractions = new float[colors.length];

        for(int i = 0; i < colors.length; i++){

            colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)];

            fractions[i] = rand.nextFloat();

        }

        Arrays.sort(fractions);

         

        g2.setColor(Color.GRAY);// 设置边框色

        g2.fillRect(0, 0, w, h);

         

        Color c = getRandColor(200, 250);

        g2.setColor(c);// 设置背景色

        g2.fillRect(0, 2, w, h-4);

         

        //绘制干扰线

        Random random = new Random();

        g2.setColor(getRandColor(160, 200));// 设置线条的颜色

        for (int i = 0; i < 20; i++) {

            int x = random.nextInt(w - 1);

            int y = random.nextInt(h - 1);

            int xl = random.nextInt(6) + 1;

            int yl = random.nextInt(12) + 1;

            g2.drawLine(x, y, x + xl + 40, y + yl + 20);

        }

         

        // 添加噪点

        float yawpRate = 0.05f;// 噪声率

        int area = (int) (yawpRate * w * h);

        for (int i = 0; i < area; i++) {

            int x = random.nextInt(w);

            int y = random.nextInt(h);

            int rgb = getRandomIntColor();

            image.setRGB(x, y, rgb);

        }

         

        shear(g2, w, h, c);// 使图片扭曲

 

        g2.setColor(getRandColor(100, 160));

        int fontSize = h-4;

        Font font = new Font("Algerian", Font.ITALIC, fontSize);

        g2.setFont(font);

        char[] chars = code.toCharArray();

        for(int i = 0; i < verifySize; i++){

            AffineTransform affine = new AffineTransform();

            affine.setToRotation(Math.PI / 4 * rand.nextDouble() * 


(rand.nextBoolean() ? 1 : -1), (w / verifySize) * i + fontSize/2, 


h/2);

            g2.setTransform(affine);

            g2.drawChars(chars, i, 1, ((w-10) / verifySize) * i + 5, 


h/2 + fontSize/2 - 10);

        }

         

        g2.dispose();

        ImageIO.write(image, "png", os);

    }

     

    private static Color getRandColor(int fc, int bc) {

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

    }

     

    private static int getRandomIntColor() {

        int[] rgb = getRandomRgb();

        int color = 0;

        for (int c : rgb) {

            color = color << 8;

            color = color | c;

        }

        return color;

    }

     

    private static int[] getRandomRgb() {

        int[] rgb = new int[3];

        for (int i = 0; i < 3; i++) {

            rgb[i] = random.nextInt(255);

        }

        return rgb;

    }

 

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


{

        shearX(g, w1, h1, color);

        shearY(g, w1, h1, color);

    }

     

    private static void shearX(Graphics g, int w1, int h1, Color 


color) {

 

        int period = random.nextInt(2);

 

        boolean borderGap = true;

        int frames = 1;

        int phase = random.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);

            }

        }

 

    }

 

    private static void shearY(Graphics g, int w1, int h1, Color 


color) {

 

        int period = random.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);

            }

 

        }

    }

    public static void main(String[] args) throws IOException{

        File dir = new File("C:/Users/H__D/Desktop/");

        int w = 200, h = 80;

        String verifyCode = generateVerifyCode(4);

        File file = new File(dir, verifyCode + ".jpg");

        outputImage(w, h, file, verifyCode);

    }

}

 


使用图形验证码

 


1、使用流程


 


技术图片


 


2、服务器端生成验证码servlet


package com.servlet;


import java.io.IOException;


import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;


import com.util.VerifyCodeUtils;



public class CreateCodeServlet extends HttpServlet {

    

    

    @Override

    protected void doGet(HttpServletRequest req, HttpServletResponse 


resp) throws ServletException, IOException {

        resp.setHeader("Pragma", "No-cache");  

        resp.setHeader("Cache-Control", "no-cache");  

        resp.setDateHeader("Expires", 0);  

        resp.setContentType("image/jpeg");  

          

        //生成随机字串  

        String verifyCode = VerifyCodeUtils.generateVerifyCode(4);  

        //存入会话session  

        req.getSession().setAttribute("CODE", verifyCode.toLowerCase


());  

        

        //生成图片  

        int width = 100;//宽

        int height = 40;//高  

        VerifyCodeUtils.outputImage(width, height, 


resp.getOutputStream(), verifyCode);  

        

    }

    

    @Override

    protected void doPost(HttpServletRequest req, HttpServletResponse 


resp) throws ServletException, IOException {

        // TODO Auto-generated method stub

        doGet(req, resp);

    }

}

3、服务器端验证验证码servlet


 


package com.servlet;


import java.io.IOException;


import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;


import com.util.VerifyCodeUtils;



public class VerifyCodeServlet extends HttpServlet {

    

    

    @Override

    protected void doGet(HttpServletRequest req, HttpServletResponse 


resp) throws ServletException, IOException {

        

        String code = req.getParameter("code");

        String key = (String) req.getSession().getAttribute("CODE");

        if(code != null && code.equalsIgnoreCase(key)){

            req.getSession().removeAttribute("CODE");

            resp.getWriter().println(true);

        }else{

            resp.getWriter().println(false);

        }

    }

    

    @Override

    protected void doPost(HttpServletRequest req, HttpServletResponse 


resp) throws ServletException, IOException {

        // TODO Auto-generated method stub

        super.doGet(req, resp);

    }

}

4、servet的注册,web.xml文件


<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="http://www.-instance" 


xmlns="http://java./xml/ns/javaee" 


xsi:schemaLocation="http://java./xml/ns/javaee 


http://java./xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" 


version="3.0">

  <display-name>test-captcha</display-name>

  

  

  <servlet>

      <servlet-name>CreateCodeServlet</servlet-name>

      <servlet-class>com.servlet.CreateCodeServlet</servlet-class>

  </servlet>

  <servlet-mapping>

      <servlet-name>CreateCodeServlet</servlet-name>

      <url-pattern>/createCode</url-pattern>

  </servlet-mapping>

  

   <servlet>

      <servlet-name>VerifyCodeServlet</servlet-name>

      <servlet-class>com.servlet.VerifyCodeServlet</servlet-class>

  </servlet>

  <servlet-mapping>

      <servlet-name>VerifyCodeServlet</servlet-name>

      <url-pattern>/verifyCode</url-pattern>

  </servlet-mapping>


  

  <welcome-file-list>

    <welcome-file>index.jsp</welcome-file>

  </welcome-file-list>

</web-app>

 


5、前端html文件


<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//深圳市博纳网络信息技术有限公司//DTD HTML 4.01 Transitional//EN" 


"http://生成验证码工具类

package com.util;


import java.awt.Color;

import java.awt.Font;

import java.awt.Graphics;

import java.awt.Graphics2D;

import java.awt.RenderingHints;

import java.awt.geom.AffineTransform;

import java.awt.image.BufferedImage;

import java.io.File;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.OutputStream;

import java.util.Arrays;

import java.util.Random;

 

import javax.imageio.ImageIO;



public class VerifyCodeUtils {

     

    //使用到Algerian字体,系统里没有的话需要安装字体,字体只显示大写,


去掉了1,0,i,o几个容易混淆的字符

    public static final String VERIFY_CODES = 


"23456789ABCDEFGHJKLMNPQRSTUVWXYZ";

    private static Random random = new Random();

 

 

    /**

     * 使用系统默认字符源生成验证码

     * @param verifySize    验证码长度

     * @return

     */

    public static String generateVerifyCode(int verifySize){

        return generateVerifyCode(verifySize, VERIFY_CODES);

    }

    

    /**

     * 使用指定源生成验证码

     * @param verifySize    验证码长度

     * @param sources   验证码字符源

     * @return

     */

    public static String generateVerifyCode(int verifySize, String 


sources){

        if(sources == null || sources.length() == 0){

            sources = VERIFY_CODES;

        }

        int codesLen = sources.length();

        Random rand = new Random(System.currentTimeMillis());

        StringBuilder verifyCode = new StringBuilder(verifySize);

        for(int i = 0; i < verifySize; i++){

            verifyCode.append(sources.charAt(rand.nextInt(codesLen-


1)));

        }

        return verifyCode.toString();

    }

     

    /**

     * 生成随机验证码文件,并返回验证码值

     * @param w

     * @param h

     * @param outputFile

     * @param verifySize

     * @return

     * @throws IOException

     */

    public static String outputVerifyImage(int w, int h, File 


outputFile, int verifySize) throws IOException{

        String verifyCode = generateVerifyCode(verifySize);

        outputImage(w, h, outputFile, verifyCode);

        return verifyCode;

    }

     

    /**

     * 输出随机验证码图片流,并返回验证码值

     * @param w

     * @param h

     * @param os

     * @param verifySize

     * @return

     * @throws IOException

     */

    public static String outputVerifyImage(int w, int h, OutputStream 


os, int verifySize) throws IOException{

        String verifyCode = generateVerifyCode(verifySize);

        outputImage(w, h, os, verifyCode);

        return verifyCode;

    }

     

    /**

     * 生成指定验证码图像文件

     * @param w

     * @param h

     * @param outputFile

     * @param code

     * @throws IOException

     */

    public static void outputImage(int w, int h, File outputFile, 


String code) throws IOException{

        if(outputFile == null){

            return;

        }

        File dir = outputFile.getParentFile();

        if(!dir.exists()){

            dir.mkdirs();

        }

        try{

            outputFile.createNewFile();

            FileOutputStream fos = new FileOutputStream(outputFile);

            outputImage(w, h, fos, code);

            fos.close();

        } catch(IOException e){

            throw e;

        }

    }

     

    /**

     * 输出指定验证码图片流

     * @param w

     * @param h

     * @param os

     * @param code

     * @throws IOException

     */

    public static void outputImage(int w, int h, OutputStream os, 


String code) throws IOException{

        int verifySize = code.length();

        BufferedImage image = new BufferedImage(w, h, 


BufferedImage.TYPE_INT_RGB);

        Random rand = new Random();

        Graphics2D g2 = image.createGraphics();

        g2.setRenderingHint


(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);

        Color[] colors = new Color[5];

        Color[] colorSpaces = new Color[] { Color.WHITE, Color.CYAN,

                Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA, 


Color.ORANGE,

                Color.PINK, Color.YELLOW };

        float[] fractions = new float[colors.length];

        for(int i = 0; i < colors.length; i++){

            colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)];

            fractions[i] = rand.nextFloat();

        }

        Arrays.sort(fractions);

         

        g2.setColor(Color.GRAY);// 设置边框色

        g2.fillRect(0, 0, w, h);

         

        Color c = getRandColor(200, 250);

        g2.setColor(c);// 设置背景色

        g2.fillRect(0, 2, w, h-4);

         

        //绘制干扰线

        Random random = new Random();

        g2.setColor(getRandColor(160, 200));// 设置线条的颜色

        for (int i = 0; i < 20; i++) {

            int x = random.nextInt(w - 1);

            int y = random.nextInt(h - 1);

            int xl = random.nextInt(6) + 1;

            int yl = random.nextInt(12) + 1;

            g2.drawLine(x, y, x + xl + 40, y + yl + 20);

        }

         

        // 添加噪点

        float yawpRate = 0.05f;// 噪声率

        int area = (int) (yawpRate * w * h);

        for (int i = 0; i < area; i++) {

            int x = random.nextInt(w);

            int y = random.nextInt(h);

            int rgb = getRandomIntColor();

            image.setRGB(x, y, rgb);

        }

         

        shear(g2, w, h, c);// 使图片扭曲

 

        g2.setColor(getRandColor(100, 160));

        int fontSize = h-4;

        Font font = new Font("Algerian", Font.ITALIC, fontSize);

        g2.setFont(font);

        char[] chars = code.toCharArray();

        for(int i = 0; i < verifySize; i++){

            AffineTransform affine = new AffineTransform();

            affine.setToRotation(Math.PI / 4 * rand.nextDouble() * 


(rand.nextBoolean() ? 1 : -1), (w / verifySize) * i + fontSize/2, 


h/2);

            g2.setTransform(affine);

            g2.drawChars(chars, i, 1, ((w-10) / verifySize) * i + 5, 


h/2 + fontSize/2 - 10);

        }

         

        g2.dispose();

        ImageIO.write(image, "png", os);

    }

     

    private static Color getRandColor(int fc, int bc) {

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

    }

     

    private static int getRandomIntColor() {

        int[] rgb = getRandomRgb();

        int color = 0;

        for (int c : rgb) {

            color = color << 8;

            color = color | c;

        }

        return color;

    }

     

    private static int[] getRandomRgb() {

        int[] rgb = new int[3];

        for (int i = 0; i < 3; i++) {

            rgb[i] = random.nextInt(255);

        }

        return rgb;

    }

 

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


{

        shearX(g, w1, h1, color);

        shearY(g, w1, h1, color);

    }

     

    private static void shearX(Graphics g, int w1, int h1, Color 


color) {

 

        int period = random.nextInt(2);

 

        boolean borderGap = true;

        int frames = 1;

        int phase = random.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);

            }

        }

 

    }

 

    private static void shearY(Graphics g, int w1, int h1, Color 


color) {

 

        int period = random.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);

            }

 

        }

    }

    public static void main(String[] args) throws IOException{

        File dir = new File("C:/Users/H__D/Desktop/");

        int w = 200, h = 80;

        String verifyCode = generateVerifyCode(4);

        File file = new File(dir, verifyCode + ".jpg");

        outputImage(w, h, file, verifyCode);

    }

}

 


使用图形验证码

 


1、使用流程


 


技术图片


 


2、服务器端生成验证码servlet


package com.servlet;


import java.io.IOException;


import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;


import com.util.VerifyCodeUtils;



public class CreateCodeServlet extends HttpServlet {

    

    

    @Override

    protected void doGet(HttpServletRequest req, HttpServletResponse 


resp) throws ServletException, IOException {

        resp.setHeader("Pragma", "No-cache");  

        resp.setHeader("Cache-Control", "no-cache");  

        resp.setDateHeader("Expires", 0);  

        resp.setContentType("image/jpeg");  

          

        //生成随机字串  

        String verifyCode = VerifyCodeUtils.generateVerifyCode(4);  

        //存入会话session  

        req.getSession().setAttribute("CODE", verifyCode.toLowerCase


());  

        

        //生成图片  

        int width = 100;//宽

        int height = 40;//高  

        VerifyCodeUtils.outputImage(width, height, 


resp.getOutputStream(), verifyCode);  

        

    }

    

    @Override

    protected void doPost(HttpServletRequest req, HttpServletResponse 


resp) throws ServletException, IOException {

        // TODO Auto-generated method stub

        doGet(req, resp);

    }

}

3、服务器端验证验证码servlet


 


package com.servlet;


import java.io.IOException;


import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;


import com.util.VerifyCodeUtils;



public class VerifyCodeServlet extends HttpServlet {

    

    

    @Override

    protected void doGet(HttpServletRequest req, HttpServletResponse 


resp) throws ServletException, IOException {

        

        String code = req.getParameter("code");

        String key = (String) req.getSession().getAttribute("CODE");

        if(code != null && code.equalsIgnoreCase(key)){

            req.getSession().removeAttribute("CODE");

            resp.getWriter().println(true);

        }else{

            resp.getWriter().println(false);

        }

    }

    

    @Override

    protected void doPost(HttpServletRequest req, HttpServletResponse 


resp) throws ServletException, IOException {

        // TODO Auto-generated method stub

        super.doGet(req, resp);

    }

}

4、servet的注册,web.xml文件


<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="http://www.-instance" 


xmlns="http://java./xml/ns/javaee" 


xsi:schemaLocation="http://java./xml/ns/javaee 


http://java./xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" 


version="3.0">

  <display-name>test-captcha</display-name>

  

  

  <servlet>

      <servlet-name>CreateCodeServlet</servlet-name>

      <servlet-class>com.servlet.CreateCodeServlet</servlet-class>

  </servlet>

  <servlet-mapping>

      <servlet-name>CreateCodeServlet</servlet-name>

      <url-pattern>/createCode</url-pattern>

  </servlet-mapping>

  

   <servlet>

      <servlet-name>VerifyCodeServlet</servlet-name>

      <servlet-class>com.servlet.VerifyCodeServlet</servlet-class>

  </servlet>

  <servlet-mapping>

      <servlet-name>VerifyCodeServlet</servlet-name>

      <url-pattern>/verifyCode</url-pattern>

  </servlet-mapping>


  

  <welcome-file-list>

    <welcome-file>index.jsp</welcome-file>

  </welcome-file-list>

</web-app>

 


5、前端html文件


<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//深圳市博纳网络信息技术有限公司//DTD HTML 4.01 Transitional//EN" 


"http://生成验证码工具类

package com.util;


import java.awt.Color;

import java.awt.Font;

import java.awt.Graphics;

import java.awt.Graphics2D;

import java.awt.RenderingHints;

import java.awt.geom.AffineTransform;

import java.awt.image.BufferedImage;

import java.io.File;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.OutputStream;

import java.util.Arrays;

import java.util.Random;

 

import javax.imageio.ImageIO;



public class VerifyCodeUtils {

     

    //使用到Algerian字体,系统里没有的话需要安装字体,字体只显示大写,


去掉了1,0,i,o几个容易混淆的字符

    public static final String VERIFY_CODES = 


"23456789ABCDEFGHJKLMNPQRSTUVWXYZ";

    private static Random random = new Random();

 

 

    /**

     * 使用系统默认字符源生成验证码

     * @param verifySize    验证码长度

     * @return

     */

    public static String generateVerifyCode(int verifySize){

        return generateVerifyCode(verifySize, VERIFY_CODES);

    }

    

    /**

     * 使用指定源生成验证码

     * @param verifySize    验证码长度

     * @param sources   验证码字符源

     * @return

     */

    public static String generateVerifyCode(int verifySize, String 


sources){

        if(sources == null || sources.length() == 0){

            sources = VERIFY_CODES;

        }

        int codesLen = sources.length();

        Random rand = new Random(System.currentTimeMillis());

        StringBuilder verifyCode = new StringBuilder(verifySize);

        for(int i = 0; i < verifySize; i++){

            verifyCode.append(sources.charAt(rand.nextInt(codesLen-


1)));

        }

        return verifyCode.toString();

    }

     

    /**

     * 生成随机验证码文件,并返回验证码值

     * @param w

     * @param h

     * @param outputFile

     * @param verifySize

     * @return

     * @throws IOException

     */

    public static String outputVerifyImage(int w, int h, File 


outputFile, int verifySize) throws IOException{

        String verifyCode = generateVerifyCode(verifySize);

        outputImage(w, h, outputFile, verifyCode);

        return verifyCode;

    }

     

    /**

     * 输出随机验证码图片流,并返回验证码值

     * @param w

     * @param h

     * @param os

     * @param verifySize

     * @return

     * @throws IOException

     */

    public static String outputVerifyImage(int w, int h, OutputStream 


os, int verifySize) throws IOException{

        String verifyCode = generateVerifyCode(verifySize);

        outputImage(w, h, os, verifyCode);

        return verifyCode;

    }

     

    /**

     * 生成指定验证码图像文件

     * @param w

     * @param h

     * @param outputFile

     * @param code

     * @throws IOException

     */

    public static void outputImage(int w, int h, File outputFile, 


String code) throws IOException{

        if(outputFile == null){

            return;

        }

        File dir = outputFile.getParentFile();

        if(!dir.exists()){

            dir.mkdirs();

        }

        try{

            outputFile.createNewFile();

            FileOutputStream fos = new FileOutputStream(outputFile);

            outputImage(w, h, fos, code);

            fos.close();

        } catch(IOException e){

            throw e;

        }

    }

     

    /**

     * 输出指定验证码图片流

     * @param w

     * @param h

     * @param os

     * @param code

     * @throws IOException

     */

    public static void outputImage(int w, int h, OutputStream os, 


String code) throws IOException{

        int verifySize = code.length();

        BufferedImage image = new BufferedImage(w, h, 


BufferedImage.TYPE_INT_RGB);

        Random rand = new Random();

        Graphics2D g2 = image.createGraphics();

        g2.setRenderingHint


(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);

        Color[] colors = new Color[5];

        Color[] colorSpaces = new Color[] { Color.WHITE, Color.CYAN,

                Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA, 


Color.ORANGE,

                Color.PINK, Color.YELLOW };

        float[] fractions = new float[colors.length];

        for(int i = 0; i < colors.length; i++){

            colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)];

            fractions[i] = rand.nextFloat();

        }

        Arrays.sort(fractions);

         

        g2.setColor(Color.GRAY);// 设置边框色

        g2.fillRect(0, 0, w, h);

         

        Color c = getRandColor(200, 250);

        g2.setColor(c);// 设置背景色

        g2.fillRect(0, 2, w, h-4);

         

        //绘制干扰线

        Random random = new Random();

        g2.setColor(getRandColor(160, 200));// 设置线条的颜色

        for (int i = 0; i < 20; i++) {

            int x = random.nextInt(w - 1);

            int y = random.nextInt(h - 1);

            int xl = random.nextInt(6) + 1;

            int yl = random.nextInt(12) + 1;

            g2.drawLine(x, y, x + xl + 40, y + yl + 20);

        }

         

        // 添加噪点

        float yawpRate = 0.05f;// 噪声率

        int area = (int) (yawpRate * w * h);

        for (int i = 0; i < area; i++) {

            int x = random.nextInt(w);

            int y = random.nextInt(h);

            int rgb = getRandomIntColor();

            image.setRGB(x, y, rgb);

        }

         

        shear(g2, w, h, c);// 使图片扭曲

 

        g2.setColor(getRandColor(100, 160));

        int fontSize = h-4;

        Font font = new Font("Algerian", Font.ITALIC, fontSize);

        g2.setFont(font);

        char[] chars = code.toCharArray();

        for(int i = 0; i < verifySize; i++){

            AffineTransform affine = new AffineTransform();

            affine.setToRotation(Math.PI / 4 * rand.nextDouble() * 


(rand.nextBoolean() ? 1 : -1), (w / verifySize) * i + fontSize/2, 


h/2);

            g2.setTransform(affine);

            g2.drawChars(chars, i, 1, ((w-10) / verifySize) * i + 5, 


h/2 + fontSize/2 - 10);

        }

         

        g2.dispose();

        ImageIO.write(image, "png", os);

    }

     

    private static Color getRandColor(int fc, int bc) {

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

    }

     

    private static int getRandomIntColor() {

        int[] rgb = getRandomRgb();

        int color = 0;

        for (int c : rgb) {

            color = color << 8;

            color = color | c;

        }

        return color;

    }

     

    private static int[] getRandomRgb() {

        int[] rgb = new int[3];

        for (int i = 0; i < 3; i++) {

            rgb[i] = random.nextInt(255);

        }

        return rgb;

    }

 

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


{

        shearX(g, w1, h1, color);

        shearY(g, w1, h1, color);

    }

     

    private static void shearX(Graphics g, int w1, int h1, Color 


color) {

 

        int period = random.nextInt(2);

 

        boolean borderGap = true;

        int frames = 1;

        int phase = random.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);

            }

        }

 

    }

 

    private static void shearY(Graphics g, int w1, int h1, Color 


color) {

 

        int period = random.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);

            }

 

        }

    }

    public static void main(String[] args) throws IOException{

        File dir = new File("C:/Users/H__D/Desktop/");

        int w = 200, h = 80;

        String verifyCode = generateVerifyCode(4);

        File file = new File(dir, verifyCode + ".jpg");

        outputImage(w, h, file, verifyCode);

    }

}

 


使用图形验证码

 


1、使用流程


 


技术图片


 


2、服务器端生成验证码servlet


package com.servlet;


import java.io.IOException;


import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;


import com.util.VerifyCodeUtils;



public class CreateCodeServlet extends HttpServlet {

    

    

    @Override

    protected void doGet(HttpServletRequest req, HttpServletResponse 


resp) throws ServletException, IOException {

        resp.setHeader("Pragma", "No-cache");  

        resp.setHeader("Cache-Control", "no-cache");  

        resp.setDateHeader("Expires", 0);  

        resp.setContentType("image/jpeg");  

          

        //生成随机字串  

        String verifyCode = VerifyCodeUtils.generateVerifyCode(4);  

        //存入会话session  

        req.getSession().setAttribute("CODE", verifyCode.toLowerCase


());  

        

        //生成图片  

        int width = 100;//宽

        int height = 40;//高  

        VerifyCodeUtils.outputImage(width, height, 


resp.getOutputStream(), verifyCode);  

        

    }

    

    @Override

    protected void doPost(HttpServletRequest req, HttpServletResponse 


resp) throws ServletException, IOException {

        // TODO Auto-generated method stub

        doGet(req, resp);

    }

}

3、服务器端验证验证码servlet


 


package com.servlet;


import java.io.IOException;


import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;


import com.util.VerifyCodeUtils;



public class VerifyCodeServlet extends HttpServlet {

    

    

    @Override

    protected void doGet(HttpServletRequest req, HttpServletResponse 


resp) throws ServletException, IOException {

        

        String code = req.getParameter("code");

        String key = (String) req.getSession().getAttribute("CODE");

        if(code != null && code.equalsIgnoreCase(key)){

            req.getSession().removeAttribute("CODE");

            resp.getWriter().println(true);

        }else{

            resp.getWriter().println(false);

        }

    }

    

    @Override

    protected void doPost(HttpServletRequest req, HttpServletResponse 


resp) throws ServletException, IOException {

        // TODO Auto-generated method stub

        super.doGet(req, resp);

    }

}

4、servet的注册,web.xml文件


<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="http://生成验证码工具类

package com.util;


import java.awt.Color;

import java.awt.Font;

import java.awt.Graphics;

import java.awt.Graphics2D;

import java.awt.RenderingHints;

import java.awt.geom.AffineTransform;

import java.awt.image.BufferedImage;

import java.io.File;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.OutputStream;

import java.util.Arrays;

import java.util.Random;

 

import javax.imageio.ImageIO;



public class VerifyCodeUtils {

     

    //使用到Algerian字体,系统里没有的话需要安装字体,字体只显示大写,


去掉了1,0,i,o几个容易混淆的字符

    public static final String VERIFY_CODES = 


"23456789ABCDEFGHJKLMNPQRSTUVWXYZ";

    private static Random random = new Random();

 

 

    /**

     * 使用系统默认字符源生成验证码

     * @param verifySize    验证码长度

     * @return

     */

    public static String generateVerifyCode(int verifySize){

        return generateVerifyCode(verifySize, VERIFY_CODES);

    }

    

    /**

     * 使用指定源生成验证码

     * @param verifySize    验证码长度

     * @param sources   验证码字符源

     * @return

     */

    public static String generateVerifyCode(int verifySize, String 


sources){

        if(sources == null || sources.length() == 0){

            sources = VERIFY_CODES;

        }

        int codesLen = sources.length();

        Random rand = new Random(System.currentTimeMillis());

        StringBuilder verifyCode = new StringBuilder(verifySize);

        for(int i = 0; i < verifySize; i++){

            verifyCode.append(sources.charAt(rand.nextInt(codesLen-


1)));

        }

        return verifyCode.toString();

    }

     

    /**

     * 生成随机验证码文件,并返回验证码值

     * @param w

     * @param h

     * @param outputFile

     * @param verifySize

     * @return

     * @throws IOException

     */

    public static String outputVerifyImage(int w, int h, File 


outputFile, int verifySize) throws IOException{

        String verifyCode = generateVerifyCode(verifySize);

        outputImage(w, h, outputFile, verifyCode);

        return verifyCode;

    }

     

    /**

     * 输出随机验证码图片流,并返回验证码值

     * @param w

     * @param h

     * @param os

     * @param verifySize

     * @return

     * @throws IOException

     */

    public static String outputVerifyImage(int w, int h, OutputStream 


os, int verifySize) throws IOException{

        String verifyCode = generateVerifyCode(verifySize);

        outputImage(w, h, os, verifyCode);

        return verifyCode;

    }

     

    /**

     * 生成指定验证码图像文件

     * @param w

     * @param h

     * @param outputFile

     * @param code

     * @throws IOException

     */

    public static void outputImage(int w, int h, File outputFile, 


String code) throws IOException{

        if(outputFile == null){

            return;

        }

        File dir = outputFile.getParentFile();

        if(!dir.exists()){

            dir.mkdirs();

        }

        try{

            outputFile.createNewFile();

            FileOutputStream fos = new FileOutputStream(outputFile);

            outputImage(w, h, fos, code);

            fos.close();

        } catch(IOException e){

            throw e;

        }

    }

     

    /**

     * 输出指定验证码图片流

     * @param w

     * @param h

     * @param os

     * @param code

     * @throws IOException

     */

    public static void outputImage(int w, int h, OutputStream os, 


String code) throws IOException{

        int verifySize = code.length();

        BufferedImage image = new BufferedImage(w, h, 


BufferedImage.TYPE_INT_RGB);

        Random rand = new Random();

        Graphics2D g2 = image.createGraphics();

        g2.setRenderingHint


(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);

        Color[] colors = new Color[5];

        Color[] colorSpaces = new Color[] { Color.WHITE, Color.CYAN,

                Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA, 


Color.ORANGE,

                Color.PINK, Color.YELLOW };

        float[] fractions = new float[colors.length];

        for(int i = 0; i < colors.length; i++){

            colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)];

            fractions[i] = rand.nextFloat();

        }

        Arrays.sort(fractions);

         

        g2.setColor(Color.GRAY);// 设置边框色

        g2.fillRect(0, 0, w, h);

         

        Color c = getRandColor(200, 250);

        g2.setColor(c);// 设置背景色

        g2.fillRect(0, 2, w, h-4);

         

        //绘制干扰线

        Random random = new Random();

        g2.setColor(getRandColor(160, 200));// 设置线条的颜色

        for (int i = 0; i < 20; i++) {

            int x = random.nextInt(w - 1);

            int y = random.nextInt(h - 1);

            int xl = random.nextInt(6) + 1;

            int yl = random.nextInt(12) + 1;

            g2.drawLine(x, y, x + xl + 40, y + yl + 20);

        }

         

        // 添加噪点

        float yawpRate = 0.05f;// 噪声率

        int area = (int) (yawpRate * w * h);

        for (int i = 0; i < area; i++) {

            int x = random.nextInt(w);

            int y = random.nextInt(h);

            int rgb = getRandomIntColor();

            image.setRGB(x, y, rgb);

        }

         

        shear(g2, w, h, c);// 使图片扭曲

 

        g2.setColor(getRandColor(100, 160));

        int fontSize = h-4;

        Font font = new Font("Algerian", Font.ITALIC, fontSize);

        g2.setFont(font);

        char[] chars = code.toCharArray();

        for(int i = 0; i < verifySize; i++){

            AffineTransform affine = new AffineTransform();

            affine.setToRotation(Math.PI / 4 * rand.nextDouble() * 


(rand.nextBoolean() ? 1 : -1), (w / verifySize) * i + fontSize/2, 


h/2);

            g2.setTransform(affine);

            g2.drawChars(chars, i, 1, ((w-10) / verifySize) * i + 5, 


h/2 + fontSize/2 - 10);

        }

         

        g2.dispose();

        ImageIO.write(image, "png", os);

    }

     

    private static Color getRandColor(int fc, int bc) {

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

    }

     

    private static int getRandomIntColor() {

        int[] rgb = getRandomRgb();

        int color = 0;

        for (int c : rgb) {

            color = color << 8;

            color = color | c;

        }

        return color;

    }

     

    private static int[] getRandomRgb() {

        int[] rgb = new int[3];

        for (int i = 0; i < 3; i++) {

            rgb[i] = random.nextInt(255);

        }

        return rgb;

    }

 

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


{

        shearX(g, w1, h1, color);

        shearY(g, w1, h1, color);

    }

     

    private static void shearX(Graphics g, int w1, int h1, Color 


color) {

 

        int period = random.nextInt(2);

 

        boolean borderGap = true;

        int frames = 1;

        int phase = random.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);

            }

        }

 

    }

 

    private static void shearY(Graphics g, int w1, int h1, Color 


color) {

 

        int period = random.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);

            }

 

        }

    }

    public static void main(String[] args) throws IOException{

        File dir = new File("C:/Users/H__D/Desktop/");

        int w = 200, h = 80;

        String verifyCode = generateVerifyCode(4);

        File file = new File(dir, verifyCode + ".jpg");

        outputImage(w, h, file, verifyCode);

    }

}

 


使用图形验证码

 


1、使用流程


 


技术图片


 


2、服务器端生成验证码servlet


package com.servlet;


import java.io.IOException;


import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;


import com.util.VerifyCodeUtils;



public class CreateCodeServlet extends HttpServlet {

    

    

    @Override

    protected void doGet(HttpServletRequest req, HttpServletResponse 


resp) throws ServletException, IOException {

        resp.setHeader("Pragma", "No-cache");  

        resp.setHeader("Cache-Control", "no-cache");  

        resp.setDateHeader("Expires", 0);  

        resp.setContentType("image/jpeg");  

          

        //生成随机字串  

        String verifyCode = VerifyCodeUtils.generateVerifyCode(4);  

        //存入会话session  

        req.getSession().setAttribute("CODE", verifyCode.toLowerCase


());  

        

        //生成图片  

        int width = 100;//宽

        int height = 40;//高  

        VerifyCodeUtils.outputImage(width, height, 


resp.getOutputStream(), verifyCode);  

        

    }

    

    @Override

    protected void doPost(HttpServletRequest req, HttpServletResponse 


resp) throws ServletException, IOException {

        // TODO Auto-generated method stub

        doGet(req, resp);

    }

}

3、服务器端验证验证码servlet


 


package com.servlet;


import java.io.IOException;


import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;


import com.util.VerifyCodeUtils;



public class VerifyCodeServlet extends HttpServlet {

    

    

    @Override

    protected void doGet(HttpServletRequest req, HttpServletResponse 


resp) throws ServletException, IOException {

        

        String code = req.getParameter("code");

        String key = (String) req.getSession().getAttribute("CODE");

        if(code != null && code.equalsIgnoreCase(key)){

            req.getSession().removeAttribute("CODE");

            resp.getWriter().println(true);

        }else{

            resp.getWriter().println(false);

        }

    }

    

    @Override

    protected void doPost(HttpServletRequest req, HttpServletResponse 


resp) throws ServletException, IOException {

        // TODO Auto-generated method stub

        super.doGet(req, resp);

    }

}

4、servet的注册,web.xml文件


<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="http://www.-instance" 


xmlns="http://java./xml/ns/javaee" 


xsi:schemaLocation="http://java./xml/ns/javaee 


http://java./xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" 


version="3.0">

  <display-name>test-captcha</display-name>

  

  

  <servlet>

      <servlet-name>CreateCodeServlet</servlet-name>

      <servlet-class>com.servlet.CreateCodeServlet</servlet-class>

  </servlet>

  <servlet-mapping>

      <servlet-name>CreateCodeServlet</servlet-name>

      <url-pattern>/createCode</url-pattern>

  </servlet-mapping>

  

   <servlet>

      <servlet-name>VerifyCodeServlet</servlet-name>

      <servlet-class>com.servlet.VerifyCodeServlet</servlet-class>

  </servlet>

  <servlet-mapping>

      <servlet-name>VerifyCodeServlet</servlet-name>

      <url-pattern>/verifyCode</url-pattern>

  </servlet-mapping>


  

  <welcome-file-list>

    <welcome-file>index.jsp</welcome-file>

  </welcome-file-list>

</web-app>

 


5、前端html文件


<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 


"http://www.www.">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Insert title here</title>

</head>

<body>

    <h2>测试验证码:</h2>

    请输入验证码:<input type="text" name="code" /><img id="codeimg" 


src="${pageContext.request.contextPath }/createCode" 


onclick="changeImg()"><a href="javascript:void(0);" 


onclick="changeImg()">看不清,换一张</a>

    <button onclick="submit()">提交</button>

    <script type="text/javascript">

    

        //改变验证码事件

        function changeImg(){

            var img = document.getElementById(‘codeimg‘);

            img.src = "${pageContext.request.contextPath 


}/createCode?x=" + Math.floor(Math.random()*100)

        }

        

        //提交验证并验证验证码

        function submit(){

            var input = document.getElementsByTagName(‘input‘)[0];

            

            //ajax提交

            var xhr = new XMLHttpRequest();

            

            xhr.onreadystatechange = function(){

                if(xhr.readyState == 4 && xhr.status == 200) {

                    alert(xhr.responseText);

                }  

            }

            

            xhr.open(‘get‘,‘${pageContext.request.contextPath 


}/verifyCode?code=‘ + input.value);

            xhr.send(null);

            

        }

        

        

        

    </script>

</body>

</html>-instance" xmlns="http://java./xml/ns/javaee" 


xsi:schemaLocation="http://java./xml/ns/javaee 


http://java./xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" 


version="3.0">

  <display-name>test-captcha</display-name>

  

  

  <servlet>

      <servlet-name>CreateCodeServlet</servlet-name>

      <servlet-class>com.servlet.CreateCodeServlet</servlet-class>

  </servlet>

  <servlet-mapping>

      <servlet-name>CreateCodeServlet</servlet-name>

      <url-pattern>/createCode</url-pattern>

  </servlet-mapping>

  

   <servlet>

      <servlet-name>VerifyCodeServlet</servlet-name>

      <servlet-class>com.servlet.VerifyCodeServlet</servlet-class>

  </servlet>

  <servlet-mapping>

      <servlet-name>VerifyCodeServlet</servlet-name>

      <url-pattern>/verifyCode</url-pattern>

  </servlet-mapping>


  

  <welcome-file-list>

    <welcome-file>index.jsp</welcome-file>

  </welcome-file-list>

</web-app>

 


5、前端html文件


<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//深圳市博纳网络信息技术有限公司//DTD HTML 


4.01 Transitional//EN" "http://生成验证码工具类

package com.util;


import java.awt.Color;

import java.awt.Font;

import java.awt.Graphics;

import java.awt.Graphics2D;

import java.awt.RenderingHints;

import java.awt.geom.AffineTransform;

import java.awt.image.BufferedImage;

import java.io.File;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.OutputStream;

import java.util.Arrays;

import java.util.Random;

 

import javax.imageio.ImageIO;



public class VerifyCodeUtils {

     

    //使用到Algerian字体,系统里没有的话需要安装字体,字体只显示大写,


去掉了1,0,i,o几个容易混淆的字符

    public static final String VERIFY_CODES = 


"23456789ABCDEFGHJKLMNPQRSTUVWXYZ";

    private static Random random = new Random();

 

 

    /**

     * 使用系统默认字符源生成验证码

     * @param verifySize    验证码长度

     * @return

     */

    public static String generateVerifyCode(int verifySize){

        return generateVerifyCode(verifySize, VERIFY_CODES);

    }

    

    /**

     * 使用指定源生成验证码

     * @param verifySize    验证码长度

     * @param sources   验证码字符源

     * @return

     */

    public static String generateVerifyCode(int verifySize, String 


sources){

        if(sources == null || sources.length() == 0){

            sources = VERIFY_CODES;

        }

        int codesLen = sources.length();

        Random rand = new Random(System.currentTimeMillis());

        StringBuilder verifyCode = new StringBuilder(verifySize);

        for(int i = 0; i < verifySize; i++){

            verifyCode.append(sources.charAt(rand.nextInt(codesLen-


1)));

        }

        return verifyCode.toString();

    }

     

    /**

     * 生成随机验证码文件,并返回验证码值

     * @param w

     * @param h

     * @param outputFile

     * @param verifySize

     * @return

     * @throws IOException

     */

    public static String outputVerifyImage(int w, int h, File 


outputFile, int verifySize) throws IOException{

        String verifyCode = generateVerifyCode(verifySize);

        outputImage(w, h, outputFile, verifyCode);

        return verifyCode;

    }

     

    /**

     * 输出随机验证码图片流,并返回验证码值

     * @param w

     * @param h

     * @param os

     * @param verifySize

     * @return

     * @throws IOException

     */

    public static String outputVerifyImage(int w, int h, OutputStream 


os, int verifySize) throws IOException{

        String verifyCode = generateVerifyCode(verifySize);

        outputImage(w, h, os, verifyCode);

        return verifyCode;

    }

     

    /**

     * 生成指定验证码图像文件

     * @param w

     * @param h

     * @param outputFile

     * @param code

     * @throws IOException

     */

    public static void outputImage(int w, int h, File outputFile, 


String code) throws IOException{

        if(outputFile == null){

            return;

        }

        File dir = outputFile.getParentFile();

        if(!dir.exists()){

            dir.mkdirs();

        }

        try{

            outputFile.createNewFile();

            FileOutputStream fos = new FileOutputStream(outputFile);

            outputImage(w, h, fos, code);

            fos.close();

        } catch(IOException e){

            throw e;

        }

    }

     

    /**

     * 输出指定验证码图片流

     * @param w

     * @param h

     * @param os

     * @param code

     * @throws IOException

     */

    public static void outputImage(int w, int h, OutputStream os, 


String code) throws IOException{

        int verifySize = code.length();

        BufferedImage image = new BufferedImage(w, h, 


BufferedImage.TYPE_INT_RGB);

        Random rand = new Random();

        Graphics2D g2 = image.createGraphics();

        g2.setRenderingHint


(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);

        Color[] colors = new Color[5];

        Color[] colorSpaces = new Color[] { Color.WHITE, Color.CYAN,

                Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA, 


Color.ORANGE,

                Color.PINK, Color.YELLOW };

        float[] fractions = new float[colors.length];

        for(int i = 0; i < colors.length; i++){

            colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)];

            fractions[i] = rand.nextFloat();

        }

        Arrays.sort(fractions);

         

        g2.setColor(Color.GRAY);// 设置边框色

        g2.fillRect(0, 0, w, h);

         

        Color c = getRandColor(200, 250);

        g2.setColor(c);// 设置背景色

        g2.fillRect(0, 2, w, h-4);

         

        //绘制干扰线

        Random random = new Random();

        g2.setColor(getRandColor(160, 200));// 设置线条的颜色

        for (int i = 0; i < 20; i++) {

            int x = random.nextInt(w - 1);

            int y = random.nextInt(h - 1);

            int xl = random.nextInt(6) + 1;

            int yl = random.nextInt(12) + 1;

            g2.drawLine(x, y, x + xl + 40, y + yl + 20);

        }

         

        // 添加噪点

        float yawpRate = 0.05f;// 噪声率

        int area = (int) (yawpRate * w * h);

        for (int i = 0; i < area; i++) {

            int x = random.nextInt(w);

            int y = random.nextInt(h);

            int rgb = getRandomIntColor();

            image.setRGB(x, y, rgb);

        }

         

        shear(g2, w, h, c);// 使图片扭曲

 

        g2.setColor(getRandColor(100, 160));

        int fontSize = h-4;

        Font font = new Font("Algerian", Font.ITALIC, fontSize);

        g2.setFont(font);

        char[] chars = code.toCharArray();

        for(int i = 0; i < verifySize; i++){

            AffineTransform affine = new AffineTransform();

            affine.setToRotation(Math.PI / 4 * rand.nextDouble() * 


(rand.nextBoolean() ? 1 : -1), (w / verifySize) * i + fontSize/2, 


h/2);

            g2.setTransform(affine);

            g2.drawChars(chars, i, 1, ((w-10) / verifySize) * i + 5, 


h/2 + fontSize/2 - 10);

        }

         

        g2.dispose();

        ImageIO.write(image, "png", os);

    }

     

    private static Color getRandColor(int fc, int bc) {

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

    }

     

    private static int getRandomIntColor() {

        int[] rgb = getRandomRgb();

        int color = 0;

        for (int c : rgb) {

            color = color << 8;

            color = color | c;

        }

        return color;

    }

     

    private static int[] getRandomRgb() {

        int[] rgb = new int[3];

        for (int i = 0; i < 3; i++) {

            rgb[i] = random.nextInt(255);

        }

        return rgb;

    }

 

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


{

        shearX(g, w1, h1, color);

        shearY(g, w1, h1, color);

    }

     

    private static void shearX(Graphics g, int w1, int h1, Color 


color) {

 

        int period = random.nextInt(2);

 

        boolean borderGap = true;

        int frames = 1;

        int phase = random.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);

            }

        }

 

    }

 

    private static void shearY(Graphics g, int w1, int h1, Color 


color) {

 

        int period = random.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);

            }

 

        }

    }

    public static void main(String[] args) throws IOException{

        File dir = new File("C:/Users/H__D/Desktop/");

        int w = 200, h = 80;

        String verifyCode = generateVerifyCode(4);

        File file = new File(dir, verifyCode + ".jpg");

        outputImage(w, h, file, verifyCode);

    }

}

 


使用图形验证码

 


1、使用流程


 


技术图片


 


2、服务器端生成验证码servlet


package com.servlet;


import java.io.IOException;


import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;


import com.util.VerifyCodeUtils;



public class CreateCodeServlet extends HttpServlet {

    

    

    @Override

    protected void doGet(HttpServletRequest req, HttpServletResponse 


resp) throws ServletException, IOException {

        resp.setHeader("Pragma", "No-cache");  

        resp.setHeader("Cache-Control", "no-cache");  

        resp.setDateHeader("Expires", 0);  

        resp.setContentType("image/jpeg");  

          

        //生成随机字串  

        String verifyCode = VerifyCodeUtils.generateVerifyCode(4);  

        //存入会话session  

        req.getSession().setAttribute("CODE", verifyCode.toLowerCase


());  

        

        //生成图片  

        int width = 100;//宽

        int height = 40;//高  

        VerifyCodeUtils.outputImage(width, height, 


resp.getOutputStream(), verifyCode);  

        

    }

    

    @Override

    protected void doPost(HttpServletRequest req, HttpServletResponse 


resp) throws ServletException, IOException {

        // TODO Auto-generated method stub

        doGet(req, resp);

    }

}

3、服务器端验证验证码servlet


 


package com.servlet;


import java.io.IOException;


import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;


import com.util.VerifyCodeUtils;



public class VerifyCodeServlet extends HttpServlet {

    

    

    @Override

    protected void doGet(HttpServletRequest req, HttpServletResponse 


resp) throws ServletException, IOException {

        

        String code = req.getParameter("code");

        String key = (String) req.getSession().getAttribute("CODE");

        if(code != null && code.equalsIgnoreCase(key)){

            req.getSession().removeAttribute("CODE");

            resp.getWriter().println(true);

        }else{

            resp.getWriter().println(false);

        }

    }

    

    @Override

    protected void doPost(HttpServletRequest req, HttpServletResponse 


resp) throws ServletException, IOException {

        // TODO Auto-generated method stub

        super.doGet(req, resp);

    }

}

4、servet的注册,web.xml文件


<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="http://www.-instance" 


xmlns="http://java./xml/ns/javaee" 


xsi:schemaLocation="http://java./xml/ns/javaee 


http://java./xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" 


version="3.0">

  <display-name>test-captcha</display-name>

  

  

  <servlet>

      <servlet-name>CreateCodeServlet</servlet-name>

      <servlet-class>com.servlet.CreateCodeServlet</servlet-class>

  </servlet>

  <servlet-mapping>

      <servlet-name>CreateCodeServlet</servlet-name>

      <url-pattern>/createCode</url-pattern>

  </servlet-mapping>

  

   <servlet>

      <servlet-name>VerifyCodeServlet</servlet-name>

      <servlet-class>com.servlet.VerifyCodeServlet</servlet-class>

  </servlet>

  <servlet-mapping>

      <servlet-name>VerifyCodeServlet</servlet-name>

      <url-pattern>/verifyCode</url-pattern>

  </servlet-mapping>


  

  <welcome-file-list>

    <welcome-file>index.jsp</welcome-file>

  </welcome-file-list>

</web-app>

 


5、前端html文件


<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//深圳市博纳网络信息技术有限公司//DTD HTML 


4.01 Transitional//EN" "http://www.">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Insert title here</title>

</head>

<body>

    <h2>测试验证码:</h2>

    请输入验证码:<input type="text" name="code" /><img id="codeimg" 


src="${pageContext.request.contextPath }/createCode" 


onclick="changeImg()"><a href="javascript:void(0);" 


onclick="changeImg()">看不清,换一张</a>

    <button onclick="submit()">提交</button>

    <script type="text/javascript">

    

        //改变验证码事件

        function changeImg(){

            var img = document.getElementById(‘codeimg‘);

            img.src = "${pageContext.request.contextPath 


}/createCode?x=" + Math.floor(Math.random()*100)

        }

        

        //提交验证并验证验证码

        function submit(){

            var input = document.getElementsByTagName(‘input‘)[0];

            

            //ajax提交

            var xhr = new XMLHttpRequest();

            

            xhr.onreadystatechange = function(){

                if(xhr.readyState == 4 && xhr.status == 200) {

                    alert(xhr.responseText);

                }  

            }

            

            xhr.open(‘get‘,‘${pageContext.request.contextPath 


}/verifyCode?code=‘ + input.value);

            xhr.send(null);

            

        }

        

        

        

    </script>

</body>

</html>">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Insert title here</title>

</head>

<body>

    <h2>测试验证码:</h2>

    请输入验证码:<input type="text" name="code" /><img id="codeimg" 


src="${pageContext.request.contextPath }/createCode" 


onclick="changeImg()"><a href="javascript:void(0);" 


onclick="changeImg()">看不清,换一张</a>

    <button onclick="submit()">提交</button>

    <script type="text/javascript">

    

        //改变验证码事件

        function changeImg(){

            var img = document.getElementById(‘codeimg‘);

            img.src = "${pageContext.request.contextPath 


}/createCode?x=" + Math.floor(Math.random()*100)

        }

        

        //提交验证并验证验证码

        function submit(){

            var input = document.getElementsByTagName(‘input‘)[0];

            

            //ajax提交

            var xhr = new XMLHttpRequest();

            

            xhr.onreadystatechange = function(){

                if(xhr.readyState == 4 && xhr.status == 200) {

                    alert(xhr.responseText);

                }  

            }

            

            xhr.open(‘get‘,‘${pageContext.request.contextPath 


}/verifyCode?code=‘ + input.value);

            xhr.send(null);

            

        }

        

        

        

    </script>

</body>

</html>">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Insert title here</title>

</head>

<body>

    <h2>测试验证码:</h2>

    请输入验证码:<input type="text" name="code" /><img id="codeimg" 


src="${pageContext.request.contextPath }/createCode" 


onclick="changeImg()"><a href="javascript:void(0);" 


onclick="changeImg()">看不清,换一张</a>

    <button onclick="submit()">提交</button>

    <script type="text/javascript">

    

        //改变验证码事件

        function changeImg(){

            var img = document.getElementById(‘codeimg‘);

            img.src = "${pageContext.request.contextPath 


}/createCode?x=" + Math.floor(Math.random()*100)

        }

        

        //提交验证并验证验证码

        function submit(){

            var input = document.getElementsByTagName(‘input‘)[0];

            

            //ajax提交

            var xhr = new XMLHttpRequest();

            

            xhr.onreadystatechange = function(){

                if(xhr.readyState == 4 && xhr.status == 200) {

                    alert(xhr.responseText);

                }  

            }

            

            xhr.open(‘get‘,‘${pageContext.request.contextPath 


}/verifyCode?code=‘ + input.value);

            xhr.send(null);

            

        }

        

        

        

    </script>

</body>

</html>">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Insert title here</title>

</head>

<body>

    <h2>测试验证码:</h2>

    请输入验证码:<input type="text" name="code" /><img id="codeimg" 


src="${pageContext.request.contextPath }/createCode" 


onclick="changeImg()"><a href="javascript:void(0);" 


onclick="changeImg()">看不清,换一张</a>

    <button onclick="submit()">提交</button>

    <script type="text/javascript">

    

        //改变验证码事件

        function changeImg(){

            var img = document.getElementById(‘codeimg‘);

            img.src = "${pageContext.request.contextPath 


}/createCode?x=" + Math.floor(Math.random()*100)

        }

        

        //提交验证并验证验证码

        function submit(){

            var input = document.getElementsByTagName(‘input‘)[0];

            

            //ajax提交

            var xhr = new XMLHttpRequest();

            

            xhr.onreadystatechange = function(){

                if(xhr.readyState == 4 && xhr.status == 200) {

                    alert(xhr.responseText);

                }  

            }

            

            xhr.open(‘get‘,‘${pageContext.request.contextPath 


}/verifyCode?code=‘ + input.value);

            xhr.send(null);

            

        }

        

        

        

    </script>

</body>

</html>-instance" xmlns="http://java./xml/ns/javaee" 


xsi:schemaLocation="http://java./xml/ns/javaee 


http://java./xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" 


version="3.0">

  <display-name>test-captcha</display-name>

  

  

  <servlet>

      <servlet-name>CreateCodeServlet</servlet-name>

      <servlet-class>com.servlet.CreateCodeServlet</servlet-class>

  </servlet>

  <servlet-mapping>

      <servlet-name>CreateCodeServlet</servlet-name>

      <url-pattern>/createCode</url-pattern>

  </servlet-mapping>

  

   <servlet>

      <servlet-name>VerifyCodeServlet</servlet-name>

      <servlet-class>com.servlet.VerifyCodeServlet</servlet-class>

  </servlet>

  <servlet-mapping>

      <servlet-name>VerifyCodeServlet</servlet-name>

      <url-pattern>/verifyCode</url-pattern>

  </servlet-mapping>


  

  <welcome-file-list>

    <welcome-file>index.jsp</welcome-file>

  </welcome-file-list>

</web-app>

 


5、前端html文件


<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//深圳市博纳网络信息技术有限公司//DTD HTML 


4.01 Transitional//EN" "http://www.">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Insert title here</title>

</head>

<body>

    <h2>测试验证码:</h2>

    请输入验证码:<input type="text" name="code" /><img id="codeimg" 


src="${pageContext.request.contextPath }/createCode" 


onclick="changeImg()"><a href="javascript:void(0);" 


onclick="changeImg()">看不清,换一张</a>

    <button onclick="submit()">提交</button>

    <script type="text/javascript">

    

        //改变验证码事件

        function changeImg(){

            var img = document.getElementById(‘codeimg‘);

            img.src = "${pageContext.request.contextPath 


}/createCode?x=" + Math.floor(Math.random()*100)

        }

        

        //提交验证并验证验证码

        function submit(){

            var input = document.getElementsByTagName(‘input‘)[0];

            

            //ajax提交

            var xhr = new XMLHttpRequest();

            

            xhr.onreadystatechange = function(){

                if(xhr.readyState == 4 && xhr.status == 200) {

                    alert(xhr.responseText);

                }  

            }

            

            xhr.open(‘get‘,‘${pageContext.request.contextPath 


}/verifyCode?code=‘ + input.value);

            xhr.send(null);

            

        }

        

        

        

    </script>

</body>

</html>

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约