关于验证码的使用(使用servlet实现验证码)~
前提:所使用的页面包括登录页面(login.jsp)、登录成功的页面(index.jsp)、验证码(VerifyCode.java)、登录的Servlet(LoginServlet)、处理验证码的Servlet(VerifyCodeServlet)
整个实现工程的目录结构
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 }