验证码实现
Posted caozz
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了验证码实现相关的知识,希望对你有一定的参考价值。
一、springboot实现,用于测试工具类是否可用
1、先写一个生成验证码的工具类,用来生成验证码
package com.jdwa.utill;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Locale;
import java.util.Random;
/**
* 生成验证码的工具类
*/
public class VerifyCode {
private static final Logger log = LoggerFactory.getLogger(VerifyCode.class);
private int width = 100;// 生成验证码图片的宽度
private int height = 50;// 生成验证码图片的高度
private String[] fontNames = { "宋体", "楷体", "隶书", "微软雅黑" };
private Color bgColor = new Color(255, 255, 255);// 定义验证码图片的背景颜色为白色
private Random random = new Random();
private String codes = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
private String text;// 记录随机字符串
/**
* 获取一个随意颜色
*
* @return
*/
private Color randomColor() {
int red = random.nextInt(150);
int green = random.nextInt(150);
int blue = random.nextInt(150);
return new Color(red, green, blue);
}
/**
* 获取一个随机字体
*
* @return
*/
private Font randomFont() {
String name = fontNames[random.nextInt(fontNames.length)];
int style = random.nextInt(4);
int size = random.nextInt(5) + 24;
return new Font(name, style, size);
}
/**
* 获取一个随机字符
*
* @return
*/
private char randomChar() {
return codes.charAt(random.nextInt(codes.length()));
}
/**
* 创建一个空白的BufferedImage对象
*
* @return
*/
private BufferedImage createImage() {
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = (Graphics2D) image.getGraphics();
g2.setColor(bgColor);// 设置验证码图片的背景颜色
g2.fillRect(0, 0, width, height);
return image;
}
public BufferedImage getImage() {
BufferedImage image = createImage();
Graphics2D g2 = (Graphics2D) image.getGraphics();
StringBuffer sb = new StringBuffer();
Font f = randomFont();
System.out.println(f.getFontName());
System.out.println(f.getFontName(new Locale("zh_CN")));
for (int i = 0; i < 4; i++) {
String s = randomChar() + "";
sb.append(s);
g2.setColor(randomColor());
g2.setFont(randomFont());
float x = i * width * 1.0f / 4;
g2.drawString(s, x, height - 15);
}
this.text = sb.toString();
drawLine(image);
return image;
}
/**
* 绘制干扰线
*
* @param image
*/
private void drawLine(BufferedImage image) {
Graphics2D g2 = (Graphics2D) image.getGraphics();
int num = 5;
for (int i = 0; i < num; i++) {
int x1 = random.nextInt(width);
int y1 = random.nextInt(height);
int x2 = random.nextInt(width);
int y2 = random.nextInt(height);
g2.setColor(randomColor());
g2.setStroke(new BasicStroke(1.5f));
g2.drawLine(x1, y1, x2, y2);
}
}
public String getText() {
return text;
}
public static void output(BufferedImage image, OutputStream out) throws IOException {
ImageIO.write(image, "JPEG", out);
}
}
2、然后写一个Controller
package com.jdwa.controller;
import com.jdwa.utill.VerifyCode;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
@Controller
public class VerifyCodeController {
@RequestMapping("code")
public void getCode(HttpServletResponse response) throws IOException {
VerifyCode vc = new VerifyCode();
BufferedImage image = vc.getImage();
// VerifyCode.veryfiCode = vc.getText();
//实际项目中可以存到session中,
// 如果无法维护session,也可以存一个静态变量,
// 不过登录验证时(无论成功失败)要销毁上一次的验证码
System.out.println(vc.getText());
VerifyCode.output(image, response.getOutputStream());
}
}
3、运行信息以及效果截图
二、centos7环境,Jersey框架的问题
1、当环境中没有代码中对应的字体,可能会导致获取不到image
yum install fontconfig //安装字体库
cd /usr/share/fonts //字体所在文件夹
mkdir chinese //新建文件夹,用于放中文字体文件。文件可在windows系统C:WindowsFonts下拷贝
chmod -R 755 /usr/share/fonts/chinese //给字体文件赋权
fc-list //查询当前支持的所有字体
2、获取不到HttpServletResponse,即使按照网上说的加上 @Context
注解,安装较新版本,也未解决。如果有解决这个问题的大神,欢迎交流。
3、改用了struts2环境,顺利获取到
package *;
import *;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.struts2.interceptor.ServletResponseAware;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import static com.opensymphony.xwork2.Action.SUCCESS;
public class VerifyCodeAction implements ServletResponseAware {
private static final Logger log = LoggerFactory.getLogger(VerifyCodeAction.class);
private HttpServletResponse response;
public String execute() {
log.info("=============进入生成验证码方法================");
ServletOutputStream out = null;
try{
VerifyCode vc = new VerifyCode();
BufferedImage image = vc.getImage();
log.info("=========image================= : {}",image.toString());
out = response.getOutputStream();
VerifyCode.output(image, out);
}catch (Exception ex) {
log.error("=========生成验证码出错================= ");
} finally {
if (out != null){
try {
out.close();
} catch (IOException e){
}
}
}
return SUCCESS;
}
@Override
public void setServletResponse(HttpServletResponse response) {
this.response = response;
}
}
实现刷新效果
<img src="vf.action" id="img" style="width: 75px; height:30px;">
<a href="#" onclick="changeVf()" style="display: block;">看不清</a>
js方法:
function changeVf() {
var doc = document.getElementById("img");
var src = "vf.action?k=" + Math.random();
doc.setAttribute("src",src);
}
路漫漫其修远兮,吾将上下而求索。。。
以上是关于验证码实现的主要内容,如果未能解决你的问题,请参考以下文章