目标:要实现一个登陆界面,且含有验证码输入,输入验证码后可检验输入的正确性
目录
- jsp页面
- 验证码生成
- 跳转检验
- xml文件配置
- 结果展示:
jsp页面
登陆页面的前端login.jsp文件内容:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>登陆页面</title>
</head>
<body>
<script>
function reloadCode(){
var time=new Date().getTime();
//由于传过去的时间不一样,所以不是同一个请求 同一个请求时不能实现更新
document.getElementById("imageCode").src="<%=request.getContextPath()%>/servlet/CodeServlet?d="+time;
}
</script>
<h1 style="align:center;margin:auto"> 登陆界面 </h1>
<div style = "margin:auto auto;width:320px;height:300px;margin-top:100px;
position:'center';border:3px;border-color:blue;">
<form action="/ex_7/servlet/ValidataServlet" method="post" style="margin:auto;width:250;height:82">
账号:<input name = "account" type = "text"><br>
密码:<input name = "password" type = "password"><br>
<div>
验证码:<input name="check_code" type = "text" width=60px height=20px value="验证码" />
<img border=0 src="/ex_7/servlet/CodeServlet" id = "imageCode" onclick="reloadCode()" style="cursor:pointer;">
</div>
<input type = "submit" value ="登陆" style="margin-left:100px;margin-top:10px;">
</form>
</div>
</body>
</html>
验证码生成
jsp页面对调用该CodeServlet.java的内容:
生成包含四个由数字:含大小写字母、随机字体和颜色、干扰线组成的一个验证码
各个板块在程序的注释中都有说明
package servlet;
import java.awt.*; //Graphics Color Font
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.*;
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;
public class CodeServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private String[] fontNames = {"Georgia", "Verdana", "Arial", "Tahoma",
"Time News Roman", "Courier New", "Arial Black", "Quantzite"};
//内存中创建图像 设置图像个宽高
private int width = 60,height=20;
public CodeServlet() {
super();
// TODO Auto-generated constructor stub
}
public String get_rand_digit_str() {
//取随机产生了的验证码(4位数字或字符)
Random rnd = new Random();
String str = "";
int x = rnd.nextInt(2);
if(x == 1) //大写字母
str += (char) (65+rnd.nextInt(26)); //随机字符
else if(x == 2) { //小写字母
str += (char) (97+rnd.nextInt(26));
}
else //数字
str+=String.valueOf(rnd.nextInt(9)); //随机一位数字
return str;
}
//获取 一种 随机颜色
public Color rand_color() {
Random random = new Random();
int r = random.nextInt(256);
int g = random.nextInt(256);
int b = random.nextInt(256);
return new Color(r, g, b);
}
//获取 一种 字体
public Font rand_font() {
Random rnd = new Random();
int fontindex = rnd.nextInt(fontNames.length-1); //随机索引
String str = fontNames[fontindex]; //获得该字体
int fontSize = (int) Math.round(Math.random() * 4 + 16);
return new Font(str, Font.PLAIN, fontSize);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setHeader("Cache-Control", "no-cache");
BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
//获取画笔
Graphics g = image.getGraphics();
//设定背景色
g.setColor(new Color(200,200,200));
g.fillRect(0, 0, width, height); //设置背景板大小 并涂上颜色
Random rnd = new Random();
//画干扰线
g.setColor(new Color(255,225,255));
//随机产生100个干扰线(点) ,使图像中验证码不易被其他程序探测到
for(int i =0;i<80;i++) {
int x =rnd.nextInt(width);
int y = rnd.nextInt(height);
int x1 = rnd.nextInt(2);
int y1 = rnd.nextInt(4);
g.drawOval(x,y,x+x1,y+y1);
}
//画一定个数的字符
String randStr = "";
for (int i = 0; i < 4; i++) {
String str = get_rand_digit_str(); //随机单个字符
randStr += str; //连接字符串
g.setFont(rand_font());//随机字体
// 将认证码显示到图象中
g.setColor(rand_color());
g.drawString(str, 13 * i + 6, 16); //i控制横坐标 将验证码显示到图像中
}
//将验证码存入session
HttpSession session = request.getSession();
session.setAttribute("randStr",randStr); //连接的字符串为验证码
//输出图像到页面
ImageIO.write(image,"JPG",response.getOutputStream());
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
跳转检验
检验验证码输入是否正确,忽略大小写(validataServlet.java内容):
package servlet;
import java.io.IOException;
import java.io.PrintWriter;
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;
@WebServlet("/ValidataServlet")
public class ValidataServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.getWriter().append("Served at: ").append(request.getContextPath());
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
//得到提交的验证码
String code = request.getParameter("check_code");
//获取session中的验证码
HttpSession session = request.getSession();
String randStr = (String)session.getAttribute("randStr");
response.setCharacterEncoding("gb2312");
PrintWriter out = response.getWriter();
// if(!code.equals(randStr)) { //不能忽略大小写
if(!code.equalsIgnoreCase(randStr)) { //忽略大小写的字符串比较
out.println("验证码错误");
}
else {
out.println("验证码正确!跳转到LoginServlet.....");
}
}
}
xml文件配置
配置两个位于服务器端的servlet文件的路径:
<servlet>
<servlet-name>CodeServlet</servlet-name>
<servlet-class>servlet.CodeServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CodeServlet</servlet-name>
<url-pattern>/servlet/CodeServlet</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>ValidataServlet</servlet-name>
<servlet-class>servlet.ValidataServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ValidataServlet</servlet-name>
<url-pattern>/servlet/ValidataServlet</url-pattern>
</servlet-mapping>
结果展示:
运行login.jsp 显示内容:
输入对应的验证码(正确,无视大小写):
点击登陆(或直接回车),显示内容:
输入错误时:
错误结果: