这是个tomcat部署的小项目(本地一样用)
每次点击按钮,向Servlet请求一次资源,更新一次img的src
CheckImage.java
public class CheckImage {
/*
* 【该类用于生成并处理BufferedImage】
* 两个公有方法:
* public BufferedImage getImage() 返回验证码图片(流)
* public String getText() 返回验证码正确答案
*/
// 成员变量
private int x = 200;
private int y = 80;
private int fontSize = 70;
private StringBuilder sb = new StringBuilder();
private Random random = new Random();
private Color bgColor = new Color(255, 255, 255);
private String[] fontFamily = {"宋体", "华文楷体", "黑体", "华文新魏", "华文隶书", "微软雅黑", "楷体_GB2312"};
private String chars = "0123456789ABCDEFGHIGKLMNOPQRSTUVWXYZabcdefghigklmnopqrstuvwxyz";
// 获取随机字体
private String getFont(){
int index = random.nextInt(fontFamily.length);
return fontFamily[index];
}
// 获取随机字母
private String getChar(){
int index = random.nextInt(chars.length());
return chars.charAt(index) + "";
}
// 获取随机颜色
private Color getColor(){
int R = random.nextInt(256);
int G = random.nextInt(256);
int B = random.nextInt(256);
return new Color(R, G, B);
}
// 生成图片(缓冲区)
// 返回image
private BufferedImage getBufferedImage(){
BufferedImage image = new BufferedImage(x, y, BufferedImage.TYPE_INT_RGB);
Graphics2D pen = (Graphics2D)image.getGraphics();
pen.setColor(bgColor);
pen.fillRect(0, 0, x, y);
return image;
}
// 处理图片(字符 + 干扰线)
// 返回image
private BufferedImage addCharAndLine(){
BufferedImage image = getBufferedImage();
Graphics2D pen = (Graphics2D)image.getGraphics();
for(int i = 0; i < 4; i++){
pen.setColor(getColor());
pen.setFont(new Font(getFont(), random.nextInt(4), fontSize));
String c = getChar();
pen.drawString(c, 10+i*50, 65);
sb.append(c);
}
int lineNum = 4;
for(int i = 0; i < lineNum; i++){
pen.setColor(getColor());
pen.setStroke(new BasicStroke(1.5F, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER));
int x1 = random.nextInt(x);
int y1 = random.nextInt(y);
int x2 = random.nextInt(x);
int y2 = random.nextInt(y);
pen.drawLine(x1, y1, x2, y2);
}
return image;
}
// 获取一张验证码图片
public BufferedImage getImage(){
return addCharAndLine();
}
// 获取对应的验证码
public String getText(){
return sb.toString();
}
}
CheckServlet.java
@WebServlet("/CheckServlet")
public class CheckServlet extends HttpServlet {
/*
* 该Srevlet接收请求的响应为:服务器输出验证码图片到浏览器
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
BufferedImage image = new CheckImage().getImage();
ImageIO.write(image, "jpg", response.getOutputStream());
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}
index.html
<html lang="en">
<head>
<meta charset="UTF-8">
<title>萝莉housetitle>
<script>
// 用js实现"点击按钮,请求资源,img更新"的逻辑
window.onload = function () {
var img = document.querySelector("img");
var btn = document.querySelector("button");
btn.addEventListener("click", function () {
var date = new Date().getTime();
img.src = "/loli/ServletCheck?" + date;
// 如果不加时间戳的话,浏览器会认为你一直在请求相同的资源,而一直使用缓存中的img
})
}
script>
head>
<body>
<img src="/loli/ServletCheck">
<button>换一张?button>
body>
html>
如果增加需求,让其真正具有"验证功能"——即提交一个表单,如果验证码填写正确则跳转到成功页面(SuccessServlet);如果填写错误则刷新验证码,依旧是index.html页面
逻辑:
@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
String checkCode = request.getParameter("checkCode");
HttpSession session = request.getSession();
String myCode = (String)session.getAttribute("checkCode");
if(myCode.equalsIgnoreCase(checkCode)){
response.sendRedirect(request.getContextPath() + "/SuccessServlet"); // 重定向
}else{
request.getRequestDispatcher("/index.html").forward(request, response); // 转发
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}