web登录验证码生成
目的:实现在登录表单验证码的生成
声明:我是参考别人的例子,代码大部分也是引用的
原理:是在要显示验证码的地方用,它的src指向了另一个生成验证码的jsp页面(用controller的url指向一个jsp页面),在生成验证码jsp页面的java代码里生成一张验证码图片
代码里注释已经非常详情,这里就不做多说了!
提交表单的登录页面 login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" import="java.util.*" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8"/>
<title>登录</title>
<%
pageContext.setAttribute("APP_PATH",request.getContextPath());
%>
<script type="text/javascript">
/* 刷新验证码 */
function change_yanzhengma()
{
// 这个src也可以用相对路径
// 这个flag=Math.random()很关键,作用是每次传的值不同,才可以实现<img>的src的局部刷新,没有这个src不会变,
// 因为请求参数一样,浏览器不会重新请求,这里每次传的参数不一样,浏览器就会每次发出请求,实际上后台并没有接受flag这个参数
document.getElementById("checkcode_img").src = "changeCode?flag="+Math.random();
}
function checkLoginInfo()
{
if (form1.userName.value == "" || form1.userName.value == null)
{
alert("用户名不能为空");
form1.userName.focus();
return false;
}
else if (form1.userCode.value == "" || form1.userCode.value == null)
{
alert("验证码不能为空");
form1.yanzhengma.focus();
return false;
}
return true;
}
</script>
</head>
<body>
<%--想要用js验证表单,返回false就不提交,必须要 onsubmit="return functionName();" 少了 return 一样会提交--%>
<form action="loginCheck" method="post" name="form1" onsubmit="return checkLoginInfo();">
请输入用户名:<input type="text" name="userName" id="userName"/>
<br/>
<%--src路径直接用controler指定的url,这个url是直接return一个jsp页面,那个页面没有边框只有图,直接显示在这里--%>
<img title="刷新验证码" alt="刷新验证码" src="${APP_PATH}/changeCode" border="0" id="checkcode_img" onClick="change_yanzhengma();" />
<br/>
请输入验证码:<input type="text" name="code" />
<br/>
<input type="submit" value="确认登录">
<br/>
<!-- 保存登录失败时显示给用户的提示信息 -->
<span color="red">
<%--回显完信息,立即将session信息删除,防止重新刷新页面还看到这条信息--%>
${sessionScope.loginError } <%session.removeAttribute("loginError"); %>
</span>
</form>
</body>
</html>
生成验证码的 jsp页面 changeCode.jsp
<%@ page contentType="text/html;charset=gbk" language="java" import="java.awt.*,java.awt.image.*,java.util.*,javax.imageio.*"%>
<%@ page import="java.io.OutputStream"%>
<%-- 采用JPG格式的图片验证码 --%>
<%--这里之所以用声明语句块,是因为这是一个方法,java代码块编译后是放到servlet类的方法里面,方法里面不可以再有方法,会报错。
而声明语句块是编译后在servlet类里方法外,作为成员变量,可以声明一个方法--%>
<%!Color getRandColor(int fc, int bc) //随机生成图片中rgb的值
{
Random random = new Random();
if (fc > 255)
fc = 255;
if (bc > 255)
bc = 255;
int r = fc + random.nextInt(bc - fc);
int g = fc + random.nextInt(bc - fc);
int b = fc + random.nextInt(bc - fc);
return new Color(r, g, b);
}
%>
<%
try
{
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
int width = 75, height = 30;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
OutputStream os = response.getOutputStream();
Graphics g = image.getGraphics(); // 画笔
Random random = new Random();
// 设置画笔的颜色
g.setColor(getRandColor(200, 250));
// 画图,生成干扰图片
g.fillRect(0, 0, width, height);
//字体等样式
g.setFont(new Font("Times New Roman", Font.PLAIN, 25));
g.setColor(getRandColor(160, 200));
//生成图像内部的干扰线条
for (int i = 0; i < 155; i++)
{
int x = random.nextInt(width);
int y = random.nextInt(height);
int xl = random.nextInt(12);
int yl = random.nextInt(12);
//绘制干扰线条
g.drawLine(x, y, x + xl, y + yl);
}
String sRand = "";
//生成4个随机的、有彩色的验证码
for (int i = 0; i < 4; i++)
{
//生成一位验证码的值
String rand = String.valueOf(random.nextInt(10));
sRand += rand;
g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));
//把生成的验证码值画进图对象里,后面两个参数是生成的位置
g.drawString(rand, 14 * i + 11, 23);
}
session.setAttribute("code_inSession", sRand);
g.dispose();
//生成JPEG格式的图片验证码
ImageIO.write(image, "gif", os);
os.flush();
os.close();
os = null;
// 用来将缓冲区的数据立即输出到浏览器当中
response.flushBuffer();
/* 两句关键代码 */
out.clear();
out = pageContext.pushBody();
}
catch (IllegalStateException e)
{
System.out.println(e.getMessage());
e.printStackTrace();
}
%>
controller部分代码
// 验证码登录页面
@RequestMapping("/loginPage")
public String loginPage1(){
return "login_code/login";
}
// 更新验证码,换验证码
@RequestMapping("/changeCode")
public String checkcode(){
return "login_code/changeCode";
}
// 验证验证码是否正确
@RequestMapping("/loginCheck")
public String loginCheck(String username,String code, HttpServletRequest request,HttpServletResponse response){
HttpSession session = request.getSession();
// 获取session里的验证码,然后删除
String sessionCode = (String)session.getAttribute("code_inSession");
session.removeAttribute("code_inSession");
if (!code.equals(sessionCode))
{
// 验证码错误
session.setAttribute("loginError", "验证码错误");
// 重定向,redirect: 后面跟controller的url路径,不同controller也可以,记得要加 /
// 请求转发,forward: 用法一样 用重定向是防止表单重复提交的简单解决方法
return "redirect:/loginPage";
}else
{
//用户名密码验证
return "redirect:/main";
}
}
@RequestMapping("/main")
public String mainPage(){
return "login_code/main";
}
最后给一个简单的验证通过页面 main.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8"/>
<title>main页面</title>
</head>
<body>
验证成功!
</body>
</html>
还没有评论,来说两句吧...