文章目录

  • 1.实现最简单的登录
  • 2.过滤器处理中文乱码
  • 3.编写最简单前端页面
  • 4.编写验证码servlet
  • 5.修改前端页面,添加验证码和自动登录按钮
  • 6.实现自动登录
  • 7.前端脚本编写:读取cookie并实现验证的点击切换
  • 8.小结

1.实现最简单的登录

首先,要想实现验证码和自动登录就要弄清楚登录这个过程中有多少步骤,那么接下来我来说说我的登录逻辑。

首先,要实现登录,必须要servlet去验证输入的用户名和密码是否正确,
那么简单的servlet就出炉了:

package com.ps.Servlet;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;//这里配置的就是以后表单要提交的地址
@WebServlet(urlPatterns = "/Login")
public class LoginServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//获取数据String username = request.getParameter("username");String password = request.getParameter("password");//在这里应该是把参数传给数据库来判断的,为了简便演示,我就先这么写了if ("admin".equals(username) && "123456".equals(password)) {//把登录后的信息存储在会话域中,方面访问别的页面使用session.setAttribute("username", username);//跳转到index页面response.sendRedirect("index.jsp");} else {//输入的信息错误,跳回到原页面,需要重新输入request.getRequestDispatcher("login.html").forward(request, response);}
}

2.过滤器处理中文乱码

写到这里实现并运行过的小伙伴就会发现一个问题,那就有些时候传入的参数会乱码,尤其是在传入中文的时候会乱码。

原因是我没有处理请求的编码格式,这是为什么呢?

因为在比较大的项目中,这种问题经常会出现,如果每个servlet里面都加入的话,就比较麻烦,为了不麻烦,那我们编写一个处理请求参数乱码问题的过滤器(filter)就好了。

不会没有关系,代码在下面:

package com.ps.Filter;import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;/*** 目标:* 拦截请求,把涉及到登录和注册的请求拦截下来,修改请求编码避免获取参数的时候乱码*///这里配置的就是servlet1的路径配置成完全一样的就好了
@WebFilter(urlPatterns = "/Login")
public class RequestFilter implements Filter {public void destroy() {}public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {//1.强性把类型转换,便于操作HttpServletRequest request = (HttpServletRequest) req;HttpServletResponse response = (HttpServletResponse) resp;//2.修改编码,防止乱码request.setCharacterEncoding("utf-8");//3.放行chain.doFilter(request, response);}public void init(FilterConfig config) throws ServletException {}
}

3.编写最简单前端页面

写完上面两个步骤的话,我们就可以先写一个前端页面来测试一下了。


<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>login</title>
</head>
<body>
<h2>用户登录</h2>
<!--form的id是为了以后自动登录的时候获取,method就是请求的方法,action就是请求的servlet地址,就是前面配置的那个-->
<form action="Login" method="post" id="loginForm"><!--name属性是给servlet获取值的-->用户名:&nbsp;<input name="username" type="text"><br><br>密码:&nbsp;<input name="password" type="password"><br><br><input value="登录" type="submit">
</form>
</body>
</html>

以上,就是最简单的一个登录功能的实现了,我相信都已经跟的上了,那么接下来我们就稍稍微微的加快点速度

4.编写验证码servlet

这里其实没有太多好说的,都是比较固定的东西,所以看看就好。

package com.ps.Servlet;import javax.imageio.ImageIO;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;/*** 生成验证码,并把验证码存储在会话域中*/
@WebServlet(urlPatterns = "/Encode")
public class EncodeServlet extends HttpServlet {// 写一个方法随机获取颜色public Color randomColor() {// r g b 取值范围 0到255Random random = new Random();return new Color(random.nextInt(256),random.nextInt(256),random.nextInt(256));}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doGet(request, response);}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 创建缓存图片:指定宽width=90,高 height=30int width = 90;int height = 30;BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);// 获取画笔对象Graphics g = image.getGraphics();// 设置画笔颜色,并且填充矩形区域g.setColor(Color.white);g.fillRect(0, 0, width, height);// 创建可变字符串StringBuilder sb = new StringBuilder();// 从字符数组中随机得到字符,根据需求添加你需要的字符char[] arr = {'1', '2', '3', '4', '5', '6', '7', '8', '9', '0','A', 'B', 'C', 'D', 'N', 'E', 'W', 'b', 'o', 'y'};// 创建随机对象Random r = new Random();for (int i = 0; i < 4; i++) {// 随机产生一个索引值int index = r.nextInt(arr.length);// 根据索引获得随机字符char ch = arr[index]; // 拼接字符sb.append(ch);// 设置字体,大小为 18g.setFont(new Font(Font.DIALOG, Font.BOLD + Font.ITALIC, 18));// 设置字的颜色随机g.setColor(randomColor());// 绘制字符串// 7. 将每个字符画到图片上,位置:int x = 5 + (i * 20);int y = 20;g.drawString(String.valueOf(ch), x, y);}// 将验证码字符串存储会话域中HttpSession session = request.getSession();session.setAttribute("verCode", sb.toString());// 8. 画10条干扰线,线的位置是随机的,x 范围在 width 之中,y 的范围在 height 之中。for (int i = 0; i < 10; i++) {// 设置颜色随机g.setColor(randomColor());int x1 = r.nextInt(width + 1);int x2 = r.nextInt(height + 1);int y1 = r.nextInt(width + 1);int y2 = r.nextInt(height + 1);g.drawLine(x1, y1, x2, y2);}// 9. 将缓存的图片输出到响应输出流中ImageIO.write(image, "png", response.getOutputStream());}
}

这样写完之后,我们前端页面只需要把img标签的src地址写成我们servlet的地址就可以实现验证码了。而之前的servlet也只需要根据相应的标签获取页面的验证码,再去获取会话域中的存放的正确验证码即可,由于还要实现自动登录,一会儿一起放最终结果好了。

5.修改前端页面,添加验证码和自动登录按钮

前面已经把主要功能实现了,那么接下来就是随便修改一下页面就好了,如下:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>login</title><style>body {margin-top: 20px;margin: 0 auto;}.carousel-inner .item img {width: 100%;height: 300px;}.container .row div {/* position:relative;float:left; */}font {color: #666;font-size: 22px;font-weight: normal;padding-right: 17px;}</style>
</head>
<body>
<div class="container" style="width:100%;height:460px;"><div class="row"><div class="col-md-5"><div style="width:440px;border:1px solid #E7E7E7;padding:20px 0 20px 30px;border-radius:5px;margin-top:60px;background:#fff;"><form id="loginForm" class="form-horizontal" action="Login" method="post"><div class="form-group"><label for="username" class="col-sm-2 control-label">用户名</label><div class="col-sm-6"><!--表单要加上name属性,否则服务器得到不值--><input type="text" class="form-control" name="username" id="username" placeholder="请输入用户名"></div></div><div class="form-group"><label for="password" class="col-sm-2 control-label">密码</label><div class="col-sm-6"><input type="password" class="form-control" name="password" id="password"placeholder="请输入密码"></div></div><div class="form-group"><label for="verCode" class="col-sm-2 control-label">验证码</label><div class="col-sm-3"><input type="text" class="form-control" name="verCode" id="verCode" placeholder="请输入验证码"></div><div class="col-sm-3"><img src="Encode" style="width: 90px; height: 30px; cursor: pointer;"onclick="changeImage(this)"title="看不清,点击刷新"></div></div><div class="form-group"><div class="col-sm-offset-2 col-sm-10"><div class="checkbox"><label><input name="remember" type="checkbox"> 自动登录</label>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div></div></div><div class="form-group"><div class="col-sm-offset-2 col-sm-10"><input id="click" type="submit" width="100" value="登录" name="submit" border="0"style="  eight:35px;width:100px;"></div></div></form></div></div></div>
</div>
</body>
</html>

这样一个比较有代表性的框就有了,只需要实现功能就可以了。

6.实现自动登录

要想实现自动登录,那么就要明白自动登录是用什么实现的。

cookie这是唯一一个存在用户浏览器的一组数据,所以想要实现自动登录,就只能通过cookie来实现,完成这一步的时候,如果浏览器禁用了cookie,记得解除。

那么如何实现登录,其实就是在用户请求数据,服务器返回响应的时候,把用户名和密码以cookie的形式返回给客户端,这样下次登陆的时候,就只需要在前端页面编写js脚本实现读取cookie和自动发起请求即可实现。

但是我们现在多了一个验证码呀,这可怎么办呢?

其实也很简单,思路就是:

在cookie中多添加一个验证码的cookie,内容输入为不可能出现的验证码,这样用户在自己输入的时候就不会那样输入,而你又可以实现自动登陆了。

这样实现就可以了吗?

一般情况下是可以了,但是架不住有些小伙伴神通广大呀,想要更强力的杜绝,最好是把验证码框的内容长度也给定死了,在我们脚本读取cookie的时候,在手动修改长度,这样验证码可以任意长度任意字符串,就可以杜绝大部分小伙伴了,毕竟它不知道你的真实验证码是什么。

那么接下来,我们来实现自动登陆中servlet的编写,也顺便把验证码的判断加入进去:

package com.ps.Servlet;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;@WebServlet(urlPatterns = "/Login")
public class LoginServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//1.获取数据String username = request.getParameter("username");String password = request.getParameter("password");String remember = request.getParameter("remember");String code = request.getParameter("verCode");//2.获取会话域中的验证码HttpSession session = request.getSession();String encode = (String) session.getAttribute("verCode");//3.判断验证码是否通过,记住密码的,或者是输入验证码正确的if (code.equals(encode) || code.equals("remember")) {//4.验证码输入正确,判断输入的信息是否正确if ("admin".equals(username) && "123456".equals(password)) {//6.输入的信息正确,查看是否需要记住账号和密码if (remember != null) {//8.需要记住账号和密码实现自动登录,创建cookieCookie uCookie = new Cookie("username", username);uCookie.setMaxAge(6000);response.addCookie(uCookie);Cookie pCookie = new Cookie("password", password);pCookie.setMaxAge(6000);response.addCookie(pCookie);Cookie codeCookie = new Cookie("verCode", "remember");codeCookie.setMaxAge(600);response.addCookie(codeCookie);}//9.把登录后的信息存储在会话域中,方面访问别的页面使用session.setAttribute("username", username);//10.跳转到index页面response.sendRedirect("index.jsp");} else {//7.输入的信息错误,跳回到原页面,需要重新输入request.getRequestDispatcher("login.html").forward(request, response);}} else {//5.验证码输入不正确,需要重新输入request.getRequestDispatcher("login.html").forward(request, response);}}
}

写到这里大部分小伙伴就发现了,哎好像后台该实现的都实现了,前端页面的按钮啥的也都有了,那是不是可以用了?其实还不可以,还有一些脚本没有编写,那么最后一步就是脚本的编写了

7.前端脚本编写:读取cookie并实现验证的点击切换

你看就这么简单就到最后一步了,前端页面脚本的编写其实没那么难,那么我们就先来实现一下验证码的点击切换功能。

看过之前页面的小伙伴一定还记得,我在img标签上加入了onclick属性,并写了一个函数名,那么我们就以那个函数名来编写一下,切换函数:

<script>function changeImage(img) {//给对应的servlet发送请求,并添加输入值//如果不添加输入值,会让服务器认为你在重复请求//认为你请求的时间太短了,不需要响应,进而使用本地数据缓存//导致验证码点击切换失败img.src = "Encode?t=" + Math.random();}
</script>

看了上面的脚本,非常的简单是吧,确实是,那么我们在一鼓作气把读取cookie的也写了吧。

<script>//如果你的脚本放在页面的最开始就一定要加入这个函数//不然你写的脚本就无法运行了window.onload = function () {// 读取Cookie信息var cookies = document.cookie;// 如果cookie不为空if (cookies) {// 得到用户名、密码和验证码// 其实就是一组键值对,根据你设置好的来就可以了var username = getCookie("username"); var password = getCookie("password"); var code = getCookie("verCode");// 填写相应的数值document.getElementById("username").value = username;document.getElementById("password").value = password;document.getElementById("verCode").value = code;// 提交表单document.getElementById("click").click();}};//获取cookie的值function getCookie(cname) {//由于读取的cookie是通过;来分割的,所以需要根据;来获取对应的参数var ca = document.cookie.split(';'); for (var i = 0; i < ca.length; i++) {var c = ca[i]; var arr = c.split("="); //这里一定要加入trim,这个很重要//为什么呢?因为cookie会在其中加入一些空格//去掉空格之后才能获取到正确的数值if (arr[0].trim() == cname) { return arr[1];}}return "";}
</script>

写到这里,内容基本就写完了,接下来就该测试一下代码了:




反复进入登录页面,哎,验证码登录和自动登录都实现了。

你学会了吗?

8.小结

那么我们象征性的小结一下吧。

如何实现自动登录:

1.在前端页面设置自动登录按钮
2.servlet获取是否要自动登录
3.自动登录则返回cookie给浏览器,让浏览器保存
4.编写脚本来帮助我们自动填写cookie中的数据

如何实现验证码:

1.编写能生成验证的servlet(不会写没关系,直接复制就好)
2.在前端页面加入img标签,并把src路径写成生成验证码的servlet的路径
3.设置name属性,便于后台servlet获取数据
4.编写脚本函数实现点击刷新验证码

如何同时实现验证和自动登录:

1.设定一个字符串为自动登录时的验证码
2.把这个字符串设置成cookie,并返回给浏览器
3.脚本实现自动登录的时候,把设置的字符串输入进去
4.当servlet判断到验证码是设置好的验证码时,放行,直接去判断用户名和密码是否正确

带你一步一步实现验证码登录和自动登录相关推荐

  1. python discuz验证码_python实现自动登录discuz论坛

    最近被公司的事情搞的很纠结,博客也有段时间没写了,不过最近还是忙里偷闲做了点其他事情,在这里记录下来,和大家分享一下. 需求也比较简单,老婆是做社区运营的,所以需要每天把几个帖子定时的顶上来,手工做很 ...

  2. 手挽手带你学React:四档(上)一步一步学会react-redux (自己写个Redux)

    手挽手带你学React入门四档,用人话教你react-redux,理解redux架构,以及运用在react中.学完这一章,你就可以开始自己的react项目了. 之前在思否看到过某个大神的redux搭建 ...

  3. 从零开始带你一步一步使用 YOLOv3 测试自己的数据

    上一篇: 从零开始带你一步一步使用YOLOv3训练自己的数据 我给大家详细介绍了如何使用 YOLOv3 模型来训练自己的数据集.训练部分完成,本文将继续给大家详细介绍如何使用我们训练好的模型来进行图片 ...

  4. 从零开始带你一步一步使用YOLOv3测试自己的数据

    红色石头的个人网站:redstonewill.com 知乎:https://www.zhihu.com/people/red_stone_wl 公众号:AI有道(redstonewill) 上一篇: ...

  5. 从零开始带你一步一步使用YOLOv3训练自己的数据

    红色石头的个人网站:redstonewill.com 知乎:https://www.zhihu.com/people/red_stone_wl 公众号:AI有道(redstonewill) YOLOv ...

  6. 从爬虫构建数据集到CNN模型的验证码识别,一步一步搭建基于Python的PC个人端12306抢票程序

    写在前面:这个程序不是一个人能在短时间内完成的,感谢达纳,王哥的支持帮助.也感谢小平老师,没有压迫,就没有项目. 简介:这是一篇很硬核的Blog, 有一定Python基础的童鞋方能看懂,本程序的主要内 ...

  7. a4988 脉宽要求_Allegro MicroSystems 公司发布全新带过流保护的 DMOS 微步电动机驱动器 A4988...

    Allegro MicroSystems 公司发布全新带过流保护的 DMOS 微步电动机驱动器 A4988 热效率高.封装小巧精致 马萨诸塞州伍斯特-2010 年 4 月 29 日 - Allegro ...

  8. 一步一步,手把手带你用最简单的方法,在linux上安装anaconda

    1 前言 本文将会一步一步用最简单的方法,手把手带你在linux上安装anaconda,不改文件,不需要管理员权限,普通用户也可以操作! 当我们想利用服务器进行深度学习/数据分析时,我们通常需要使用P ...

  9. 你还停留在使用Dagger2吗? 带你一步一步走进Dagger2的世界

    Dagger2是一个依赖注入框架 1.什么是依赖注入? 就是目标类中所依赖的其他的类的初始化过程,不是通过手动编码的方式创建 将其他的类初始化好的实例自动注入到我们的目标类当中.它也是面向对象的一种设 ...

最新文章

  1. tf.cast()数据类型转换
  2. 54. spring boot日志升级篇—logback【从零开始学Spring Boot】
  3. C++求从1到n的正整数中1出现的次数
  4. centos7 安装配置mesos+marathon+zookeeper
  5. 甘肃关于领取软考2021年上半年合格证书的通知
  6. JS-数据属性与访问器属性
  7. Go非阻塞channel的常见写法
  8. SX1280抗WIFI强干扰电磁环境能力解析
  9. javascript测试_了解有关JavaScript承诺的更多信息:25次测试中从零到英雄
  10. 用python为喜欢的人写一个程序,每天发送贴心的消息
  11. linux服务器的诗句迁移,使用scp命令在两台linux上对拷文件或者文件夹
  12. SharePoint 常用操作杂谈
  13. mysql gtid 集群_Docker搭建MySQL主从集群,基于GTID
  14. BP神经网络分类算法
  15. Hi3559a移植Opencv3.0
  16. 【场景化解决方案】ERP系统与钉钉实现数据互通
  17. 重学 statistics, Cha10 Inference About Means and Proportions with Two Populations
  18. 机器学习 数据集划分 训练集 验证集 测试集
  19. Linux中的/proc文件系统详解(C/C++代码实现)
  20. Android系统:如何开启或隐藏Navigation Bar导航 栏

热门文章

  1. i3处理器_9400F的正式下岗证,i3-10100F正版盒装装机指南_主板
  2. 武林风云之数据库插入
  3. python热搜排行功能_简单几行代码用Python爬取微博的热搜榜
  4. 面试常败给微服务?我总结了一套核心资料三天肝完……
  5. Vue项目引入echarts
  6. photoshopcc基础教程
  7. 浅谈Linux用户态和内核态
  8. Spring事务注解Transactional失效
  9. 怎么裁剪视频时长?手把手教你裁剪
  10. ps插件DR5扩展面板dr4.5升级版磨皮调色工笔画集合