session完成验证码案例

需求
用户登录的时候使用验证码进行验证
步骤
一、
LoginServlet实现步骤:

  1. 使用代码实现验证码的绘制
  2. 将随机产生的字符串放在会话域中
  3. 用户登录的时候提交验证码的字符串
  4. 比较表单提交的字符串是否与会话域中的字符串相等,如果相等则验证成功
  5. 登录一次以后删除会话域中的验证码字符串
  6. 登录成功以后保存用户的信息到会话域中,并且跳转到WelcomeServlet
    二、
    WelcomeServlet的实现步骤:
  7. 会话域中取出用户信息并且显示
  8. 判断用户是否正常登录,如果是非法用户则跳转到登录页面
  9. 在页面上输出一个注销的连接,点注销跳转到LogoutServlet
    三、 LogoutServlet的实现步骤:
  10. 让会话立刻过期
  11. 显示您已经成功退出

web网页页面部分
在这里插入图片描述
登陆页面主要使用bootstrap框架写的
Java类部分
在这里插入图片描述
验证码类 PicCodeServlet 的代码部分

package com.zjs.servlet;

import javax.imageio.ImageIO;
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.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

@WebServlet(name = "PicCodeServlet", urlPatterns = "/code")
public class PicCodeServlet extends HttpServlet {

    //创建一个随机类
    private Random ran = new Random();

    //写一个方法随机生成一种颜色
    private Color getRandomColor() {
        //随机生成0~255之间的数
        int red = ran.nextInt(256);
        int green = ran.nextInt(256);
        int blue = ran.nextInt(256);
        //红,绿,蓝
        return new Color(red, green, blue);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1. 创建缓存图片
        int width = 90, height = 30;
        //参数:宽,高,图片模式
        BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        //2. 获取画笔对象
        Graphics graphics = img.getGraphics();
        //3. 设置画笔颜色
        graphics.setColor(Color.WHITE);
        //4. 填充矩形区域
        graphics.fillRect(0, 0, width, height);
        //5. 从字符数组中随机得到字符
        char[] arr = { 'A', 'B', 'C', 'D', 'N', 'E', 'W', 'b', 'o', 'y', '1', '2', '3', '4','5','6' };
        //6. 循环4次,画4个字符
        //new一个空字符用来存储验证码字符串
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 4; i++) {
            //7. 设置字的颜色为随机
            graphics.setColor(getRandomColor());
            //8. 设置字体,大小为19
            graphics.setFont(new Font(Font.SANS_SERIF,Font.BOLD+Font.ITALIC,19));
            //随机得到下标
            int index = ran.nextInt(arr.length);
            char c = arr[index];
            //将循环得到的字符拼接成字符串
            sb.append(c);
            //随机得到一个字符
             //9. 将每个字符画到图片,x增加,y不变。
            graphics.drawString(String.valueOf(c),10+(i*20), 20);
        }
        //将验证码以字符串的方式放到会话域中
        HttpSession session = request.getSession();
        System.out.println("验证码:"+sb.toString());
        session.setAttribute("code",sb.toString());
        //11. 画8条干扰线,每条线的颜色不同
        for (int i = 0; i < 8; i++) {
            //10. 线的位置是随机的,x范围在width之中,y的范围在height之中。
            int x1 = ran.nextInt(width);
            int y1 = ran.nextInt(height);
            int x2 = ran.nextInt(width);
            int y2 = ran.nextInt(height);
            graphics.setColor(getRandomColor());
            graphics.drawLine(x1,y1,x2,y2);
        }
        //12. 将缓存的图片输出到响应输出流中
        //参数:图片对象,图片格式,输出流
        ImageIO.write(img,"jpg",response.getOutputStream());
    }

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

login.html代码部分

<!DOCTYPE html>
<html>
<head>
		<meta charset="utf-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1">
		<title>会员登录</title>
		<link rel="stylesheet" href="css/bootstrap.min.css" type="text/css" />
		<script src="js/jquery-1.11.3.min.js" type="text/javascript"></script>
		<script src="js/bootstrap.min.js" type="text/javascript"></script>
<!-- 引入自定义css文件 style.css -->
<link rel="stylesheet" href="css/style.css" type="text/css"/>

<style> body{ margin-top:20px; margin:0 auto; } .carousel-inner .item img{ width:100%; height:300px; } .container .row div{ /* position:relative; float:left; */ } font { color: #666; font-size: 22px; font-weight: normal; padding-right:17px; } </style>
</head>
<body>
	
			<!-- 描述:菜单栏 -->
			<div class="container-fluid">
				<div class="col-md-4">
					<img src="img/logo2.png" />
				</div>
				<div class="col-md-5">
					<img src="img/header.png" />
				</div>
				<div class="col-md-3" style="padding-top:20px">
					<ol class="list-inline">
						<li><a href="login.htm">登录</a></li>
						<li><a href="register.htm">注册</a></li>
						<li><a href="cart.htm">购物车</a></li>
					</ol>
				</div>
			</div>
			<!-- 描述:导航条 -->
			<div class="container-fluid">
				<nav class="navbar navbar-inverse">
					<div class="container-fluid">
						<!-- Brand and toggle get grouped for better mobile display -->
						<div class="navbar-header">
							<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
								<span class="sr-only">Toggle navigation</span>
								<span class="icon-bar"></span>
								<span class="icon-bar"></span>
								<span class="icon-bar"></span>
							</button>
							<a class="navbar-brand" href="#">首页</a>
						</div>

						<!-- Collect the nav links, forms, and other content for toggling -->
						<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
							<ul class="nav navbar-nav">
								<li class="active"><a href="#">手机数码<span class="sr-only">(current)</span></a></li>
								<li><a href="#">电脑办公</a></li>
								<li><a href="#">电脑办公</a></li>
								<li><a href="#">电脑办公</a></li>
							</ul>
							<form class="navbar-form navbar-right" role="search">
								<div class="form-group">
									<input type="text" class="form-control" placeholder="Search">
								</div>
								<button type="submit" class="btn btn-default">Submit</button>
							</form>

						</div>
						<!-- /.navbar-collapse -->
					</div>
					<!-- /.container-fluid -->
				</nav>
			</div>
	
<div class="container" style="width:100%;height:460px;background:#FF2C4C url('img/loginbg.jpg') no-repeat;">
<div class="row"> 
	<div class="col-md-7">
		<!--<img src="./img/login.jpg" width="500" height="330" alt="会员登录" title="会员登录">-->
	</div>
	
	<div class="col-md-5">
				<div style="width:440px;border:1px solid #E7E7E7;padding:20px 0 20px 30px;border-radius:5px;margin-top:60px;background:#fff;">
				<font>会员登录</font>USER LOGIN

				<div>&nbsp;</div>
<form class="form-horizontal" action="login">
  
 <div class="form-group">
    <label for="username" class="col-sm-2 control-label">用户名</label>
    <div class="col-sm-6">
      <input type="text" class="form-control"name="username" id="username" placeholder="请输入用户名">
    </div>
  </div>
   <div class="form-group">
    <label for="password" class="col-sm-2 control-label">密码</label>
    <div class="col-sm-6">
      <input type="password" class="form-control"name="password" id="password" placeholder="请输入密码">
    </div>
  </div>
   <div class="form-group">
        <label for="code" class="col-sm-2 control-label">验证码</label>
    <div class="col-sm-3">
      <input type="text" name="code" class="form-control" id="code" placeholder="请输入验证码">
    </div>
    <div class="col-sm-3">
      <img src="code" title="看不清,请重试" style="cursor: pointer" id="imgcode"/>
        <script type="text/javascript"> document.getElementById("imgcode").onclick=function (ev) { this.src="code?t="+Math.random(); } </script>
    </div>
    
  </div>
   <div class="form-group">
    <div class="col-sm-offset-2 col-sm-10">
      <div class="checkbox">
        <label>
          <input type="checkbox"> 自动登录
        </label>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
        <label>
          <input type="checkbox"> 记住用户名
        </label>
      </div>
    </div>
  </div>
  <div class="form-group">
    <div class="col-sm-offset-2 col-sm-10">
    <input type="submit" width="100" value="登录" name="submit" border="0" style="background: url('./img/login.gif') no-repeat scroll 0 0 rgba(0, 0, 0, 0);  height:35px;width:100px;color:white;">
    </div>
  </div>
</form>
</div>			
	</div>
</div>
</div>	

	<div style="margin-top:50px;">
			<img src="./img/footer.jpg" width="100%" height="78" alt="我们的优势" title="我们的优势" />
		</div>

		<div style="text-align: center;margin-top: 5px;">
			<ul class="list-inline">
				<li><a>关于我们</a></li>
				<li><a>联系我们</a></li>
				<li><a>招贤纳士</a></li>
				<li><a>法律声明</a></li>
				<li><a>友情链接</a></li>
				<li><a target="_blank">支付方式</a></li>
				<li><a target="_blank">配送方式</a></li>
				<li><a>服务声明</a></li>
				<li><a>广告声明</a></li>
			</ul>
		</div>
		<div style="text-align: center;margin-top: 5px;margin-bottom:20px;">
			Copyright &copy; 2005-2016 
		</div>
</body></html>
**主要是验证码部分的代码,我截出来了,如下图**

在这里插入图片描述
LoginServlet实现步骤:

  1. 使用代码实现验证码的绘制
  2. 将随机产生的字符串放在会话域中
  3. 用户登录的时候提交验证码的字符串
  4. 比较表单提交的字符串是否与会话域中的字符串相等,如果相等则验证成功
  5. 登录一次以后删除会话域中的验证码字符串
  6. 登录成功以后保存用户的信息到会话域中,并且跳转到WelcomeServlet

代码部分

package com.zjs.servlet;

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 = "LoginServlet", urlPatterns = "/login")
public class LoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
          //设置字符集
        response.setContentType("text/html;charset=utf-8");
        //得到打印流
          PrintWriter out = response.getWriter();
          //得到会话域
        HttpSession session = request.getSession();
        //得到登陆页面上显示得验证码
        String code = (String) session.getAttribute("code");
        //得到用户输入得验证码
        String code1 = request.getParameter("code");
        //用户输入的验证码与登陆页面上显示得验证码进行比较
        if (code.equalsIgnoreCase(code1)){
    //用户名与密码主要是从数据库中查询得,这个案例主要是验证 验证码,这里就不演示访问数据库了
            //得到用户名
            String username=request.getParameter("username");
            //得到用户密码
            String password=request.getParameter("password");
            //如果用户名和密码分别等于ljm,520的话验证就通过
            if ("ljm".equals(username)&&"520".equals(password)){
                //将用户信息存到会话域中
                session.setAttribute("username",username);
                //转发到welcome
                request.getRequestDispatcher("welcome").forward(request, response);
            }
            else {
                //写js脚本用来提示
                out.print("<script>");
                out.print("alert('用户名或密码不正确');");
                out.print("location.href='login.html';");
                out.print("</script>");
            }

            }
        else {
            out.print("<script>");
            out.print("alert('验证码不正确');");
            out.print("location.href='login.html';");
            out.print("</script>");
        }

        }



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

WelcomeServlet的实现步骤:
7. 会话域中取出用户信息并且显示
8. 判断用户是否正常登录,如果是非法用户则跳转到登录页面
9. 在页面上输出一个注销的连接,点注销跳转到LogoutServlet

代码部分

package com.zjs.servlet;

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 = "WelcomeServlet", urlPatterns = "/welcome")
public class WelcomeServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //设置字符集
        response.setContentType("text/html;charset=utf-8");
        //得到打印流
         PrintWriter out = response.getWriter();
         //得到会话域
        HttpSession session = request.getSession();
        ////从会话域中得到用户名
        String username = (String) session.getAttribute("username");
        //登陆成功后判断用户名是否为空,如果为空,重定向到登陆页面
        if (username==null){
            response.sendRedirect("login.html");
            return;
        }
        out.print("欢迎来到我的世界"+session.getAttribute("username")+"<br/>");
        //如果点退出,就跳转到logout页面
        out.print("<a href='logout'>退出</a>");

    }

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

三、 LogoutServlet的实现步骤:
10. 让会话立刻过期
11. 显示您已经成功退出

代码部分

package com.zjs.servlet;

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 java.io.IOException;

@WebServlet(name = "logoutServlet", urlPatterns = "/logout")
public class logoutServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       //得到会话域后 让会话域立刻失效
        request.getSession().invalidate();
        //并且重定向到登陆页面
        response.sendRedirect("login.html");
    }

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

效果截图
一、
登陆页面:
在这里插入图片描述
二、
1.输入正确的用户名和密码
在这里插入图片描述
2.输入正确的用户名和密码后跳转到的页面
在这里插入图片描述
三、点退出后会跳回上面显示的登陆页面

四、输入错误的验证码以及弹出的提示
在这里插入图片描述

在这里插入图片描述
五、输入错误的用户名或密码以及提示
在这里插入图片描述
在这里插入图片描述