首先我们得从服务端画好验证码,然后通过流的方法传到前台来,然后前台传过来的验证码与后台生成的验证码进行验证。验证码主要是防止一些机器人进行操作的一种手段
不多说,下面先来生成验证码吧,这里我把生成验证码做了一个封装
/**
* Copyright (C), 2018-2019, XXX有限公司
* FileName: ImageCode
* Author: 1543057945
* Date: 2019/1/11 17:18
* Description:
* History:
* <author> <time> <version> <desc>
* 张良敏 修改时间 版本号 描述
*/
package Utils;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.font.ImageGraphicAttribute;
import java.awt.image.BufferedImage;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
/**
* 〈一句话功能简述〉<br>
* 〈〉
*
* @author 1543057945
* @create 2019/1/11
* @since 1.0.0
*/
public class ImageCode {
//验证码个数
private int count=4;
//验证码宽度,且设置每个字的宽度
private int width=count*50;
//验证码高度
private int height=50;
//图片验证码key
private String code="";
public ImageCode() {
}
public ImageCode(int count, int width, int height) {
this.count = count;
this.width = width;
this.height = height;
}
public int getCount() {
return count;
}
public String getCode() {
return code;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
public void setCount(int count) {
this.count = count;
width=this.count*50;
}
public void setWidth(int width) {
this.width = width;
}
public void setHeight(int height) {
this.height = height;
}
//测试写入
public static void main(String[] args){
long startend=System.currentTimeMillis();
ImageCode imageCode=new ImageCode();
//默认验证码位数为4,我这里设为5
imageCode.setCount(5);
//得到缓冲区
BufferedImage image = imageCode.getImage();
//得到真实验证码
String code=imageCode.getCode();
long endTime=System.currentTimeMillis();
System.out.println("验证码为:"+code+"\n花费时间为:"+(endTime-startend)+"\n到E盘根目录下看,文件名为11.jpg");
}
public BufferedImage getImage(){
//图片缓冲区
BufferedImage image = new BufferedImage(width,height,1);
//获得笔
Graphics graphics = image.getGraphics();
//设置初始画笔为白色
graphics.setColor(new Color(255,255,254));
//画满整个图,也就是把图片先变为白色
graphics.fillRect(0,0,width,height);
Random rd=new Random();
//设置字体
Font font=new Font("宋体",Font.PLAIN,35+rd.nextInt(10));
graphics.setFont(font);
char[] chars="qweCRYHrtasdfBxy678934VTGopNUFKuighjklzSXEDLOP12cvbnmQAZWJMI50".toCharArray();
//画验证码
for (int i = 0; i <count ; i++) {
String string="";
string+=chars[rd.nextInt(chars.length)]+"";
graphics.setColor(new Color(rd.nextInt(254),rd.nextInt(254),rd.nextInt(254)));
graphics.drawString(string,55*i+rd.nextInt(10),27+rd.nextInt(15));
code+=string;
}
//干扰点
for (int i = 0; i <25*count ; i++) {
graphics.setFont(new Font("宋体",Font.PLAIN,15));
String string=".";
graphics.setColor(new Color(rd.nextInt(255),rd.nextInt(255),rd.nextInt(255)));
graphics.drawString(string,rd.nextInt(width),rd.nextInt(height));
}
//干扰线
for (int i = 0; i <count+count/2 ; i++) {
graphics.setFont(new Font("宋体",Font.PLAIN,10));
graphics.setColor(new Color(rd.nextInt(255),rd.nextInt(255),rd.nextInt(255)));
graphics.drawLine(rd.nextInt(width),rd.nextInt(height),rd.nextInt(width),rd.nextInt(height));
}
//归还笔
graphics.dispose();
//写到流里面需要用到ImageIo
//这里做的测试,在本地测试下是否画的是那回事
/*try {
ImageIO.write(image,"jpg",new FileOutputStream("E:/11.jpg"));
} catch (IOException e) {
e.printStackTrace();
}*/
return image;
}
}
接下来我们要写servlet代码了,其实就是一个生成验证码的接口
package Utils;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.IOException;
@WebServlet(name = "GetImgServlet",urlPatterns = {"/imgcode"})
public class GetImgServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置页面内容为image形式
response.setContentType("image/jpg");
//防止乱码
response.setCharacterEncoding("UTF-8");
//定义获取验证码的对象
ImageCode imageCode=new ImageCode();
//得到图片缓冲区
BufferedImage img = imageCode.getImage();
//得到文字验证码
String code = imageCode.getCode();
//获得用户session
HttpSession session = request.getSession();
//将文字验证码保存到客户端session,方便验证
session.setAttribute("imgcode",code);
System.out.println("生成的验证码为:"+code);
//获得sevlet输出流
ServletOutputStream outputStream = response.getOutputStream();
//写到客户端
ImageIO.write(img,"jpg",outputStream);
//关闭输出流
if(outputStream!=null){
outputStream.close();
}
}
}
做好验证码api之后我们还要进行前台交互下,看到底有没有作用
这是html文档
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>验证码</title>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
</head>
<body>
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td>
<input type="text" name="code">
</td>
<td>
<img src="/imgcode" style="height: 30px;width: 120px">
</td>
</tr>
<tr>
<td colspan="2">
<center><button type="button" class="button">验证</button></center>
</td>
</tr>
</table>
<script>
$(document).ready(function () {
//设置按钮的点击事件
$(".button").click(function () {
var code = $("input[name='code']");
if (code.val() == null || code.val() == "") {
alert("请输入验证码后再认证");
} else {
//有值了,我们就体检到后台验证,通过post
$.post("/checkcode", code.serialize(), function (data, stauts) {
if (stauts = 'success') {
if (data == "验证正确")
alert("验证正确");
else
alert("验证码错误");
} else {
alert("请求错误");
}
})
}
})
//点击图片切换验证码
$("img").click(function () {
$("img").attr("src","/imgcode?"+Math.random())
})
})
</script>
</body>
</html>
这是接受验证码的接口
package Utils;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet(name = "CheckCodeServlet",urlPatterns ={"/checkcode"})
public class CheckCodeServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置页面类型
response.setContentType("text/html,charset=urf-8");
response.setCharacterEncoding("utf-8");
//得到请求参数
String code = request.getParameter("code");
//得到session
HttpSession session = request.getSession();
//得到生成的验证码
String imgcode = (String) session.getAttribute("imgcode");
PrintWriter writer = response.getWriter();
if (imgcode.equalsIgnoreCase(code)){
System.out.println(imgcode+"\n"+code);
writer.print("验证正确");
//验证之后最好销毁下之前的
session.setAttribute("imgcode","");
}else{
writer.print("验证码错误");
}
writer.close();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
}
验证码输入正确会提示
输入错误则提示
好了,教程结束,希望能帮到大家,稍作改动就可以拿到实际项目中运用了