---controller
/**
* 生成验证码
*/
@RequestMapping
(value =
"showVerifyCode"
, produces =
"image/jpeg"
)
public
void
showVerifyCode(HttpServletRequest request, HttpServletResponse response) {
// 生成随机字串
String verifyCode = VerifyCodeUtils.
generateVerifyCode
(4);
// 存入会话session
HttpSession session = request.getSession(
true
);
// 删除以前的
session.removeAttribute(
"verifyCode"
);
session.setAttribute(
"verifyCode"
, verifyCode.toLowerCase());
// 生成图片
int
w = 100, h = 34;
try
{
VerifyCodeUtils.
outputImage
(w, h, response.getOutputStream(), verifyCode);
}
catch
(IOException e) {
e.printStackTrace();
}
}
---Bean
package
com.kanq.platform.ocean.common;
import
java.awt.Color;
import
java.awt.Font;
import
java.awt.Graphics;
import
java.awt.Graphics2D;
import
java.awt.RenderingHints;
import
java.awt.geom.AffineTransform;
import
java.awt.image.BufferedImage;
import
java.io.File;
import
java.io.FileOutputStream;
import
java.io.IOException;
import
java.io.OutputStream;
import
java.util.Arrays;
import
java.util.Random;
import
javax.imageio.ImageIO;
/**
* 验证码生成
*
*/
public
class
VerifyCodeUtils
{
//使用到Algerian字体,系统里没有的话需要安装字体,字体只显示大写,去掉了1,0,i,o几个容易混淆的字符
public
static
final
String
VERIFY_CODES
=
"23456789ABCDEFGHJKLMNPQRSTUVWXYZ"
;
private
static
Random
random
=
new
Random();
/**
* 使用系统默认字符源生成验证码
*
@param
verifySize 验证码长度
*
@return
*/
public
static
String generateVerifyCode(
int
verifySize){
return
generateVerifyCode
(verifySize,
VERIFY_CODES
);
}
/**
* 使用指定源生成验证码
*
@param
verifySize 验证码长度
*
@param
sources 验证码字符源
*
@return
*/
public
static
String generateVerifyCode(
int
verifySize, String sources){
if
(sources ==
null
|| sources.length() == 0){
sources =
VERIFY_CODES
;
}
int
codesLen = sources.length();
Random rand =
new
Random(System.
currentTimeMillis
());
StringBuilder verifyCode =
new
StringBuilder(verifySize);
for
(
int
i = 0; i < verifySize; i++){
verifyCode.append(sources.charAt(rand.nextInt(codesLen-1)));
}
return
verifyCode.toString();
}
/**
* 生成随机验证码文件,并返回验证码值
*
@param
w
*
@param
h
*
@param
outputFile
*
@param
verifySize
*
@return
*
@throws
IOException
*/
public
static
String outputVerifyImage(
int
w,
int
h, File outputFile,
int
verifySize)
throws
IOException{
String verifyCode =
generateVerifyCode
(verifySize);
outputImage
(w, h, outputFile, verifyCode);
return
verifyCode;
}
/**
* 输出随机验证码图片流,并返回验证码值
*
@param
w
*
@param
h
*
@param
os
*
@param
verifySize
*
@return
*
@throws
IOException
*/
public
static
String outputVerifyImage(
int
w,
int
h, OutputStream os,
int
verifySize)
throws
IOException{
String verifyCode =
generateVerifyCode
(verifySize);
outputImage
(w, h, os, verifyCode);
return
verifyCode;
}
/**
* 生成指定验证码图像文件
*
@param
w
*
@param
h
*
@param
outputFile
*
@param
code
*
@throws
IOException
*/
public
static
void
outputImage(
int
w,
int
h, File outputFile, String code)
throws
IOException{
if
(outputFile ==
null
){
return
;
}
File dir = outputFile.getParentFile();
if
(!dir.exists()){
dir.mkdirs();
}
try
{
outputFile.createNewFile();
FileOutputStream fos =
new
FileOutputStream(outputFile);
outputImage
(w, h, fos, code);
fos.close();
}
catch
(IOException e){
throw
e;
}
}
/**
* 输出指定验证码图片流
*
@param
w
*
@param
h
*
@param
os
*
@param
code
*
@throws
IOException
*/
public
static
void
outputImage(
int
w,
int
h, OutputStream os, String code)
throws
IOException{
int
verifySize = code.length();
BufferedImage image =
new
BufferedImage(w, h, BufferedImage.
TYPE_INT_RGB
);
Random rand =
new
Random();
Graphics2D g2 = image.createGraphics();
g2.setRenderingHint(RenderingHints.
KEY_ANTIALIASING
,RenderingHints.
VALUE_ANTIALIAS_ON
);
Color[] colors =
new
Color[5];
Color[] colorSpaces =
new
Color[] { Color.
WHITE
, Color.
CYAN
,
Color.
GRAY
, Color.
LIGHT_GRAY
, Color.
MAGENTA
, Color.
ORANGE
,
Color.
PINK
, Color.
YELLOW
};
float
[] fractions =
new
float
[colors.
length
];
for
(
int
i = 0; i < colors.
length
; i++){
colors[i] = colorSpaces[rand.nextInt(colorSpaces.
length
)];
fractions[i] = rand.nextFloat();
}
Arrays.
sort
(fractions);
g2.setColor(Color.
GRAY
);
// 设置边框色
g2.fillRect(0, 0, w, h);
Color c =
getRandColor
(200, 250);
g2.setColor(c);
// 设置背景色
g2.fillRect(0, 2, w, h-4);
//绘制干扰线
Random random =
new
Random();
g2.setColor(
getRandColor
(160, 200));
// 设置线条的颜色
for
(
int
i = 0; i < 20; i++) {
int
x = random.nextInt(w - 1);
int
y = random.nextInt(h - 1);
int
xl = random.nextInt(6) + 1;
int
yl = random.nextInt(12) + 1;
g2.drawLine(x, y, x + xl + 40, y + yl + 20);
}
// 添加噪点
float
yawpRate = 0.05f;
// 噪声率
int
area = (
int
) (yawpRate * w * h);
for
(
int
i = 0; i < area; i++) {
int
x = random.nextInt(w);
int
y = random.nextInt(h);
int
rgb =
getRandomIntColor
();
image.setRGB(x, y, rgb);
}
shear
(g2, w, h, c);
// 使图片扭曲
g2.setColor(
getRandColor
(100, 160));
int
fontSize = h-4;
Font font =
new
Font(
"Algerian"
, Font.
ITALIC
, fontSize);
g2.setFont(font);
char
[] chars = code.toCharArray();
for
(
int
i = 0; i < verifySize; i++){
AffineTransform affine =
new
AffineTransform();
affine.setToRotation(Math.
PI
/ 4 * rand.nextDouble() * (rand.nextBoolean() ? 1 : -1), (w / verifySize) * i + fontSize/2, h/2);
g2.setTransform(affine);
g2.drawChars(chars, i, 1, ((w-10) / verifySize) * i + 5, h/2 + fontSize/2 - 10);
}
g2.dispose();
ImageIO.
write
(image,
"jpg"
, os);
}
private
static
Color getRandColor(
int
fc,
int
bc) {
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
static
int
getRandomIntColor() {
int
[] rgb =
getRandomRgb
();
int
color = 0;
for
(
int
c : rgb) {
color = color << 8;
color = color | c;
}
return
color;
}
private
static
int
[] getRandomRgb() {
int
[] rgb =
new
int
[3];
for
(
int
i = 0; i < 3; i++) {
rgb[i] =
random
.nextInt(255);
}
return
rgb;
}
private
static
void
shear(Graphics g,
int
w1,
int
h1, Color color) {
shearX
(g, w1, h1, color);
shearY
(g, w1, h1, color);
}
private
static
void
shearX(Graphics g,
int
w1,
int
h1, Color color) {
int
period =
random
.nextInt(2);
boolean
borderGap =
true
;
int
frames = 1;
int
phase =
random
.nextInt(2);
for
(
int
i = 0; i < h1; i++) {
double
d = (
double
) (period >> 1)
* Math.
sin
((
double
) i / (
double
) period
+ (6.2831853071795862D * (
double
) phase)
/ (
double
) frames);
g.copyArea(0, i, w1, 1, (
int
) d, 0);
if
(borderGap) {
g.setColor(color);
g.drawLine((
int
) d, i, 0, i);
g.drawLine((
int
) d + w1, i, w1, i);
}
}
}
private
static
void
shearY(Graphics g,
int
w1,
int
h1, Color color) {
int
period =
random
.nextInt(40) + 10;
// 50;
boolean
borderGap =
true
;
int
frames = 20;
int
phase = 7;
for
(
int
i = 0; i < w1; i++) {
double
d = (
double
) (period >> 1)
* Math.
sin
((
double
) i / (
double
) period
+ (6.2831853071795862D * (
double
) phase)
/ (
double
) frames);
g.copyArea(i, 0, 1, h1, 0, (
int
) d);
if
(borderGap) {
g.setColor(color);
g.drawLine(i, (
int
) d, i, 0);
g.drawLine(i, (
int
) d + h1, i, h1);
}
}
}
public
static
void
main(String[] args)
throws
IOException{
File dir =
new
File(
"d:/testverifies"
);
int
w = 200, h = 80;
for
(
int
i = 0; i < 50; i++){
String verifyCode =
generateVerifyCode
(4);
File file =
new
File(dir, verifyCode +
".jpg"
);
outputImage
(w, h, file, verifyCode);
}
}
}
---JSP
<
div
class
=
"yzm col-xs-5"
>
<
img
id
=
"imgId"
style
="
width
:
80px
;
height
:
26px
;"
src
=
"
<%=
path
%>
/web/user/showVerifyCode.do"
/>
<
a
class
=
"kbq"
href
=
"javascript:;"
id
=
"refreshId"
>
看不清
</
a
>
</
div
>
--JS
// 刷新验证码
$(
"#imgId, #refreshId"
).click(
function
() {
$(
"#imgId"
).attr(
"src"
,
_path +
"/web/user/showVerifyCode.do?date="
+
new
Date());
});
---判断验证码是否正确
--JS
var initBootstrapValidator = function () {
$("#defaultForm").bootstrapValidator({
message: 'This value is not valid',
feedbackIcons: {/*输入框不同状态,显示图片的样式 icon-mini-edit*/
/*valid: 'glyphicon glyphicon-ok',*/
valid: 'icon-mini-edit',
invalid: 'glyphicon glyphicon-remove',
validating: 'icon-loading'
},
fields: {
$("#defaultForm").bootstrapValidator({
message: 'This value is not valid',
feedbackIcons: {/*输入框不同状态,显示图片的样式 icon-mini-edit*/
/*valid: 'glyphicon glyphicon-ok',*/
valid: 'icon-mini-edit',
invalid: 'glyphicon glyphicon-remove',
validating: 'icon-loading'
},
fields: {
verifyCode: {
validators: {
notEmpty: {
message: '验证码不能为空'
},
stringLength: {
min: 4,
max: 4,
message: '验证码长度为4位',
},
remote: {
url: _path + "/web/user/checkVerifyCode.do",
message:"验证码不正确",
type: "post",
dataType: 'json',
data: { //不填写会自动将对应的id和value发给后台
},
delay: 200
}
}
}
}
});
}
validators: {
notEmpty: {
message: '验证码不能为空'
},
stringLength: {
min: 4,
max: 4,
message: '验证码长度为4位',
},
remote: {
url: _path + "/web/user/checkVerifyCode.do",
message:"验证码不正确",
type: "post",
dataType: 'json',
data: { //不填写会自动将对应的id和value发给后台
},
delay: 200
}
}
}
}
});
}
----后台代码
/**
* 判断验证码是否正确
*
* @throws IOException
*/
@RequestMapping(value = "checkVerifyCode", produces = "text/plain;charset=UTF-8")
public String checkVerifyCode(String verifyCode, HttpServletRequest request) throws IOException {
HashMap<String, Object> resultMap = new HashMap<String, Object>();
HttpSession session = request.getSession(true);
String verifyCodeSession = (String) session.getAttribute("verifyCode");
if (verifyCode != null && verifyCode.toLowerCase().equals(verifyCodeSession)) {//toLowerCase():把字符串变成小写
resultMap.put("message", "验证码正确");
resultMap.put("valid", true);
resultMap.put("success", true);
} else {
resultMap.put("message", "验证码错误");
resultMap.put("valid", false);
resultMap.put("success", false);
}
return JsonMapper.toJson(resultMap);
}
* 判断验证码是否正确
*
* @throws IOException
*/
@RequestMapping(value = "checkVerifyCode", produces = "text/plain;charset=UTF-8")
public String checkVerifyCode(String verifyCode, HttpServletRequest request) throws IOException {
HashMap<String, Object> resultMap = new HashMap<String, Object>();
HttpSession session = request.getSession(true);
String verifyCodeSession = (String) session.getAttribute("verifyCode");
if (verifyCode != null && verifyCode.toLowerCase().equals(verifyCodeSession)) {//toLowerCase():把字符串变成小写
resultMap.put("message", "验证码正确");
resultMap.put("valid", true);
resultMap.put("success", true);
} else {
resultMap.put("message", "验证码错误");
resultMap.put("valid", false);
resultMap.put("success", false);
}
return JsonMapper.toJson(resultMap);
}