java制作验证码

java制作验证码(成语+背景图)

1,效果图

这里写图片描述
点击验证码图片或者点击“看不清,换一张”就会重新生成一张验证码。

2,整体思路

       验证码分为背景图和一个随机的成语,利用画笔画图,加上随机产生的成语,然后把验证码内容保存到session中以便后台验证,最后用ImageIO类输出到页面上。

3,jsp编写

<script type="text/javascript">
    function change() {
        document.getElementById("pic").src = "${pageContext.request.contextPath}/checkcode?time"+new Date().getTime();
    };
</script>

<form action="${pageContext.request.contextPath }/login" method="post">
    <table align="center" width="40%">
        <tr>
            <td>验证码</td>
            <td><input type="text" name="checkcode" id="checkcode">
                <img src='${pageContext.request.contextPath}/checkcode' id="pic"
                    onclick="change();">
                <span id="checkcode_span">
                    <a href="javascript:void(0)" onclick="change();">
                    <font color='black'>看不清,换一张</font>
                    </a>
                </span>
            </td>
        </tr>
    </table>
</form>

4,生成验证码Servlet编写

生成验证码保存在session中,将验证码图片信息输出到页面上显示。

public class CheckImageServlet extends HttpServlet {

    // 集合中保存所有成语
    private List<String> list = new ArrayList<String>();

    @Override
    public void init() throws ServletException {

        // web工程中读取idiom.txt文件,使用绝对磁盘路径,文件中放的是成语
        String path = getServletContext().getRealPath("/WEB-INF/idiom.txt");
        try {
            FileInputStream fis = new FileInputStream(path);
            InputStreamReader isr = new InputStreamReader(fis,"utf-8");
            BufferedReader br = new BufferedReader(isr);

            String line;
            while ((line = br.readLine()) != null) {
                list.add(line);
            }
            br.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        int width = 120;
        int height = 30;

        // 步骤一 绘制一张内存中图片
        BufferedImage bufferedImage = new BufferedImage(width, height,
                BufferedImage.TYPE_INT_RGB);

        // 步骤二 图片绘制背景颜色 ---通过绘图对象
        // 得到画图对象 (画笔)
        Graphics graphics = bufferedImage.getGraphics();
        // 绘制任何图形之前都必须指定一个颜色
        graphics.setColor(getRandColor(200, 250));
        graphics.fillRect(0, 0, width, height);

        // 步骤三 绘制边框
        graphics.setColor(Color.WHITE);
        graphics.drawRect(0, 0, width - 1, height - 1);

        // 步骤四 四个随机数字
        Graphics2D graphics2d = (Graphics2D) graphics;
        // 设置输出字体
        graphics2d.setFont(new Font("宋体", Font.BOLD, 18));

        Random random = new Random();// 生成随机数
        int index = random.nextInt(list.size());
        String idiom = list.get(index);// 获得成语

        // 定义x坐标
        int x = 10;
        for (int i = 0; i < idiom.length(); i++) {
            // 随机颜色
            graphics2d.setColor(new Color(20 + random.nextInt(110), 20 + random
                    .nextInt(110), 20 + random.nextInt(110)));
            // 旋转 -30 --- 30度
            int jiaodu = random.nextInt(60) - 30;
            // 换算弧度
            double theta = jiaodu * Math.PI / 180;

            // 获得字母数字
            char c = idiom.charAt(i);

            // 将c 输出到图片
            graphics2d.rotate(theta, x, 20);
            graphics2d.drawString(String.valueOf(c), x, 20);
            graphics2d.rotate(-theta, x, 20);
            x += 30;
        }

        // 将验证码内容保存session
        request.getSession().setAttribute("checkcode_session", idiom);
        System.out.println(idiom);

        // 步骤五 绘制干扰线
        graphics.setColor(getRandColor(160, 200));
        int x1;
        int x2;
        int y1;
        int y2;
        for (int i = 0; i < 30; i++) {
            x1 = random.nextInt(width);
            x2 = random.nextInt(12);
            y1 = random.nextInt(height);
            y2 = random.nextInt(12);
            graphics.drawLine(x1, y1, x1 + x2, x2 + y2);
        }

        // 将上面图片输出到浏览器 ImageIO
        graphics.dispose();// 释放资源
        ImageIO.write(bufferedImage, "jpg", response.getOutputStream());

    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

    //取其某一范围的color
    private Color getRandColor(int fc, int bc) {
        // 取其随机颜色
        Random random = new Random();
        if (fc > 255) {
            fc = 255;
        }
        if (bc > 255) {
            bc = 255;
        }
        int r = fc + random.nextInt(bc - fc);
        int g = fc + random.nextInt(bc - fc);
        int b = fc + random.nextInt(bc - fc);
        return new Color(r, g, b);
    }
}

5,主servlet编写

获取用户输入的验证码,判断和从session中取出来的验证码是不是一样。

public class LoginServlet extends HttpServlet {
    @Override
    public void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
        //获取用户输入的验证码
        String checkcode = request.getParameter("checkcode");
        String sessionCheckcode = (String) request.getSession().getAttribute("checkcode_session");

        System.out.println("checkcode = " + checkcode);
        System.out.println("sessionCheckcode= " + sessionCheckcode);

        if (sessionCheckcode == null || (!sessionCheckcode.equals(checkcode))) {
            System.out.println("验证码不正确");
        }
    }
}

到此也就结束了٩(˘◡˘ )

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值