1.界面采用的Js为ExtJs,
在ExtJs的view中的login文件夹中,有一个Form.js,验证码部分的代码是:
{
xtype: ' fieldcontainer ',
layout: ' hbox ',
items: [
{
fieldLable : ' 验证码 ',
xtype : ' textfield ',
lableWidth : 120,
width : 225,
maxLength : 4,
emptyText : " 验证码 ",
action : 'loginByEnter' ,
minLength: 1,
regex: /[\u0000-\u00FF]/,
regexText: "请输入正确的验证码!",
name:'verification'
},
{xtype : ' label ' , width : 10},
{
xtype : ' box ' ,
id : ' iconImage ',
border: false,
style:{
cursor:' pointer '
},
listeners : {
' click ' : {
element : ' el ',
fn : function() {
document.getElementById(' iconImage ').src = ' getValidationCode?random='+Math.random();
}
}
},
autoEl:{
width : 60,
height: 25,
border: false,
tag: 'img',
src: 'getValidationCode'
}
}
]
}
2.创建SystemUserController 。
在这个Controller中写入接口 /getValidationCode
@RequestMapping(" /getValidationCode ")
@ResponseBody
public void getValidationCode(HttpServletResponse response , HttpServletRequest request) throws Exception {
ValidationCode code = new ValidationCode();
code.doGet(request , response);
}
3.在与controller及dto的同一目录下创立filter文件夹(过滤器)
需要创建二个类,分别为ValidationCode 和 VerificationCodeFilter.
在ValidationCode 中,代码如下:
public class ValidationCode {
private Random generator = new Random();
private 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);
}
public ValidationCode() {
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//beginTime,endTime 为测试用
long beginTime;
long endTime;
//设置页面不缓存
response.setHeader("Cache-Control", "no-store");
response.setHeader("Pragma", "no-cache");
response.setDateHeader("Expires", 0);
response.setContentType("image/jpeg");
//测试图像生成时间
beginTime = System.currentTimeMillis();
//在内存中创建图像
int width = 60,height = 25;
BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
//获取图形上下文
Graphics g = image.getGraphics();
//生成随机类
Random random = new Random();
//设定背景色
g.setColor(getRandColor(200,250));
g.fillRect(0, 0, width, height);
//设定字体
g.setFont(new Font("宋体", Font.PLAIN, 9));
// 随机产生155条干扰线,使图象中的认证码不易被其它程序探测到
g.setColor(Color.WHITE);
// 取随机产生的认证码(4位数字)
String sRand = "" ;
for (int i = 0; i < 4; i++) {
String rand = "" ;
if (i % 2 == 0) {
//rand = String.valueOf(random.nextInt(10));
rand = getValidRand("N", 10, random);
g.setFont(new Font(rand, Font.HANGING_BASELINE, height - 4));
} else {
g.setFont(new Font(rand, Font.LAYOUT_LEFT_TO_RIGHT, height - 4));
rand = getValidRand("C", 10, random);
}
g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));
g.drawString(String.valueOf(rand), 15 * i, height - 2);
sRand += rand;
}
// 随机产生88个干扰点,使图象中的认证码不易被其它程序探测到
for (int i = 0; i < 20; i++) {
int x = random.nextInt(width);
int y = random.nextInt(height);
g.drawOval(x, y, 0, 0);
}
// 将认证码存入SESSION
HttpSession session = request.getSession();
session.setAttribute("VerifyCode", sRand);
// 图象生效
g.dispose();
endTime = System.currentTimeMillis();
//测试图像输出时间
beginTime = System.currentTimeMillis();
// 输出图象到页面
endTime = System.currentTimeMillis();
/**
* 使用JPEGImageEncoder将验证码输出到页面
*/
//测试图像输出-new文件时间
beginTime = System.currentTimeMillis();
ServletOutputStream out = response.getOutputStream();
PNGImageEncoder encoder = new PNGImageEncoder(out, org.apache.xmlgraphics.image.codec.png.PNGEncodeParam.getDefaultEncodeParam(image));
encoder.encode(image);
out.close();
endTime = System.currentTimeMillis();
}
private void shear (Graphics g , int w1 , int h1 , Color color){
shearX(g,w1,h1,color);
shearY(g,w1,h1,color);
}
public void shearX(Graphics g, int w1, int h1, Color color) {
int period = generator.nextInt(2);
boolean borderGap = true;
int frames = 1;
int phase = generator.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);
}
}
}
public void shearY(Graphics g, int w1, int h1, Color color) {
int period = generator.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);
}
}
}
/**
* 取得合法字符:不能出现如下易混淆的字符: 0(数字)、1(数字)、o(字母)、O(字母)、i、I、l(L)
*
* @param charType
* @param count
* @return String
* @throws Exception
*/
public String getValidRand(String charType, int count, Random random) {
String invalidCString = "01oOiIl";
String rand = "";
if ("N".equalsIgnoreCase(charType)) {
for (int i = 0; i < count; i++) {
rand = String.valueOf(random.nextInt(10));
if ((rand != null) && (invalidCString.indexOf(rand) == -1)) {
return rand;
}
}
return "9";//默认数字为9
} else {
for (int i = 0; i < count; i++) {
char c = 65;
c = (char) (c + random.nextInt(26));
rand = String.valueOf(c);
if ((rand != null) && (invalidCString.indexOf(rand) == -1)) {
return rand;
}
}
return "Q";//默认字母为Q
}
}
}
在VerificationCodeFilter中,代码如下:
public class VerificationCodeFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
String inputCode = req.getParameter("verification");
String verificationCode = (String) req.getSession(true).getAttribute("VerifyCode");
if (verificationCode != null && verificationCode.equalsIgnoreCase(inputCode)) {
chain.doFilter(request, response);
} else {
ObjectMapper mapper = new ObjectMapper();
JsonObjectResponse jsonObjectResponse = new JsonObjectResponse();
jsonObjectResponse.setStatus(JsonObjectResponse.Status.fail);
jsonObjectResponse.setMessage("验证码错误");
OutputStream out = response.getOutputStream();
mapper.writeValue(out, jsonObjectResponse);
}
}
public void destroy() {
}
Log log = LogFactory.getLog(VerificationCodeFilter.class)
}
验证码效果图如下: