Servlet验证码制作与验证
制作验证码图片
我们注册用户时,往往都需要我们在输入框中的数据与图片显示的内容进行对比。下面是二维码图片制作工具类与效果图
二维码制作工具类
public class VerifyCodeUtils {
/**
* 封装获取含有二维码图片与内容(答案)的Map集合
* @return Map含有图片与答案,k为图片对应的答案,v为图片
*/
public static Map<String, BufferedImage> getMap(){
//1、构建一张空白(透明)图片
BufferedImage image = new BufferedImage(200,50,BufferedImage.TYPE_3BYTE_BGR);
//2、得到画笔
Graphics g = image.getGraphics();
//3、设置画笔的颜色
g.setColor(Color.white);
//4、给空白200*100图片填充背景
g.fillRect(0,0,200,50);
//5、给一个黑色的边框
g.setColor(Color.BLACK);
g.drawRect(0,0,199,49);
//6、画内容
StringBuilder sb = new StringBuilder();
//7、构建随机对象
Random rd = new Random();
//8、随机画四个字母
for (int i = 0; i < 4; i++){
//8.1 随机颜色 红(0-255) 绿(0-255) 蓝(0-255)
Color c = new Color(rd.nextInt(256),rd.nextInt(256),rd.nextInt(256));
//8.2 随机字符 A - Z ∈ [65,90]
char ch = (char)(rd.nextInt(26) + 65);
//8.3 将字符画到图片上
g.setColor(c);
//8.4 设置字体为楷体与大小
g.setFont(new Font("楷体",Font.BOLD,28));
g.drawString(ch+"",45+30*i,35);
//8.5 将字符通过可变字符串保存起来
sb.append(ch);
}
//9、构建Map并添加到Map中
Map<String,BufferedImage> map = new HashMap<>();
map.put(sb.toString(),image);
//10、返回map对象
return map;
}
/**
* 封装:获取 Map<String,BufferedImage>中的二维码图片BufferedImg对象
* @param map 含有二维码图片与答案的Map集合
* @return 二维码图片BufferedImg对象
*/
public static BufferedImage getImg(Map<String,BufferedImage> map){
//二维码图片对象
BufferedImage image = null;
//遍历Map集合
Set<Map.Entry<String, BufferedImage>> entrySet = map.entrySet();
//得到set迭代器
Iterator<Map.Entry<String,BufferedImage>> iterator = entrySet.iterator();
//由于此处map只有一组键值对(K-V),直接得到键值对并返回value
return iterator.next().getValue();
}
/**
* 封装得到验证码图片对应的答案(Key值)
* @param map 含有一组键值对的答案与二维码图片集合
* @return 返回二维码图片对应的答案(字符串)
*/
public static String getCode(Map<String,BufferedImage> map){
//遍历Map集合
Set<Map.Entry<String, BufferedImage>> entrySet = map.entrySet();
Iterator<Map.Entry<String, BufferedImage>> iterator = entrySet.iterator();
//返回答案(K值及答案)
return iterator.next().getKey();
}
}
验证码图片生成的Servlet与用户输入结果的验证
我们需要通过对应的Servlet将验证码图片进行响应,由于src属性值也是一种资源寻址,因此我们可以直接修改注册网页中img标签的src属性来显示二维码图片,其属性值为该Servlet的访问地址即可
通过该Servlet业务将验证码图片对应的答案保存在Session对象中进行保存,便于获取用户输入的答案与系统自动生成的答案进行匹配,检测用户输入是否正确,下面是对应Servlet实现代码
@WebServlet("/friend_demo/imgCode")
public class ImageCodeServlet extends HttpServlet {
@Override
public void service(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException{
//1、设置请求对象的数据编码方法
request.setCharacterEncoding("utf-8");
//2、设置响应类型为一张图片
response.setContentType("image/jpeg");
//3、获取验证码的Map
Map<String, BufferedImage> map = VerifyCodeUtils.getMap();
//4、获取验证码图片
BufferedImage img = VerifyCodeUtils.getImg(map);
//5、获取系统自动生成验证码图片对应的答案
String code = VerifyCodeUtils.getCode(map);
//6、将验证码图片对应的答案绑定到Session中保存,方便后期获取用户输入答案进行比较
HttpSession session = request.getSession();
session.setAttribute("code_1",code);
//7、将验证码图片放入输出流中,写入网页中
ImageIO.write(img,"jpeg",response.getOutputStream());
}
}
将注册页面的src属性值修改为Servlet访问路径即可,修改如下
<tr>
<td valign="middle" align="right">
验证码:
<img id="num" src="imgCode" />
<a href="javascript:;"
onclick="document.getElementById('num').src = 'imgCode?'+(new Date()).getTime()">换一张</a>
</td>
<td valign="middle" align="left">
<input type="text" class="inputgri" name="checkCode" id="code" onblur="checkInputCode();"/>
<span id="err_code"></span>
</td>
</tr>
注意:
1、其中的src属性值已经修改为了 验证码生成的Servlet对应的访问路径
2、为了能够保证我们每次点击 “换一张” 时发送的请求是不同的请求,达到刷新验证码图片的效果时,我们在请求的后面通过携带一个参数,该参数一个通过js获取的日期对象毫秒数来保证每次请求的差异性,从而刷新验证码图片
感谢大家的阅读,热爱分享的仓鼠,请大家多多指教,么么哒~~~~~