6.后台验证码-session作用域
首先要有生成验证码图片和验证码文字的逻辑
package cn.bingou.util; import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.Random;
import javax.imageio.ImageIO;
/**
* 动态生成图片
*/
public class VerifyCode {
// {"宋体", "华文楷体", "黑体", "华文新魏", "华文隶书", "微软雅黑", "楷体_GB2312"}
private static String[] fontNames = { "宋体", "华文楷体", "黑体", "微软雅黑", "楷体_GB2312" };
// 可选字符
//"23456789abcdefghjkmnopqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ";
private static String codes = "23456789abcdefghjkmnopqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ";
// 背景色
private Color bgColor = new Color(255, 255, 255);
// 基数(一个文字所占的空间大小)
private int base = 30;
// 图像宽度
private int width = base * 4;
// 图像高度
private int height = base;
// 文字个数
private int len = 4;
// 设置字体大小
private int fontSize = 22;
// 验证码上的文本
private String text; private BufferedImage img = null;
private Graphics2D g2 = null; /**
* 生成验证码图片
*/
public void drawImage(OutputStream outputStream) {
// 1.创建图片缓冲区对象, 并设置宽高和图像类型
img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 2.得到绘制环境
g2 = (Graphics2D) img.getGraphics();
// 3.开始画图
// 设置背景色
g2.setColor(bgColor);
g2.fillRect(0, 0, width, height); StringBuffer sb = new StringBuffer();// 用来装载验证码上的文本 for (int i = 0; i < len; i++) {
// 设置画笔颜色 -- 随机
// g2.setColor(new Color(255, 0, 0));
g2.setColor(new Color(getRandom(0, 150), getRandom(0, 150),getRandom(0, 150))); // 设置字体
g2.setFont(new Font(fontNames[getRandom(0, fontNames.length)], Font.BOLD, fontSize)); // 旋转文字(-45~+45)
int theta = getRandom(-45, 45);
g2.rotate(theta * Math.PI / 180, 7 + i * base, height - 8); // 写字
String code = codes.charAt(getRandom(0, codes.length())) + "";
g2.drawString(code, 7 + i * base, height - 8);
sb.append(code);
g2.rotate(-theta * Math.PI / 180, 7 + i * base, height - 8);
} this.text = sb.toString(); // 画干扰线
for (int i = 0; i < len + 2; i++) {
// 设置画笔颜色 -- 随机
// g2.setColor(new Color(255, 0, 0));
g2.setColor(new Color(getRandom(0, 150), getRandom(0, 150),
getRandom(0, 150)));
g2.drawLine(getRandom(0, 120), getRandom(0, 30), getRandom(0, 120),
getRandom(0, 30));
}
/**
* 绘制边框
*/
// 设置边框的颜色
g2.setColor(Color.GRAY);
// 绘制边框
g2.drawRect(0, 0, width-1, height-1); // 4.保存图片到指定的输出流
try {
ImageIO.write(this.img, "JPEG", outputStream);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}finally{
// 5.释放资源
g2.dispose();
}
} /**
* 获取验证码字符串
* @return
*/
public String getCode() {
return this.text;
} /*
* 生成随机数的方法
*/
private static int getRandom(int start, int end) {
Random random = new Random();
return random.nextInt(end - start) + start;
} public static void main(String[] args) throws Exception {
VerifyCode vc = new VerifyCode();
vc.drawImage(new FileOutputStream("d:/vc.jpg"));
System.out.println("执行成功~!");
}
}
VerifyCode
在前台添加一个验证码的点击事件,当用户点击验证码时自动切换验证码
// 为img标签添加一个点击事件
$("#valiImage").click(function(){
// 每次点击修改src属性的值,在后面拼接一个不同的参数
// 获取当前时间的毫秒值表示
var timeStr=new Date().getTime();
// 将毫秒之直接拼接在url后面,保证每次点击url的值不同
var url="/ValiImageServlet?time="+timeStr;
// 使用生成的url给img标签的src属性赋值
$("#valiImage").attr("src",url);
});
此时会请求后台处理逻辑 ValiImageServlet
package cn.bingou.web; import java.io.IOException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import cn.bingou.util.VerifyCode; public class ValiImageServlet extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// 1.接收请求 // 2.调用工具类,生成验证码图片
VerifyCode vc=new VerifyCode();
// 3.将生成的验证码图片存入response实体中
vc.drawImage(resp.getOutputStream());
// 4.控制浏览器不要缓存验证码
// 获取验证码字符串
String text=vc.getCode();
// 将生成的验证码文本输出到控制台
System.out.println("text="+text);
// 获取用户的Session对象
HttpSession session=req.getSession();
// 将正确的验证码文本传入Session作用域
session.setAttribute("text", text);
// 不要缓存验证码
resp.setHeader("Pragma", "no-cache");
resp.setHeader("Cache-Control", "no-cache"); } public void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doGet(req, resp);
} }
后台ValiImageServlet将从VerifyCode得到的验证码图片和文字传输到前台,通过session作用域传递
前台点击提交表单按钮,表单信息将会传输到RegistServlet进行验证
package cn.bingou.web; import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import cn.bingou.util.JDBCUtils;
import cn.bingou.util.WebUtils; public class RegistServlet extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException { // 1.请求乱码问题
// 请求乱码-POST请求
req.setCharacterEncoding("utf-8");
// 应答乱码问题
resp.setContentType("text/html;charset=utf-8"); // 2.接收表单参数
String username = req.getParameter("username");
String password = req.getParameter("password");
String password2 = req.getParameter("password2");
String nickname = req.getParameter("nickname");
String email = req.getParameter("email");
String valistr = req.getParameter("valistr"); // 3.验证表单
// 1)非空验证 if(WebUtils.isEmpty(username)){ // 用户名为空验证
// 向request作用域中添加错误提示信息
req.setAttribute("errMsg", "用户名不能为空!");
// 将请求转发给regist.jsp,forward():请求转发
req.getRequestDispatcher("/regist.jsp").forward(req, resp);
// 如果用户输入为空,直接返回
return;
}
if(WebUtils.isEmpty(password)){ // 密码为空验证
req.setAttribute("errMsg", "密码不能为空!");
req.getRequestDispatcher("/regist.jsp").forward(req, resp);
return;
}
if(WebUtils.isEmpty(nickname)){ // 昵称为空验证
req.setAttribute("errMsg", "昵称不能为空!");
req.getRequestDispatcher("/regist.jsp").forward(req, resp);
return;
}
if(WebUtils.isEmpty(email)){ // 邮箱为空验证
req.setAttribute("errMsg", "邮箱不能为空!");
req.getRequestDispatcher("/regist.jsp").forward(req, resp);
return;
} // 2)密码一致验证
if(!password.equals(password2)){
// 如果密码与确认密码不一样,则输出错误
req.setAttribute("errMsg", "密码不一致");
req.getRequestDispatcher("/regist.jsp").forward(req, resp);
return;
} // 3)邮箱格式验证
// abc@123.163.com
String reg="^\\w+@\\w+(\\.\\w+)+$";
if(!email.matches(reg)){
req.setAttribute("errMsg", "邮箱格式不符");
req.getRequestDispatcher("/regist.jsp").forward(req, resp);
return;
} // 4)用户名是否存在
String sql1="select * from user where username=?";
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs=null;
try {
conn=JDBCUtils.getConnection();
ps=conn.prepareStatement(sql1);
ps.setString(1, username);
rs=ps.executeQuery();
while(rs.next()){ // 寻找用户名,直到找到为止
req.setAttribute("errMsg", "用户名已存在");
req.getRequestDispatcher("/regist.jsp").forward(req, resp);
return;
}
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("验证用户名时数据库出现异常:"+e.getMessage());
} finally{
JDBCUtils.close(conn, ps, rs);
} // 5)验证码验证
if(WebUtils.isEmpty(valistr)){ // 验证码为空验证
req.setAttribute("errMsg", "验证码不能为空!");
req.getRequestDispatcher("/regist.jsp").forward(req, resp);
return;
} else{
// 验证码不为空,执行验证码内容验证
// 获取保存在session中的正确验证码
HttpSession session=req.getSession(false);// 如果当前Session没有就为null
boolean flag=true; // 默认验证码没有问题
if(session==null && session.getAttribute("text")==null){
// 没有session对象,或者session中没有正确的验证码文本
flag=false;
}else{
String text=(String) session.getAttribute("text");
if(!valistr.equalsIgnoreCase(text)){
// 用户输入的文本和正确文本不一致
flag=false;
}
}
if(flag==false){
// 向request作用域中添加错误提示信息
req.setAttribute("errMsg", "验证码错误");
// 将请求转发给regist.jsp
req.getRequestDispatcher("/regist.jsp").forward(req, resp);
return;
}
} // 4.数据存入数据库
// 验证信息没有问题,将用户提交的注册信息提交到数据库
String sql2="insert into user values(null,?,?,?,?)";
Connection conn2=null;
PreparedStatement ps2=null;
try {
conn2=JDBCUtils.getConnection();
ps2=conn2.prepareStatement(sql2);
ps2.setString(1, username);
ps2.setString(2, password);
ps2.setString(3, nickname);
ps2.setString(4, email);
ps2.executeUpdate();
int i=ps2.executeUpdate();
if(i>0){
// 保存成功-提示成功信息,定时刷新到首页
resp.getWriter().write("<h1 style='text-align:center;color:red'>恭喜您,注册成功!3秒后自动跳转首页</h1>");
// 实现定时刷新
resp.setHeader("refresh", "3;url="+req.getContextPath()+"/index.jsp");
}else{
req.setAttribute("errMsg", "注册出现异常,请稍后重试...");
req.getRequestDispatcher("/regist.jsp").forward(req, resp);
return;
}
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("注册数据出现异常:"+e.getMessage());
} finally{
JDBCUtils.close(conn2, ps2, rs);
}
} public void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doGet(req, resp);
} }
6.后台验证码-session作用域的更多相关文章
- yxcms后台验证码不显示?怎么取消yxcms后台验证码
嗨,大家好,我是YXCMS的小M老湿,(其实还是习惯大家叫我猪猪吧!)今天又要分享一则yxcms的使用技巧,当然也是yxcms用户在使用过程中很容易出现的小白问题,当然还是同样,yxcms的大神级别的 ...
- Dede后台验证码不显示解决方法详解(dedecms 5.7)
今天朋友问我他本地与服务器上安装了dedecms5.7无法显示验证码,一般这种情况很少见,一般情况就是服务器设置问题,还有临时目录的权限问题 Dede后台验证码不显示或不正常分三种情况,下面来逐一分析 ...
- Django之验证码 + session 认证
验证码 + session认证 目录结构 . └── project ├── app01 │ ├── admin.py │ ├── apps.py │ ├── __init__.py │ ...
- python运维开发(二十一)----文件上传和验证码+session
内容目录: 文件上传 验证码+session 文件和图片的上传功能 HTML Form表单提交,实例展示 views 代码 HTML ajax提交 原生ajax提交,XMLHttpRequest方式上 ...
- Struts自动装配和四种放入Session作用域的方式
---恢复内容开始--- Struts三种自动装配的方式 第一种在Action类中定义和表单name相同的成员变量. 首先你定义一个Action类 页面: 第二种把成员变量提取到一个类中, 在Act ...
- python第一百一十八天---ajax--图片验证码 + Session
原生AJAX Ajax主要就是使用 [XmlHttpRequest]对象来完成请求的操作,该对象在主流浏览器中均存在(除早起的IE),Ajax首次出现IE5.5中存在(ActiveX控件). 1.Xm ...
- ThinkCMF后台验证码不显示,无法登陆怎么办?
ThinkCMF5在本地部署之后,过一段时间可能会莫名其妙的出现后台验证码不显示的问题,不明就里.着急登陆后台的话,可以先禁用后台验证码,方法如下: 打开文件:/app/admin/controlle ...
- Dede后台验证码不显示解决方法详解(dedecms 5.7 UTF-8版本)
织梦(dede)后台验证码不显示有多种可能性,我前几天测试就碰到了这个问题,结果百度搜索了一圈,挨个修改了下,还是不行,最后是在解决另外一个后台上传图片不成功的问题的时候,歪打正着的把验证码问题给解决 ...
- dedecms织梦系统后台验证码图片不显示的解决方法
网站迁移后,dedecms织梦系统后台验证码图片不显示的解决方法通用解决方案-取消后台验证码功能因为没有验证码,不能进后台,所以修改php文件源代码:方法一:打开dede/login.php 找到如下 ...
随机推荐
- restful 初探
1.restful 是一种编程规范,能够实现现在丰富的客户端(安卓,ios,桌面等)平等的访问服务器提供的服务. 2.重要的是利用restful来设计实现 符合该编程规范的api.
- sublime text3 设置快速生成代码
依次打开 Tools > Developer(开发者选项) > new Snippet(新的代码块).可以看到注释的说明: <snippet> <content>& ...
- MyEclipse持续性开发教程:用JPA和Spring管理数据(二)
MyEclipse红运年货节 在线购买低至69折!火爆开抢>> [MyEclipse最新版下载] 本教程介绍了MyEclipse中的一些基于JPA / Spring的功能.有关设置JPA项 ...
- Linux C 数据结构->双向链表(阴阳在六,何以言九~)
0. 弄完了单链表,在看双向链表.怎么整?多写,多想,想不通画出来在想,再写,再模仿~ 1. 没啥说的,敲代码~ 说点啥呢,注意自己的代码风格哦,要符合"潮流",不要独树一帜 ...
- Struck: Structured Output Tracking with Kernels
reference: Struck: Structured Output Tracking with Kernels hot topic: tracking-by-detection methods, ...
- OK335xS Linux Qt make: icpc: Command not found
OK335xS Linux Qt make: icpc: Command not found 一.出错现象: make: icpc: Command not found make: *** [main ...
- python--selenium多线程执行用例实例/执行多个用例
python--selenium多线程执行用例实例/执行多个用例 我们在做selenium测试的时候呢,经常会碰到一些需要执行多个用例的情况,也就是多线 程执行py程序,我们前面讲过单个的py用例怎么 ...
- Appium笔记(一) 丶Appium的自我介绍
一.我是谁,我的特点是什么 Appium是一款开源测试自动化框架,可用于原生.混合和移动Web应用程序.它使用WebDriver协议驱动iOS,Android和Windows应用程序.重要的是,App ...
- 【BZOJ3295】【CQOI2011】动态逆序对
cdq分治经典例题,然而智商掉线傻逼错误坑了两天 原题: 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你 ...
- [团队项目]SCRUM项目6.0 7.0
6.0----------------------------------------------------- sprint演示 1.坚持所有的sprint都结束于演示. 团队的成果得到认可,会感觉 ...