CaptcahCode.java

    1. package com.imooc.code;
    2. import javax.imageio.ImageIO;
    3. import javax.servlet.http.HttpServletRequest;
    4. import javax.servlet.http.HttpServletResponse;
    5. import java.awt.*;
    6. import java.awt.font.FontRenderContext;
    7. import java.awt.geom.Rectangle2D;
    8. import java.awt.image.BufferedImage;
    9. import java.io.IOException;
    10. import java.util.Random;
    11. /**
    12. * 验证码工具类
    13. */
    14. public class CaptcahCode {
    15. /**
    16. * 验证码生成的方法
    17. * @param response
    18. * @return
    19. */
    20. public static String drawImage(HttpServletResponse response) {
    21. //1、定义以字符串的拼接的StringBuilder
    22. StringBuilder builder = new StringBuilder();
    23. //产生4个字符串的随机数
    24. for (int i = 0; i < 4; i++) {
    25. builder.append(randomChar());
    26. }
    27. String code = builder.toString();
    28. //2、定义图片的宽度和高度
    29. int width = 120;
    30. int height = 25;
    31. /**
    32. *建立bufferedImage对象,制定图片的长度和宽度以及色彩,图片的缓冲流
    33. * 把绘制的每个步骤先写入到缓冲流,然后进行输出,达到高效的目的,TYPE_3BYTE_BGR表示三原色
    34. */
    35. BufferedImage bi = new BufferedImage(width,height,BufferedImage.TYPE_3BYTE_BGR);
    36. //3、获取到Graphic2D 绘制对象,开始绘制验证码
    37. Graphics2D g = bi.createGraphics();
    38. //4、设置文字的字体和大小
    39. Font font = new Font("微软雅黑",Font.PLAIN,20);
    40. //设置字体的颜色
    41. Color color = new Color(0,0,0);
    42. //关联字体属性
    43. g.setFont(font);
    44. //关联字体颜色
    45. g.setColor(color);
    46. //设置背景
    47. g.setBackground(new Color(226, 235,240));
    48. //开始绘制对象
    49. g.clearRect(0,0,width,height);
    50. //绘制形状,获取矩形对象
    51. FontRenderContext context = g.getFontRenderContext();
    52. Rectangle2D bounds = font.getStringBounds(code,context);
    53. //计算文字的坐标和间距
    54. double x = (width - bounds.getWidth())/2;
    55. double y = (height - bounds.getHeight())/2;
    56. double ascent = bounds.getY();
    57. double baseY = y - ascent;
    58. g.drawString(code,(int)x,(int)baseY);
    59. //结束绘制
    60. g.dispose();
    61. try {
    62. //这里可能会抛异常,加个try catch,把图片写到response
    63. ImageIO.write(bi,"jpg",response.getOutputStream());
    64. //刷新响应流
    65. response.flushBuffer();
    66. } catch (IOException e) {
    67. e.printStackTrace();
    68. };
    69. //验证码的对比和存储
    70. return code;
    71. }
    72. /**
    73. * 此方法用于产生随机字母和数字组合
    74. * @return
    75. */
    76. private static char randomChar(){
    77. //1、定义验证需要的字母和数字
    78. String string = "QWERTYUIOPASDFGHJKLZXCVBNM1234567890";
    79. //2、定义随机对象,随机从字符串长度中选择一个字符
    80. Random random = new Random();
    81. return string.charAt(random.nextInt(string.length()));
    82. }
    83. }

    code.jsp

    1. <%@ page import="com.imooc.code.CaptcahCode" %>
    2. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    3. <%
    4. //1、清空浏览器缓存,保证验证码图片来自服务器而不是本地缓存
    5. response.setHeader("pragma","no-cache");
    6. response.setHeader("cache-control","no-cache");
    7. response.setHeader("expires","0");
    8. //2、调用编写的生成验证码的工具
    9. String code = CaptcahCode.drawImage(response);
    10. session.setAttribute("code",code);
    11. //我这里遇到一个问题,在firefox和ie没问题,用chrome就打不开,而且还报错ERR_INCOMPLETE_CHUNKED_ENCODING,然后执行下面的第三步操作,chrome就可以了...,
    12. //3、解决getOutputStream异常问题,但是不知道为啥这么些
    13. out.clear();
    14. out = pageContext.pushBody();
    15. %>

    index.jsp

    1. <%--
    2. Created by IntelliJ IDEA.
    3. User: msi
    4. Date: 2020/7/4
    5. Time: 8:47
    6. To change this template use File | Settings | File Templates.
    7. --%>
    8. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    9. <html>
    10. <head>
    11. <title>验证码</title>
    12. </head>
    13. <body>
    14. <img src="code.jsp" alt="oops" id = "code">
    15. <a href="javascript:void(0);" onclick="changeCode()">换一张</a>
    16. <script>
    17. function changeCode() {
    18. //这里加?time=是为了避免浏览器缓存而导致加载不出验证码
    19. document.getElementById("code").src = "code.jsp"+"?time="+new Date().getTime();
    20. }
    21. </script>
    22. </body>
    23. </html>