java制作验证码

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

1,效果图

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 list = new ArrayList();

    @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("验证码不正确");
        }
    }
}

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

你可能感兴趣的:(验证码)