首先要有生成验证码图片和验证码文字的逻辑

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作用域的更多相关文章

  1. yxcms后台验证码不显示?怎么取消yxcms后台验证码

    嗨,大家好,我是YXCMS的小M老湿,(其实还是习惯大家叫我猪猪吧!)今天又要分享一则yxcms的使用技巧,当然也是yxcms用户在使用过程中很容易出现的小白问题,当然还是同样,yxcms的大神级别的 ...

  2. Dede后台验证码不显示解决方法详解(dedecms 5.7)

    今天朋友问我他本地与服务器上安装了dedecms5.7无法显示验证码,一般这种情况很少见,一般情况就是服务器设置问题,还有临时目录的权限问题 Dede后台验证码不显示或不正常分三种情况,下面来逐一分析 ...

  3. Django之验证码 + session 认证

    验证码 + session认证 目录结构 . └── project ├── app01 │   ├── admin.py │   ├── apps.py │   ├── __init__.py │  ...

  4. python运维开发(二十一)----文件上传和验证码+session

    内容目录: 文件上传 验证码+session 文件和图片的上传功能 HTML Form表单提交,实例展示 views 代码 HTML ajax提交 原生ajax提交,XMLHttpRequest方式上 ...

  5. Struts自动装配和四种放入Session作用域的方式

    ---恢复内容开始--- Struts三种自动装配的方式 第一种在Action类中定义和表单name相同的成员变量. 首先你定义一个Action类 页面: 第二种把成员变量提取到一个类中,  在Act ...

  6. python第一百一十八天---ajax--图片验证码 + Session

    原生AJAX Ajax主要就是使用 [XmlHttpRequest]对象来完成请求的操作,该对象在主流浏览器中均存在(除早起的IE),Ajax首次出现IE5.5中存在(ActiveX控件). 1.Xm ...

  7. ThinkCMF后台验证码不显示,无法登陆怎么办?

    ThinkCMF5在本地部署之后,过一段时间可能会莫名其妙的出现后台验证码不显示的问题,不明就里.着急登陆后台的话,可以先禁用后台验证码,方法如下: 打开文件:/app/admin/controlle ...

  8. Dede后台验证码不显示解决方法详解(dedecms 5.7 UTF-8版本)

    织梦(dede)后台验证码不显示有多种可能性,我前几天测试就碰到了这个问题,结果百度搜索了一圈,挨个修改了下,还是不行,最后是在解决另外一个后台上传图片不成功的问题的时候,歪打正着的把验证码问题给解决 ...

  9. dedecms织梦系统后台验证码图片不显示的解决方法

    网站迁移后,dedecms织梦系统后台验证码图片不显示的解决方法通用解决方案-取消后台验证码功能因为没有验证码,不能进后台,所以修改php文件源代码:方法一:打开dede/login.php 找到如下 ...

随机推荐

  1. python元组()小括号

    names = ('jack','rose','tom','jerry','james','jerry') print(names) print(names[0]) #使用元组中的元素 print(n ...

  2. celery(一)分布式任务调度模块简介及运行环境

    Celery是Python开发的分布式任务调度模块. Celery本身不含消息服务,它使用第三方消息服务来传递任务. django下有个分支Django-Celery,可以结合django来实现任务的 ...

  3. 【DevExpress v17.2新功能预告】WinForms上的图表增强

    在WinForms Charts v17.2中,我们新增了一些有用的功能,开发人员和最终用户可能都会喜欢. 基于标准的过滤 Chart控件已经支持一系列的过滤,但是在这个版本中,我们用FilterCr ...

  4. mybatis左连接需要输出左表的指定内容与筛选

    SELECT rpl.ID, rpl.DID, rpl.TRADE_TYPE, rpl.TRADE_TIME, rpl.CALL_TIME, rpl.TRADE_ADDR, rpl.RECEIVE_P ...

  5. 插件PageHelper实现分页查询

    一,需求: CommonQuery--PyQueryBean PyQueryBean:鹏飞历史记录查询,以往哪些人对征信进行了查询.CommonQuery:查询条件:根据查询人(umName).被查询 ...

  6. 由pg_xlogdump统计信息想到的问题

    最近深入理解了Checkpoint的相关逻辑,再来看WAL日志的一些设置,又有了新的收获. 1.回顾pg_xlogdump出来的wal日志信息: 2.wal中FPI的占比很高问题分析: 3.重申ful ...

  7. IOS UIImage两种初始化的区别

    UIImage可以通过以下两种方式进行初始化: 1 //第一种初始化方式:[注意使用这种初始化的时候如果是png格式的可以不给后缀名,根据屏幕的的分辨率去匹配图片] 2 3 UIImage *imag ...

  8. docker使用web界面管理Registry

    1:安装 docker-registry-web项目   [root@Docker ~]#docker pull atcol/docker-registry-ui   2:docker run镜像   ...

  9. hot load那点事

    热加载,最初接触的时候是使用create-react-app的时候,创建一个项目出来,修改一点代码,页面自动刷新了,贫道当时就感叹,这是造福开发者的事情. 再后来编写静态页面的时候使用 VS Code ...

  10. Complete the Word

    ZS the Coder loves to read the dictionary. He thinks that a word is nice if there exists a substring ...