(servelet)验证码

验证码的作用

  • 为了防止机器人的破坏操作,可以使用验证码技术来防止恶意的发送数据。
  • 验证码本质上是一张动态产生的图片。
  • 图片的内容会随着程序的运行而随机产生。

验证码的绘制

  • 验证码图片的生成需要使用java提供的与绘图有关的一系列API。
  • 想要绘图,需要画板,画笔,颜料,背景色,字体等多种类对象配合完成。

验证码图片的绘制步骤

  • 1、创建一个内存画板对象
  • 2、获取画笔
  • 3、为画笔指定颜色
  • 4、为画板设置背景色
  • 5、绘制一个随机的字符串
  • 6、修改画笔颜色
  • 7、绘制多条干扰线
  • 8、压缩图片并输出到客户端
package com.verificationCode.servelet;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class ValidateCode extends HttpServlet {
    private static final long serialVersionUID = 1L;
    public ValidateCode() {
        super();
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //0、创建空白图片
        BufferedImage image = new BufferedImage(100, 30, BufferedImage.TYPE_INT_RGB);
        //1、获取图片画笔
        Graphics g = image.getGraphics();
        Random r = new Random();
        //2、设置画笔颜色
        g.setColor(new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255)));
        //3、绘制矩形的背景
        g.fillRect(0, 0, 100, 30);
        //4、调用自定义的方法,获取长度为5的字母数字组合的字符串
        String number = getNumber(5);
        HttpSession session = request.getSession();
        session.setAttribute("code", number);
        g.setColor(new Color(0, 0, 0));
        g.setFont(new Font(null, Font.BOLD, 24));
        //5、设置颜色字体后,绘制字符串
        g.drawString(number, 5, 25);
        //6、绘制8条干扰线
        for(int i = 0;i<8;i++){
            g.setColor(new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255), r.nextInt(255)));
            g.drawLine(r.nextInt(100), r.nextInt(30), r.nextInt(100), r.nextInt(30));
        }
        response.setContentType("image/jpeg");
        OutputStream ops = response.getOutputStream();
        ImageIO.write(image, "jpeg", ops);
        ops.close();
    }

    private String getNumber(int size){
        String str = "ASDFGHJLPOIUYTREWQZXCVBNM";
        String number = "";
        Random r = new Random();
        for(int i = 0 ; i<size;i++){
            number += str.charAt(r.nextInt(str.length()));
        }
        return number;
    }
}

验证码的验证流程

  • 请求带有验证码的页面时:
    • 通过img标签的src属性获取验证码图片
    • 服务器端生成随机字符串,并绘制
    • 服务器端将生成的随机字符串绑定到session中
  • 提交表单及填写的验证码内容时:
    • 处理程序将session中绑定的正确的验证码字符串取出来
    • 获取表单提交时填写的验证码内容
    • 比较两者,根据结果做出判断
package com.verificationCode.servelet;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class ActionServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    public ActionServlet() {
        super();
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }


    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        String uri = request.getRequestURI();
        String action = uri.substring(uri.lastIndexOf("/")+1, uri.lastIndexOf("."));
        //判断动作是否为登录
        if(action.equals("login")){
            String name = request.getParameter("uname");
            String pwd = request.getParameter("pwd");
            String number = request.getParameter("vcode");
            HttpSession session = request.getSession();
            String code = session.getAttribute("code").toString();
            if(number.equals(code)&&name.equals("111")&&pwd.equals("111")){
                //编程式--设定session超时时间为10秒
                //session.setMaxInactiveInterval(10);
                session.setAttribute("uname", name);
                //重定向到首页
                //response.sendRedirect("index.jsp");
                response.sendRedirect(response.encodeRedirectUrl("index.jsp"));
            } else{
                //登录失败
                request.setAttribute("msg", "用户名或密码错误");
                request.getRequestDispatcher("login.jsp").forward(request, response);
            }
        }else if(action.equals("logout")){
            HttpSession session = request.getSession();
            //session失效
            session.invalidate();
            response.sendRedirect("login.jsp");
        }
        out.close();
    }
}
login.jsp代码
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<script type="text/javascript"></script>
<style type="text/css">
    .s1 {
        cursor: pointer;
    }
</style>
</head>

<body>
    <form action="" method="post">
        姓名:<input type="text" /><br> 
        密码:<input type="password" /><br>
        验证码:<input type="text" /> 
        <img src="code" onclick="this.src='code?'+Math.random()" class="s1" title="点击更换"><br>
        <input type="submit" value="提交" />
    </form>
</body>
</html>
web.xml代码
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>verificationCode</display-name>

  <servlet>
    <servlet-name>ValidateCode</servlet-name>
    <servlet-class>com.verificationCode.servelet.ValidateCode</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>ValidateCode</servlet-name>
    <url-pattern>/code</url-pattern>
  </servlet-mapping>

  <servlet>
    <servlet-name>ActionServlet</servlet-name>
    <servlet-class>com.verificationCode.servelet.ActionServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>ActionServlet</servlet-name>
    <url-pattern>*.do</url-pattern>
  </servlet-mapping>
</web-app>

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏偏前端工程师的驿站

CSS魔法堂:重拾Border之——解构Border

前言  当CSS3推出border-radius属性时我们是那么欣喜若狂啊,一想到终于不用再添加额外元素来模拟圆角了,但发现border-radius还分水平半...

2318
来自专栏黒之染开发日记

css3动画在手机端的流畅度比较

我发现即使都是用css3的transition做动画,有的属性在动画播放时却会不流畅,出现定格动画的效果,这里做个比较,方便我以后做动画。

4012
来自专栏一“技”之长

iOS开发CoreAnimation解读之四——Layer层动画内容

        通过前几篇博客的介绍,我们可以了解到layer层可以设置许多与控件UI相关的属性,并且对于iOS开发,UIView层的属性是会映射到CALaye...

961
来自专栏Android中高级开发

深入分析Android动画(一)

  View动画顾名思义其作用对象为View,包含平移、缩放、旋转、透明,这四类变化分别对应着Animation的子类TranlateAnimation、Sca...

1194
来自专栏一“技”之长

Java开发GUI之可编辑区域 原

    Java的awt包中提供了单行的文本编辑组件TextField与多行的文本编辑区TextArea,这两个组件都是继承自TextComponent类。

862
来自专栏河湾欢儿的专栏

标签类型

标签类型 块 1.独占一行 2.支持所有样式 3.不设置宽度的时候,宽度撑满整个一行 内嵌 1.可以在一行显示 2.不支持宽高,不支持上下的mar...

1043
来自专栏九彩拼盘的叨叨叨

那些 CSS 的设计失误(译)

CSS Working Group 写的 Incomplete List of Mistakes in the Design of CSS 。译的不好,请见谅。

911
来自专栏柠檬先生

VUE 入门基础(9)

十一,深入响应式原理    声明响应式属性     由于Vue不允许动态添加根级响应式属性,所以你必须在初始化实例钱声明根级响应式属性,哪怕只有一个空值。 ...

2365
来自专栏Android常用基础

自定义View(三)-动画-属性动画ValueAnimator

之前我们把视图动画(也就是View动画)分析的差不多了,当然帧动画我们没有讲解,其实帧动画比较简单,就是通过顺序播放一系列的图像从而产生动画效果,可以简单理解为...

3802
来自专栏everhad

android自定义控件一站式入门

Android系统提供了一系列UI相关的类来帮助我们构造app的界面,以及完成交互的处理。 一般的,所有可以在窗口中被展示的UI对象类型,最终都是继承自Vie...

3020

扫码关注云+社区

领取腾讯云代金券