javaweb实现图片验证码,并进行验证操作

时间:2019-01-11
本文章向大家介绍javaweb实现图片验证码,并进行验证操作,主要包括javaweb实现图片验证码,并进行验证操作使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

首先我们得从服务端画好验证码,然后通过流的方法传到前台来,然后前台传过来的验证码与后台生成的验证码进行验证。验证码主要是防止一些机器人进行操作的一种手段
不多说,下面先来生成验证码吧,这里我把生成验证码做了一个封装

/**
 * Copyright (C), 2018-2019, XXX有限公司
 * FileName: ImageCode
 * Author:   1543057945
 * Date:     2019/1/11 17:18
 * Description:
 * History:
 * <author>          <time>          <version>          <desc>
 * 张良敏         修改时间           版本号              描述
 */
package Utils;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.font.ImageGraphicAttribute;
import java.awt.image.BufferedImage;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Random;
import java.util.concurrent.CountDownLatch;

/**
 * 〈一句话功能简述〉<br> 
 * 〈〉
 *
 * @author 1543057945
 * @create 2019/1/11
 * @since 1.0.0
 */
public class ImageCode {
    //验证码个数
     private int count=4;
    //验证码宽度,且设置每个字的宽度
     private int width=count*50;
    //验证码高度
     private int height=50;
    //图片验证码key
     private String code="";
    public ImageCode() {
    }
    public ImageCode(int count, int width, int height) {
        this.count = count;
        this.width = width;
        this.height = height;
    }
    public int getCount() {
        return count;
    }
    public String getCode() {
        return code;
    }
    public int getWidth() {
        return width;
    }
    public int getHeight() {
        return height;
    }
    public void setCount(int count) {
        this.count = count;
        width=this.count*50;
    }

    public void setWidth(int width) {
        this.width = width;
    }

    public void setHeight(int height) {
        this.height = height;
    }
    //测试写入
    public static void main(String[] args){
        long startend=System.currentTimeMillis();
        ImageCode imageCode=new ImageCode();
        //默认验证码位数为4,我这里设为5
        imageCode.setCount(5);
        //得到缓冲区
        BufferedImage image = imageCode.getImage();
        //得到真实验证码
        String code=imageCode.getCode();
        long endTime=System.currentTimeMillis();
        System.out.println("验证码为:"+code+"\n花费时间为:"+(endTime-startend)+"\n到E盘根目录下看,文件名为11.jpg");
    }
    public BufferedImage getImage(){
        //图片缓冲区
        BufferedImage image = new BufferedImage(width,height,1);
        //获得笔
        Graphics graphics = image.getGraphics();
        //设置初始画笔为白色
        graphics.setColor(new Color(255,255,254));
        //画满整个图,也就是把图片先变为白色
        graphics.fillRect(0,0,width,height);
        Random rd=new Random();
        //设置字体
        Font font=new Font("宋体",Font.PLAIN,35+rd.nextInt(10));
        graphics.setFont(font);
        char[] chars="qweCRYHrtasdfBxy678934VTGopNUFKuighjklzSXEDLOP12cvbnmQAZWJMI50".toCharArray();
        //画验证码
        for (int i = 0; i <count ; i++) {
            String string="";
            string+=chars[rd.nextInt(chars.length)]+"";
            graphics.setColor(new Color(rd.nextInt(254),rd.nextInt(254),rd.nextInt(254)));
            graphics.drawString(string,55*i+rd.nextInt(10),27+rd.nextInt(15));
            code+=string;
        }
        //干扰点
        for (int i = 0; i <25*count ; i++) {
            graphics.setFont(new Font("宋体",Font.PLAIN,15));
            String string=".";
            graphics.setColor(new Color(rd.nextInt(255),rd.nextInt(255),rd.nextInt(255)));
            graphics.drawString(string,rd.nextInt(width),rd.nextInt(height));
        }
        //干扰线
        for (int i = 0; i <count+count/2 ; i++) {
            graphics.setFont(new Font("宋体",Font.PLAIN,10));
            graphics.setColor(new Color(rd.nextInt(255),rd.nextInt(255),rd.nextInt(255)));
            graphics.drawLine(rd.nextInt(width),rd.nextInt(height),rd.nextInt(width),rd.nextInt(height));
        }
        //归还笔
        graphics.dispose();
        //写到流里面需要用到ImageIo
        //这里做的测试,在本地测试下是否画的是那回事
        /*try {
            ImageIO.write(image,"jpg",new FileOutputStream("E:/11.jpg"));
        } catch (IOException e) {
            e.printStackTrace();
        }*/
        return image;
    }
}




接下来我们要写servlet代码了,其实就是一个生成验证码的接口



 package Utils;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.IOException;

@WebServlet(name = "GetImgServlet",urlPatterns = {"/imgcode"})
public class GetImgServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //设置页面内容为image形式
        response.setContentType("image/jpg");
        //防止乱码
        response.setCharacterEncoding("UTF-8");
        //定义获取验证码的对象
        ImageCode imageCode=new ImageCode();
        //得到图片缓冲区
        BufferedImage img = imageCode.getImage();
        //得到文字验证码
        String code = imageCode.getCode();
        //获得用户session
        HttpSession session = request.getSession();
        //将文字验证码保存到客户端session,方便验证
        session.setAttribute("imgcode",code);
        System.out.println("生成的验证码为:"+code);
        //获得sevlet输出流
        ServletOutputStream outputStream = response.getOutputStream();
        //写到客户端
        ImageIO.write(img,"jpg",outputStream);
        //关闭输出流
        if(outputStream!=null){
            outputStream.close();
        }
    }
}

做好验证码api之后我们还要进行前台交互下,看到底有没有作用


这是html文档
   <!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>验证码</title>
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
</head>
<body>
<table border="0" cellpadding="0" cellspacing="0">
    <tr>
        <td>
            <input type="text" name="code">
        </td>
        <td>
            <img src="/imgcode" style="height: 30px;width: 120px">
        </td>
    </tr>
    <tr>
        <td colspan="2">
            <center><button type="button" class="button">验证</button></center>
        </td>
    </tr>
</table>
<script>
    $(document).ready(function () {
        //设置按钮的点击事件
        $(".button").click(function () {
            var code = $("input[name='code']");
            if (code.val() == null || code.val() == "") {
                alert("请输入验证码后再认证");
            } else {
                //有值了,我们就体检到后台验证,通过post
                $.post("/checkcode", code.serialize(), function (data, stauts) {
                    if (stauts = 'success') {
                        if (data == "验证正确")
                            alert("验证正确");
                        else
                            alert("验证码错误");
                    } else {
                        alert("请求错误");
                    }
                })
            }
        })

        //点击图片切换验证码
        $("img").click(function () {
            $("img").attr("src","/imgcode?"+Math.random())
        })
    })
</script>

</body>
</html>

这是接受验证码的接口

package Utils;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet(name = "CheckCodeServlet",urlPatterns ={"/checkcode"})
public class CheckCodeServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //设置页面类型
        response.setContentType("text/html,charset=urf-8");
        response.setCharacterEncoding("utf-8");
        //得到请求参数
        String code = request.getParameter("code");
        //得到session
        HttpSession session = request.getSession();
        //得到生成的验证码
        String imgcode = (String) session.getAttribute("imgcode");
        PrintWriter writer = response.getWriter();
        if (imgcode.equalsIgnoreCase(code)){
            System.out.println(imgcode+"\n"+code);
            writer.print("验证正确");
            //验证之后最好销毁下之前的
            session.setAttribute("imgcode","");
        }else{
            writer.print("验证码错误");
        }
        writer.close();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}

验证码输入正确会提示

输入错误则提示

好了,教程结束,希望能帮到大家,稍作改动就可以拿到实际项目中运用了