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

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. 数据结构(C语言)关于查找与排序

    1)利用readData()函数从data1.txt中读入不同规模的数据存入数组,编写基于数组的顺序查找算法,测试数据量为1万.5万.10万.20万.30万.40万和50万时的数据查询时间. 算法代码 ...

  2. ZOJ2540 Form a Square

    Form a Square 题意就是 判断 给你四个点,能否组成一个正方形 要点: 格式很重要, 很重要!!! 数据很小,直接暴力 四个点判断是否为正方形,只需将所有可能的边长度算出来,然后选其中最短 ...

  3. 可远程定位、解锁并启动汽车的黑客设备OwnStar

    GM告诉WIRED,OnStar用户不必担心之前存在的问题,现在已经修复了之前可被利用的漏洞,. 然而,Kamkar表示问题还是没有被解决,并且已经由GM汇报了该问题. 在任何已经连接的汽车上,GM的 ...

  4. tp5中捕获异常的配置

    首选在配置文件中加入配置如下 // 异常处理handle类 留空使用 \think\exception\Handle    'exception_handle'       => '\\app\ ...

  5. 触电(by quqi99)

    高压电线杆相关的触电方式主要是两种: 一是跨步电压,高压电线落在地面时,如果人恰好在这个范围内步行时,就会从一只脚到跨下再到另一只脚到地形成回路,这叫跨步电压.步子越大,电压越大(以落地点为圆心向外电 ...

  6. 常用增强学习实验环境 I (MuJoCo, OpenAI Gym, rllab, DeepMind Lab, TORCS, PySC2) (转载)

    原文地址:http://blog.csdn.net/jinzhuojun/article/details/77144590 和其它的机器学习方向一样,强化学习(Reinforcement Learni ...

  7. stdlib.h

    stdlib 头文件即standard library标准库头文件.stdlib.h里面定义了五种类型.一些宏和通用工具函数. 1 类型例如size_t.wchar_t.div_t.ldiv_t和ll ...

  8. tiny4412 UART for C printf Demo

    /************************************************************************** * tiny4412 UART for C pr ...

  9. [LeetCode&Python] Problem 872. Leaf-Similar Trees

    Consider all the leaves of a binary tree.  From left to right order, the values of those leaves form ...

  10. Codeforces 1096G. Lucky Tickets【生成函数】

    LINK 题目大意 很简单自己看 思路 考虑生成函数(为啥tags里面有一个dp啊) 显然,每一个指数上是否有系数是由数集中是否有这个数决定的 有的话就是1没有就是0 然后求出这个生成函数的\(\fr ...