JSP+Servlet实现验证码

制作验证码图片

        我们注册用户时,往往都需要我们在输入框中的数据与图片显示的内容进行对比。下面是二维码图片制作工具类与效果图
在这里插入图片描述

二维码制作工具类

public class VerifyCodeUtils {
    /**
     * 封装获取含有二维码图片与内容(答案)的Map集合
     * @return Map含有图片与答案,k为图片对应的答案,v为图片
     */
    public static Map<String, BufferedImage> getMap(){
        //1、构建一张空白(透明)图片
        BufferedImage image = new BufferedImage(200,50,BufferedImage.TYPE_3BYTE_BGR);
        //2、得到画笔
        Graphics g = image.getGraphics();
        //3、设置画笔的颜色
        g.setColor(Color.white);
        //4、给空白200*100图片填充背景
        g.fillRect(0,0,200,50);
        //5、给一个黑色的边框
        g.setColor(Color.BLACK);
        g.drawRect(0,0,199,49);
        //6、画内容
        StringBuilder sb = new StringBuilder();
        //7、构建随机对象
        Random rd = new Random();
        //8、随机画四个字母
        for (int i = 0; i < 4; i++){
            //8.1 随机颜色 红(0-255)  绿(0-255)  蓝(0-255)
            Color c = new Color(rd.nextInt(256),rd.nextInt(256),rd.nextInt(256));
            //8.2 随机字符 A - Z ∈ [65,90]
            char ch = (char)(rd.nextInt(26) + 65);
            //8.3 将字符画到图片上
            g.setColor(c);
            //8.4 设置字体为楷体与大小
            g.setFont(new Font("楷体",Font.BOLD,28));
            g.drawString(ch+"",45+30*i,35);
            //8.5 将字符通过可变字符串保存起来
            sb.append(ch);
        }
        //9、构建Map并添加到Map中
        Map<String,BufferedImage> map = new HashMap<>();
        map.put(sb.toString(),image);
        //10、返回map对象
        return map;
    }
    
    /**
     *  封装:获取 Map<String,BufferedImage>中的二维码图片BufferedImg对象
     * @param map 含有二维码图片与答案的Map集合
     * @return 二维码图片BufferedImg对象
     */
    public static BufferedImage getImg(Map<String,BufferedImage> map){
        //二维码图片对象
        BufferedImage image = null;
        //遍历Map集合
        Set<Map.Entry<String, BufferedImage>> entrySet = map.entrySet();
        //得到set迭代器
        Iterator<Map.Entry<String,BufferedImage>> iterator = entrySet.iterator();
        //由于此处map只有一组键值对(K-V),直接得到键值对并返回value
        return iterator.next().getValue();
    }

    /**
     * 封装得到验证码图片对应的答案(Key值)
     * @param map 含有一组键值对的答案与二维码图片集合
     * @return 返回二维码图片对应的答案(字符串)
     */
    public static String getCode(Map<String,BufferedImage> map){
        //遍历Map集合
        Set<Map.Entry<String, BufferedImage>> entrySet = map.entrySet();
        Iterator<Map.Entry<String, BufferedImage>> iterator = entrySet.iterator();
        //返回答案(K值及答案)
        return iterator.next().getKey();
    }
}

验证码图片生成的Servlet与用户输入结果的验证

        我们需要通过对应的Servlet将验证码图片进行响应,由于src属性值也是一种资源寻址,因此我们可以直接修改注册网页中img标签的src属性来显示二维码图片,其属性值为该Servlet的访问地址即可
        通过该Servlet业务将验证码图片对应的答案保存在Session对象中进行保存,便于获取用户输入的答案与系统自动生成的答案进行匹配,检测用户输入是否正确,下面是对应Servlet实现代码

@WebServlet("/friend_demo/imgCode")
public class ImageCodeServlet extends HttpServlet {
    @Override
    public void service(HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException{
        //1、设置请求对象的数据编码方法
        request.setCharacterEncoding("utf-8");
        //2、设置响应类型为一张图片
        response.setContentType("image/jpeg");
        //3、获取验证码的Map
        Map<String, BufferedImage> map = VerifyCodeUtils.getMap();
        //4、获取验证码图片
        BufferedImage img = VerifyCodeUtils.getImg(map);
        //5、获取系统自动生成验证码图片对应的答案
        String code = VerifyCodeUtils.getCode(map);
        //6、将验证码图片对应的答案绑定到Session中保存,方便后期获取用户输入答案进行比较
        HttpSession session = request.getSession();
        session.setAttribute("code_1",code);
        //7、将验证码图片放入输出流中,写入网页中
        ImageIO.write(img,"jpeg",response.getOutputStream());
    }
}

        将注册页面的src属性值修改为Servlet访问路径即可,修改如下

<tr>
	<td valign="middle" align="right">
		验证码:
		<img id="num" src="imgCode" />
		<a href="javascript:;"
			onclick="document.getElementById('num').src = 'imgCode?'+(new Date()).getTime()">换一张</a>
	</td>
	<td valign="middle" align="left">
		<input type="text" class="inputgri" name="checkCode" id="code" onblur="checkInputCode();"/>
		<span id="err_code"></span>
	</td>
</tr>

注意:
1、其中的src属性值已经修改为了 验证码生成的Servlet对应的访问路径
2、为了能够保证我们每次点击 “换一张” 时发送的请求是不同的请求,达到刷新验证码图片的效果时,我们在请求的后面通过携带一个参数,该参数一个通过js获取的日期对象毫秒数来保证每次请求的差异性,从而刷新验证码图片

         感谢大家的阅读,热爱分享的仓鼠,请大家多多指教,么么哒~~~~~

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

被风吹过的忧伤

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值