Servlet---登录界面添加验证码

本文介绍了如何在Servlet中实现登录界面的验证码功能,包括生成随机验证码的Servlet代码,网页设置验证码图片及点击刷新事件,以及在过滤器中放行验证码请求,并在登录验证时优先检查验证码的正确性。通过引入随机数防止重复请求,确保了验证码的安全性和用户体验。
摘要由CSDN通过智能技术生成

基本思路

在网页设置的登录login.jsp文件里加上输入验证码的操作,引入带有验证码的图片。生成验证码的CodeServlet太过麻烦不需要自己写,去网上找一个即可**,但是,要在获得的生成验证码图片文件中将验证码图片中的随机数放进session以获取用于验证。**并且设置一个验证码点击刷新事件(会用到jQuery)。

具体步骤

1.codeServlet

@WebServlet("/code")
public class CodeServlet extends HttpServlet {
	private static final long serialVersionUID = 2376992603034716655L;
	private final Font mFont = new Font("Arial Black", Font.PLAIN, 15); // 设置字体
	private final int lineWidth = 2; // 干扰线的长度=1.414*lineWidth
	private final int width = 88; // 定义图形大小
	private final int height = 25; // 定义图形大小
	private final int count = 200;

	
	private Color getRandColor(int fc, int bc) { // 取得给定范围随机颜色
		final Random random = new Random();
		if (fc > 255) {
			fc = 255;
		}
		if (bc > 255) {
			bc = 255;
		}
		final int r = fc + random.nextInt(bc - fc);
		final int g = fc + random.nextInt(bc - fc);
		final int b = fc + random.nextInt(bc - fc);
		return new Color(r, g, b);
	}

	// 处理post
	@Override
	public void doPost(final HttpServletRequest request, final HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

	@Override
	public void doGet(final HttpServletRequest request, final HttpServletResponse response)
			throws ServletException, IOException {
		response.reset();
		// 设置页面不缓存
		response.setHeader("Pragma", "No-cache");
		response.setHeader("Cache-Control", "no-cache");
		response.setDateHeader("Expires", 0);
		response.setContentType("image/gif");
		// 在内存中创建图象
		final BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		// 获取图形上下文
		final Graphics2D g = (Graphics2D) image.getGraphics();
		// 生成随机类
		final Random random = new Random();
		// 设定背景色
		g.setColor(getRandColor(200, 250)); // ---1
		g.fillRect(0, 0, width, height);
		// 设定字体
		g.setFont(mFont);
		// 画边框
		g.setColor(getRandColor(0, 20)); // ---2
		// 距离
		g.drawRect(0, 0, width - 1, height - 1);
		// 随机产生干扰线,使图象中的认证码不易被其它程序探测到
		for (int i = 0; i < count; i++) {
			g.setColor(getRandColor(150, 200)); // ---3
			final int x = random.nextInt(width - lineWidth - 1) + 1; // 保证画在边框之内
			final int y = random.nextInt(height - lineWidth - 1) + 1;
			final int xl = random.nextInt(lineWidth);
			final int yl = random.nextInt(lineWidth);
			g.drawLine(x, y, x + xl, y + yl);
		}

		// 取随机产生的认证码(4位数字)
		String sRand = "";
		for (int i = 0; i < 4; i++) {
			final String rand = String.valueOf(random.nextInt(10));
			sRand += rand;
			// 将认证码显示到图象中,调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成
			g.setColor(new Color(20 + random.nextInt(130), 20 + random.nextInt(130), 20 + random.nextInt(130))); // --4--50-100
			// 第一个参数是要画上去的字符串 后面两个参数是针对 (0,0) x轴和y轴
			g.drawString(rand, (13 * i) + 10, 20);
		}

// 把生成的随机数,保存到session里面
		HttpSession session = request.getSession();
		session.setAttribute("sessionCode", sRand);

		// 图象生效
		// 它的作用是销毁程序中指定的图形界面资源,如果在使用了graphics获得windows一些图形资源,而不进行关闭的话,由于后期多人使用就会造成内存溢出的情况的,导致程序卡死。
		g.dispose();
		OutputStream os = response.getOutputStream();
		// 输出图象到页面
		ImageIO.write(image, "PNG", os);
		os.flush();
		os.close();
	}
}

2.网页设置

注意这一句,在获得的路径后加了一串随机数,因为每次点击图片切换都是在发送相同的请求,为了避免服务器不接受相同的许多请求,加上随机数会让请求变的各不相同。

$("#imageCode").attr('str',"<%=request.getContextPath()%>/code?" + Math.random() );

只截取body部分

<body>
<form action="<%=request.getContextPath()%>/user?method=login" method="post">
    用户名:<input type="text" name="name"/><br/>
    密码:<input type="password" name="password"/><br/>
    验证码:<input type="text" name="code"/><img src="<%=request.getContextPath()%>/code" id="imgCode" onclick="refreshCode()"/><br />
    <input type="submit" value="登录"/>
</form>
<script src="<%=request.getContextPath()%>/static/jquery-2.1.4.js" type="text/javascript" charset="UTF-8"></script>
<script type="text/javascript">
    function refreshCode(){
        $("#imageCode").attr('str',"<%=request.getContextPath()%>/code?" + Math.random() );
        }
</script>
</body>

2.放行

加入图片后我们会发现由于被拦截我们的界面又被重定向回了登录界面,所以修改之前过滤器loginFilter中doFilter以达到放行效果。

@Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("loginFilter.doFilter");

        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;

        String servletPath = httpServletRequest.getServletPath();
        System.out.println("servletPath = " + servletPath);
        String method = httpServletRequest.getParameter("method");
        System.out.println("method = " + method);

        if (servletPath.equals("/login.jsp")
                || (servletPath.equals("/user") && method.equals("login"))
                 || servletPath.equals("/fail.jsp")
                 || servletPath.equals("/code")
                || servletPath.endsWith(".js")
                || servletPath.endsWith(".css")){
            chain.doFilter(request,response);
            return;
        }

        HttpSession httpSession = httpServletRequest.getSession();
        User user = (User) httpSession.getAttribute("user");
        System.out.println("user = " + user);

        if (user == null){
            httpServletResponse.sendRedirect(httpServletRequest.getContextPath() + "/login.jsp");
            return;
        }
        chain.doFilter(request,response);
    }

3.设置优先检查验证码

点击提交submit可以将在网页输入的用户名、密码和验证码一并传输给userServlet的login方法,我们要去配置先验证验证码,只要验证码错误,之后的代码就不再运行。

        String code = req.getParameter("code");
        HttpSession httpSession = req.getSession();
        String sessionCode = (String) httpSession.getAttribute("sessionCode");
        if(!sessionCode.equals(code)){
            resp.sendRedirect(req.getContextPath() + "/login.jsp");
            return;
        }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值