关于验证码的使用(使用servlet实现验证码)~

前提:所使用的页面包括登录页面(login.jsp)、登录成功的页面(index.jsp)、验证码(VerifyCode.java)、登录的Servlet(LoginServlet)、处理验证码的Servlet(VerifyCodeServlet)

整个实现工程的目录结构

关于验证码的使用(使用servlet实现验证码)~

1. login.jsp

 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
 2 <%
 3 String path = request.getContextPath();
 4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
 5 %>
 6 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 7 <html>
 8   <head>
 9     <base href="<%=basePath%>">   
10     <title>登录页面</title>    
11     <meta http-equiv="pragma" content="no-cache">
12     <meta http-equiv="cache-control" content="no-cache">
13     <meta http-equiv="expires" content="0">    
14     <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
15     <meta http-equiv="description" content="This is my page">
16     <!--
17     <link rel="stylesheet" type="text/css" href="styles.css">
18     -->
20   </head>
22   <body>
23    <!-- 登录页面 -->
24    <%
25    //获得错误信息
26            String msg="";
27            String msgs=(String)session.getAttribute("msg");
28            if(msgs!=null){
29                msg=msgs;
30            }
31     %>
32    <form action="/review_javaee09/servlet/LoginServlet" method="post">
33        <table>
34            <caption>用户登录</caption>
35            <tr>
36                <td>用户名:</td>
37                <td><input type="text" name="username" value=""></td>
38            </tr>
39            <tr>
40                <td>密码</td>
41                <td><input type="password" name="pwd" ></td>
42            </tr>
43            <tr>
44                <td>验证码</td>
45                <td><input type="text" name="verify" size=5><a href="javascript:_change()"><img alt="验证码" src="/review_javaee09/servlet/VerifyCodeServlet" id=image></a></td>
46            </tr>
47            <tr>
48                <td><input type="reset" value="重置"></td>
49                <td><input type="submit" value="登录" ></td>
50            </tr>    
51        </table>
52        <p>
53            <font size=3 color="red"><%=msg %></font>
54        </p>
55    </form>
56   </body>
57   <script type="text/javascript">
58   /*
59       实现验证码图片看不清换一张
60   */
61       function _change(){
62           document.getElementById("image").src="/review_javaee09/servlet/VerifyCodeServlet?"+new Date().getTime(); 
63       }
64       /*
65           此处src必须带有一个可以变化的参数,原因主要是由于当前浏览器的缓存机制
66       */
67   </script>
68 </html>

2. index.jsp

 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
 2 <%
 3 String path = request.getContextPath();
 4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
 5 %>
 6 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 7 <html>
 8   <head>
 9     <base href="<%=basePath%>">
10     <title>登录成功页面</title>
11     <meta http-equiv="pragma" content="no-cache">
12     <meta http-equiv="cache-control" content="no-cache">
13     <meta http-equiv="expires" content="0">    
14     <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
15     <meta http-equiv="description" content="This is my page">
16   </head>
17   <body>
18   <!-- 如果没有登录,跳转到登录页面 -->
19   <%
20       String name=(String)session.getAttribute("username");
21       if(name==null){
22           response.sendRedirect("/review_javaee09/login.jsp");
23       }
24    %>
25     <h1>首页</h1>  
26     <p>
27     <font size="5" color="yellow">欢迎<%=name %></font>
28     </p>
29   </body>
30 </html>

3.LoginServlet.java

 1 package com.review_javaee09.web.servlet;
 2 
 3 import java.io.IOException;
 4 import javax.servlet.ServletException;
 5 import javax.servlet.http.Cookie;
 6 import javax.servlet.http.HttpServlet;
 7 import javax.servlet.http.HttpServletRequest;
 8 import javax.servlet.http.HttpServletResponse;
 9 import javax.servlet.http.HttpSession;
10 
11 import org.apache.jasper.tagplugins.jstl.core.Out;
12 
13 
14 @SuppressWarnings("serial")
15 public class LoginServlet extends HttpServlet {
16     
17     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
18         doPost(request, response);
19     }
20 
21     
22     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
23         request.setCharacterEncoding("utf-8");
24         response.setContentType("text/html;charset=utf-8");
25         
26         HttpSession session = request.getSession();
27         
28         String name=request.getParameter("username"); //获得用户名
29         String pwd=request.getParameter("pwd");   //获得密码
30         String verify=request.getParameter("verify");  //获得输入的验证码
31         String verifys = (String) session.getAttribute("verify");  //获得存在session中的验证码
32         if("admin".equals(name)&&"admin".equals(pwd)){//如果用户名和密码正确
33             if(verify.equals(verifys)){//如果验证码正确
34                 session.setAttribute("username", name);
35                 session.setAttribute("pwd", pwd);
36                 request.getRequestDispatcher("/index.jsp").forward(request, response);
37             }else{ //如果验证码不正确
38                 String msg="验证码不正确!";
39                 session.setAttribute("msg", msg);
40                 request.getRequestDispatcher("/login.jsp").forward(request, response);
41                 return;
42             }
43         }else if(name==null||pwd==null||"".equals(name)||"".equals(pwd)){//如果输入的用户名或密码为空
44             String msg="用户名或密码不能为空!";
45             session.setAttribute("msg", msg);
46             request.getRequestDispatcher("/login.jsp").forward(request, response);
47             return;
48         }else{//其他情况
49             String msg="您输入的用户名或密码不正确,请重新输入!";
50             session.setAttribute("msg", msg);
51             request.getRequestDispatcher("/login.jsp").forward(request, response);
52             return;
53         }
54     }
55 
56 }

 4. VerifyCodeServlet

 1 package com.review_javaee09.web.servlet;
 2 
 3 import java.awt.image.BufferedImage;
 4 import java.io.IOException;
 5 
 6 import javax.servlet.ServletException;
 7 import javax.servlet.http.HttpServlet;
 8 import javax.servlet.http.HttpServletRequest;
 9 import javax.servlet.http.HttpServletResponse;
10 import javax.servlet.http.HttpSession;
11 
12 import com.cheryl.commons.VerifyCode;
13 
14 
15 public class VerifyCodeServlet extends HttpServlet {
16     
17     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
18         doPost(request,response);
19     }
20 
21     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
22         request.setCharacterEncoding("utf-8");
23         response.setContentType("text/html;charset=utf-8");
24         
25         VerifyCode vc=new VerifyCode(); //得到验证码对象
26         BufferedImage image = vc.getImage();  //得到验证码图片
27         String text = vc.getText(); //得到验证码的文本
28         HttpSession session = request.getSession(); //将验证码存放到session中
29         session.setAttribute("verify", text);
30         VerifyCode.output(image, response.getOutputStream()); //将验证码图片输出到页面
31     
32     }
33 
34 }

5. VerifyCode.java(验证码不用自己写,网上有很多源码可以拿来使用,当然也可以自己写)

  1 package com.cheryl.commons;
  2 
  3 import java.awt.BasicStroke;
  4 import java.awt.Color;
  5 import java.awt.Font;
  6 import java.awt.Graphics2D;
  7 import java.awt.image.BufferedImage;
  8 import java.io.IOException;
  9 import java.io.OutputStream;
 10 import java.util.Random;
 11 
 12 import javax.imageio.ImageIO;
 13 
 14 public class VerifyCode {
 15     private int w = 70;//设置缓冲区的宽
 16     private int h = 35;//设置缓冲区的宽
 17      private Random r = new Random();
 18      //// {"宋体", "华文楷体", "黑体", "华文新魏", "华文隶书", "微软雅黑", "楷体_GB2312"}
 19     private String[] fontNames  = {"宋体", "华文楷体", "黑体", "华文新魏", "华文隶书", "微软雅黑", "楷体_GB2312"};
 20     //源
 21     private String codes  = "23456789abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ";
 22     // 背景颜色
 23     private Color bgColor  = new Color(255, 255, 255);
 24     // 保存随机生成的图片当中的内容。
 25     private String text ;
 26     
 27     // 随机生成颜色
 28     private Color randomColor () {
 29         int red = r.nextInt(150);
 30         int green = r.nextInt(150);
 31         int blue = r.nextInt(150);
 32         return new Color(red, green, blue);
 33     }
 34     
 35     // 随机生成字体
 36     private Font randomFont () {
 37         int index = r.nextInt(fontNames.length);
 38         String fontName = fontNames[index];//根据随机的索引,获取随机字体
 39         int style = r.nextInt(4);//0,1,2,3, 0:没有任何样式,1,加粗,2,斜体,3,加粗和斜体  PLAIN(0)、BOLD(1)、ITALIC(2) 或 BOLD+ITALIC(3)。 
 40         int size = r.nextInt(5) + 24; //随机生成字号
 41         return new Font(fontName, style, size);
 42     }
 43     
 44     // 画干扰线
 45     private void drawLine (BufferedImage image) {
 46         int num  = 3;//花三条干扰线
 47         Graphics2D g2 = (Graphics2D)image.getGraphics();
 48         for(int i = 0; i < num; i++) {
 49             int x1 = r.nextInt(w);
 50             int y1 = r.nextInt(h);
 51             int x2 = r.nextInt(w);
 52             int y2 = r.nextInt(h); 
 53             g2.setStroke(new BasicStroke(1.5F)); 
 54             g2.setColor(Color.BLUE); //给干扰线设置了颜色
 55             g2.drawLine(x1, y1, x2, y2);//划线
 56         }
 57     }
 58     
 59     //随机生成字符
 60     private char randomChar () {
 61         int index = r.nextInt(codes.length());
 62         return codes.charAt(index);
 63     }
 64     
 65     // 得到一个缓冲区
 66     private BufferedImage createImage () {
 67         // 获取一个缓冲区
 68         BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); 
 69         // 得到一个画笔
 70         Graphics2D g2 = (Graphics2D)image.getGraphics(); 
 71         // 设置画笔的颜色 白颜色
 72         g2.setColor(this.bgColor);
 73         // 填充图片的缓冲区。
 74         g2.fillRect(0, 0, w, h);
 75         // 将缓冲区返回。
 76          return image;
 77     }
 78     
 79     // 调用该方法,可以得到验证码
 80     public BufferedImage getImage () {
 81         BufferedImage image = createImage();//创建图片的缓冲区
 82         Graphics2D g2 = (Graphics2D)image.getGraphics();//得到绘制环境(画笔)
 83         StringBuilder sb = new StringBuilder();//定义一个容器,用来装在生成的验证码
 84         //向图片当中画四个字符
 85         for(int i = 0; i < 4; i++)  {//循环四次,每次生成一个字符
 86             String s = randomChar() + "";//随机成成一个字符
 87             sb.append(s); //将生成的字符放在缓冲区
 88             float x = i * 1.0F * w / 4; //设置当前字符的x轴坐标
 89             g2.setFont(randomFont()); //设置随机生成的字体
 90             g2.setColor(randomColor()); //设置字符的随机颜色
 91             g2.drawString(s, x, h-5); //画图
 92         }
 93         this.text = sb.toString(); //随机生成的图片的内容复制给this.text
 94         drawLine(image); //画干扰线
 95         return image;        
 96     }
 97     
 98     // 获取图片当中的内容
 99     public String getText() {
100         return text;
101     }
102     
103     // 保存图片到指定的输出流
104     public static void output (BufferedImage image, OutputStream out) 
105                 throws IOException {
106         ImageIO.write(image, "JPEG", out);
107     }
108 
109 }