Java基于springMVC的验证码案例
```
Java验证码案例(基于springMVC方式) 验证码工具类
package com.ekyb.common.util; import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics; import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random; import javax.servlet.http.HttpServletRequest; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; /**
* 图片验证码生成类
*
* @author gx
*/
@Component("imageCode")
public class ImageCode {
/*
* Spring 3支持@value注解的方式获取properties文件中的配置值,大简化了读取配置文件的代码。
* 在applicationContext.xml文件中配置properties文件,在bean中使用@value注解获取配置文件的值
* 即使给变量赋了初值也会以配置文件的值为准。
*/
@Value("${ImageCode.width}")
private int width; @Value("${ImageCode.height}")
private int height; @Value("${ImageCode.codeLength}")
private int codeLength; @Value("${ImageCode.randomString}")
private String randomString; @Value("${ImageCode.sessionKey}")
private String sessionKey; @Value("${ImageCode.font.name}")
private String fontName; @Value("${ImageCode.font.style}")
private int fontStyle; @Value("${ImageCode.font.size}")
private int fontSize; public BufferedImage getImage(HttpServletRequest request) {
// 在内存中创建图片
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 获取图片上下文
Graphics g = image.getGraphics();
// 生成随机类
Random random = new Random();
// 设定背景颜色
g.setColor(getRandColor(100, 250));
g.fillRect(0, 0, width, height);
// 设定字体
g.setFont(new Font(fontName, fontStyle, fontSize));
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, xl, y + yl);
}
// 取随机产生的认证码
String sRand = randomRand(codeLength);
int strWidth = width / 2 - g.getFontMetrics().stringWidth(sRand) / codeLength - fontSize;
int strHeight = height / 2 + g.getFontMetrics().getHeight() / 4;
for (int i = 0; i < codeLength; i++) {
String rand = sRand.substring(i, i + 1);
g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));
g.drawString(rand, 13 * i + 6 + strWidth, strHeight);
}
//System.out.println(sRand);
request.getSession().setAttribute(sessionKey, sRand);
request.setAttribute("sRand", sRand);
g.dispose();
return image;
} public static String randomResult(int length) {
String[] i = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "0" };
List<String> l = new ArrayList<String>();
l.addAll(Arrays.asList(i));
Random ran = new Random();
String s = "";
while (l.size() > 10 - length)
s += l.remove(ran.nextInt(l.size()));
s = s.replaceAll("^(0)(\\d)", "$2$1");
return s;
} // 给定范围获取随机颜色
public Color getRandColor(int fc, int bc) {
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); } private String randomRand(int n) {
String rand = "";
int len = randomString.length() - 1;
double r;
for (int i = 0; i < n; i++) {
r = ((Math.random())) * len;
rand = rand + randomString.charAt((int) r);
}
return rand;
} public int getWidth() {
return width;
} public void setWidth(int width) {
this.width = width;
} public int getHeight() {
return height;
} public void setHeight(int height) {
this.height = height;
} public int getCodeLength() {
return codeLength;
} public void setCodeLength(int codeLength) {
this.codeLength = codeLength;
} public String getRandomString() {
return randomString;
} public void setRandomString(String randomString) {
this.randomString = randomString;
} public String getSessionKey() {
return sessionKey;
} public void setSessionKey(String sessionKey) {
this.sessionKey = sessionKey;
} public String getFontName() {
return fontName;
} public void setFontName(String fontName) {
this.fontName = fontName;
} public int getFontStyle() {
return fontStyle;
} public void setFontStyle(int fontStyle) {
this.fontStyle = fontStyle;
} public int getFontSize() {
return fontSize;
} public void setFontSize(int fontSize) {
this.fontSize = fontSize;
} } -----------------------------------------------
读取config.properties配置的验证码和图片设置 #ImageCode生成器配置
ImageCode.width=120
ImageCode.height=38
ImageCode.codeLength=4
ImageCode.randomString=ABCDEFGHIJKLMNPQRSTUVWXYZ1234567890abcdefghijkmnpqrstuvwxyz
ImageCode.sessionKey=SESSIONCODE
ImageCode.font.name=Times New Roman
ImageCode.font.style=0
ImageCode.font.size=18
-------------------------------------------------
springMVC action中的代码
package com.ekyb.common.auContract.action; import java.io.IOException; import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping; import com.ekyb.common.util.ImageCode; @Controller
@RequestMapping(value="/yanZhen")
public class YanZhenMaAction {
/*
* @Resource默认按 byName 自动注入,是J2EE提供的, 需导入Package: javax.annotation.Resource;
*
* @Resource有两个中重要的属性:name和type ,而Spring将@Resource注解的name属性解析为bean的
* 名字,而type属性则解析为bean的类型。所以如果使用name属性,则使用byName的自动注入策略,而使用 type属性时则使用
* byType自动注入策略。如果既不指定name也不指定type属性,这时将通过反射机制使用by Name自动注入策略。
*/
@Resource
ImageCode imageCode; private static String sRand; @RequestMapping(value = "/openLoginPage")
public String openLoginPage(HttpServletRequest request, HttpServletResponse response) {
String msg=request.getParameter("msg");
if(msg==null&& msg.isEmpty()){
//得到用户读入框信息,如果没有输入或者为空,直接跳转到验证失败页面
return "error";
}else{
if(sRand.equalsIgnoreCase((msg))){
//得到用户输入的验证码匹配成功,跳转到验证通过页面
return "ok";
}else{
//得到用户输入的验证码匹配失败,跳转到验证失败页面
return "error";
}
}
} @RequestMapping(value = "/getImage")
public void getImage(HttpServletRequest request, HttpServletResponse response
) throws IOException {
// 禁止图片缓存
response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
response.setContentType("image/jpeg");
// 将图像输出到servlet输出流中
ServletOutputStream sos = response.getOutputStream();
ImageIO.write(imageCode.getImage(request), "jpeg", sos);
sos.close();
sRand=(String)request.getAttribute("sRand");
String result="ok"; }
}
-------------------------------------------------
前端登录页面代码
<%@ page language="java" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>登录</title>
</head>
<script type="text/javascript" src="js/jquery-easyui/jquery.min.js"></script>
<body>
<!-- cursor: pointer;鼠标放上显示手; title:鼠标放上时显示的文字 -->
<img id="imageCode" alt="" src="" onclick="checkcode()" style="cursor: pointer;" title="点我更换验证码" />
<br>
<form action="<%=basePath%>yanZhen/openLoginPage" method="post">
<input type="text" value="" name="msg">
<input type="submit" value="提交">
</form>
</body>
<script type="text/javascript">
var basePath = "<%=basePath%>";
$(function() {
checkcode();
});
function checkcode() {
var XMLHttp = null;
if (window.XMLHttpRequest) {
XMLHttp = new XMLHttpRequest();
} else if (window.ActiveXObject) {
XMLHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
XMLHttp.onreadystatechange = function() {
if (XMLHttp.readyState == 4) {
//改变验证码图片
$("#imageCode").attr("src",(basePath + "/yanZhen/getImage?" + new Date()));
}
};
//将请求发送出去
//加上 new Date()防止浏览器缓存,不重新发送请求
XMLHttp.open("GET", basePath + "/yanZhen/getImage?" + new Date(), true);
XMLHttp.send(null);
}
</script>
</html>
-----------------------------------------------------
登录成页面ok.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>"> <title>验证通过</title>
</head>
<body>
<h2>验证通过</h2>
</body>
</html>
-------------------------------------------------
登录失败页面error.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>"> <title>验证失败</title>
</head> <body>
<h2>验证失败</h2>
</body>
</html>
--------------------
==****注意个别路径根据自己的文件路劲更改==
如果有误请多指教
```
Java基于springMVC的验证码案例的更多相关文章
- java 基于tomcat的数据源案例
1.在context中定义数据源 <?xml version="1.0" encoding="UTF-8"?> <Context path=& ...
- Java 之 Response 发送验证码案例
定义一个 Servlet 用来在内存中生成 二维码图片,并向浏览器页面输出. import javax.imageio.ImageIO; import javax.servlet.ServletExc ...
- JAVA WEB快速入门之从编写一个基于SpringMVC框架的网站了解Maven、SpringMVC、SpringJDBC
接上篇<JAVA WEB快速入门之通过一个简单的Spring项目了解Spring的核心(AOP.IOC)>,了解了Spring的核心(AOP.IOC)后,我们再来学习与实践Maven.Sp ...
- Spring+springmvc+Mybatis整合案例 annotation版(myeclipse)详细版
Spring+springmvc+Mybatis整合案例 Version:annotation版 文档结构图: 从底层开始做起: 01.配置web.xml文件 <?xml version=&qu ...
- 基于SpringMVC+Ext.js的权限管理系统(无权限框架)
代码地址如下:http://www.demodashi.com/demo/12811.html 0.准备工作 注意!!! 本案例数据库相关请下载例子包,内有数据库脚本.EXCEL数据表和详细的设计文档 ...
- Spring+springmvc+Mybatis整合案例 xml配置版(myeclipse)详细版
Spring+springmvc+Mybatis整合案例 Version:xml版(myeclipse) 文档结构图: 从底层开始做起: 01.配置web.xml文件 <?xml version ...
- 基于SpringMVC下的Rest服务框架搭建【1、集成Swagger】
基于SpringMVC下的Rest服务框架搭建[1.集成Swagger] 1.需求背景 SpringMVC本身就可以开发出基于rest风格的服务,通过简单的配置,即可快速开发出一个可供客户端调用的re ...
- springMVC用法 以及一个简单的基于springMVC hibernate spring的配置
替代struts 1 web.xml中配置springmvc中央控制器 <?xml version="1.0" encoding="UTF-8"?> ...
- Java基于opencv实现图像数字识别(五)—投影法分割字符
Java基于opencv实现图像数字识别(五)-投影法分割字符 水平投影法 1.水平投影法就是先用一个数组统计出图像每行黑色像素点的个数(二值化的图像): 2.选出一个最优的阀值,根据比这个阀值大或小 ...
随机推荐
- AtCoder AGC #3 Virtual Participation
Havana真好听qwq AB题就不写了 SB C.BBuBBBlesort! 有一个长度为$n$的数列 你每次可以用两种操作 1.交换两个相邻元素 2.交换两个隔且仅隔了一个的元素 求把数列排成有序 ...
- Educational Codeforces Round 17 颓废记
又被虐了... (记一次惨痛的Codeforces) 好不容易登上去了Codeforces,22:35准时开打 第一题,一看:这不SB题嘛?直接枚举因数上啊.9min才过掉了pretest 第二题.. ...
- [转]从onload和DOMContentLoaded谈起
这篇文章是对这一两年内几篇dom ready文章的汇总(文章的最后会标注参考文章),因为浏览器进化的关系,可能他们现在的行为与本文所谈到的一些行为不相符.我也并没有一一去验证,所以本文仅供参考,在具体 ...
- Codeplus2017 12月赛——可做题1
题目:https://www.luogu.org/problemnew/show/P4030 可以发现一个矩阵是巧妙矩阵当且仅当其所有二阶子矩阵都是巧妙矩阵: 将不巧妙的二阶矩阵计为1,维护二维前缀和 ...
- break、continue和return的区别
break.continue和return的区别 break function myBreak() { for(var i = 0; i < 5; i++) { if(i == 3) { bre ...
- jquery中attr() & prop() 的区别与其实现方法
$(function(){ $('#check').attr('checked'); // undefind ???一头雾水 }) 在jquery中 attr 本来就是用来设置或者获取属性的,可是上面 ...
- 一 Kubernetes介绍
Kubenetes是一款由Google开发的开源的容器编排工具,它可以解决以下分布式环境下的问题: 调度 你已经得到了这个很棒的基于容器的应用程序? 太棒了!现在你需要确保它能够运行在它应该运行的地方 ...
- 关于WPF的弹出窗口
几个重要的概念需要清楚: Show和ShowDialog区别 1.调用Show方法后弹出子窗口后,线程会继续往下执行.调用ShowDialog方法弹出子窗口后,线程会阻塞,直到子窗口关闭才继续往下执行 ...
- Swoole 协程与 Go 协程的区别
Swoole 协程与 Go 协程的区别 进程.线程.协程的概念 进程是什么? 进程就是应用程序的启动实例. 例如:打开一个软件,就是开启了一个进程. 进程拥有代码和打开的文件资源,数据资源,独立的内存 ...
- 扩展thinkphp5的redis类方法
笔者在开发时发现,thinkphp5的自带redis类方法,只有简单的读取缓存.写入缓存的基本方法,远不能满足我们业务的需求.redis本身支持五种数据类型,string(字符串).hash(哈希). ...