JavaWeb 使用Filter实现自动登录
思路
使用cookie存储账号、密码,使用Filter拦截,从cookie中取出账号、密码。若用户要注销|登出、不再想使用自动登录,将cookie的有效期设置为0即可。
浏览器可以查看Cookie,不能直接存储账号、密码的明文,使用Cookie存储账号、密码时需要加密,从Cookie中取出来时需要解密。
每次HTTP请求都使用Filter拦截,从Cookie中解密出账号、密码,每次都要解密,浪费时间。第一次从Cookie中解密出账号、密码后,可以将账号、密码放到session域中,会话期间直接从session中取,不必再解密。
登录页面
<form action="loginServlet" method="post">
用户名:<input type="text" name="user" /><br />
密码:<input type="password" name="pwd" /><br />
<button type="submit">登录</button><br />
${requestScope.errorMsg}
</form>
EL表达式没有空指针异常,没有时返回空串。所以没有errorMsg时, ${requestScope.errorMsg} 也不会出错。
EL表达式不同于<% %>、<%= %>,EL表达式不会报数组越界、域中没有这个变量(空指针异常)这些错,找不到就返回空串,不会报错。但EL表达式中不能使用+号来拼接字符串。
将登录页面设为项目初始页面
<welcome-file-list>
<welcome-file>/login.jsp</welcome-file>
</welcome-file-list>
处理登录表单的Servlet
@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String user=request.getParameter("user");
String pwd=request.getParameter("pwd");
//连接数据库,检查是否正确
//......
if (true){
//放到session中
HttpSession session = request.getSession();
session.setAttribute("user",user);
session.setAttribute("pwd","pwd");
//将值加密后存储在Cookie中,此处略过加密
Cookie cookie=new Cookie("autoLogin",user+"-"+pwd);
//整个项目中可用
cookie.setPath(request.getContextPath());
//这个域名地址下的所有webApp都可用
//cookie.setPath("/");
cookie.setMaxAge(60*60*24*7);
response.addCookie(cookie);
//重定向到目标页面。request.getContextPath()获取的是当前web应用的根目录
response.sendRedirect(request.getContextPath()+"/index.jsp");
//不能这样写,这样写表示域名下的index.jsp,不是域名/web应用/index.jsp。
//response.sendRedirect("/index.jsp");
}
else{
//转发到登录页面,附加错误信息
request.setAttribute("errorMsg","账户名或密码错误");
request.getRequestDispatcher("/login.jsp").forward(request,response);
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
}
首页
<h2>hello,${sessionScope.user}</h2>
Filter实现自动登录
@WebFilter("/*")
public class HandlerFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
//统一全站编码
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
//ServletRequest不能获取session、cookie,需要强转为HttpServletRequest
HttpServletRequest httpReq = (HttpServletRequest) req;
//检查session中有没有用户信息
HttpSession session = httpReq.getSession();
if (session.getAttribute("user")==null){
//如果session中没有,从Cookie中找autoLogin。可能是会话结束后再次访问,比如离开网站30min(session默认超时时间)后再次访问、关闭浏览器后重新打开再次访问。
Cookie[] cookies = httpReq.getCookies();
//需要先检测cookies是否为null,为null时会报空指针异常
if (cookies!=null){
for (Cookie cookie:cookies){
if (cookie.getName().equals("autoLogin")) {
//需要先解密,此处略过
//......
String[] userInfo=cookie.getValue().split("-");
session.setAttribute("user",userInfo[0]);
session.setAttribute("pwd",userInfo[1]);
}
}
}
}
chain.doFilter(req, resp);
}
public void init(FilterConfig config) throws ServletException {
}
}
ServletRequest不能获取session、cookie,需要强转为HttpServletRequest才可以。
处理注销 | 登出 | 不再使用自动登录 的Servlet
@WebServlet("/logoutServlet")
public class LogoutServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//从session中移出用户信息
HttpSession session = request.getSession();
session.removeAttribute("user");
session.removeAttribute("pwd");
//删除Cookie,此处采用同名覆盖,也可以遍历获取,再将有效期设为0
Cookie cookie=new Cookie("autoLogin","");
cookie.setPath(request.getContextPath());
cookie.setMaxAge(0);
response.addCookie(cookie);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
}
获取当前WebApp的根目录:
String path1 = request.getContextPath(); //通过request对象来获取
String path2 = getServletContext().getContextPath(); //通过ServletContext对象来获取
这2种方式获取的都是相对路径。
获取当前WebApp中的某个资源在服务器上的绝对路径:
String path3 = getServletContext().getRealPath("/index.jsp"); //通过ServletContext对象来获取
就是把当前项目的根目录(绝对路径)、参数中的路径拼接在一起。
JavaWeb 使用Filter实现自动登录的更多相关文章
- JavaWeb学习记录总结(二十九)--Servlet\Session\Cookie\Filter实现自动登录和记住密码
一.Servlet package autologin.servlet.login; import java.io.IOException;import java.security.MessageDi ...
- JavaWeb 之 Filter 验证用户登录案例
需求: 1. 访问一个网站的资源.验证其是否登录 2. 如果登录了,则直接放行. 3. 如果没有登录,则跳转到登录页面,提示"您尚未登录,请先登录". 代码实现: import j ...
- 二十 Filter&自动登录功能
Filter过滤器 过滤器,其实就是对客户端发出来的请求进行过滤,浏览器发出,然后服务器用Servelt处理.在中间就可以过滤,起到的是拦截的作用. 不仅仅作用于客户端请求,而且过滤服务器响应 作用: ...
- JavaWeb 后端 <十二> 之 过滤器 filter 乱码、不缓存、脏话、标记、自动登录、全站压缩过滤器
一.过滤器是什么?有什么? 1.过滤器属于Servlet规范,从2.3版本就开始有了. 2.过滤器就是对访问的内容进行筛选(拦截).利用过滤器对请求和响应进行过滤
- 实现自动登录:Filter 实现思路和方式
当你勾选(记住登录状态),用cookie保存用户名和密码.不勾选,cookie失效. 所有的页面都要经过autoLoginFilter.java 的过滤器,在这类中,必须要判断cookies不为nul ...
- 【JAVAWEB学习笔记】24_filter实现自动登录和解决全局的编码问题
过滤器Filter 学习目标 案例-自动登录 案例-解决全局的编码 一.过滤器Filter 1.filter的简介 filter是对客户端访问资源的过滤,符合条件放行,不符合条件不放行,并且可以对目标 ...
- Filter自动登录
Dao层略过 Domain略过 Service层过 Web层 Select逻辑 获取表单数据,Web-service--Dao返回用户信息 如果返回不为null否则,重定向到登录页面.则判断用户是否勾 ...
- 自动登录(过滤器filter的应用)
//反复实验的时候注意数据库数据的更新 //将数据存储到cookie里面 protected void doGet(HttpServletRequest request, HttpServletRes ...
- Filter应用之-自动登录
自动登录,是为了帮助用户多次使用这个网页时,不用再次输入用户名和密码就可以登录. 是指用户将用户的登录信息,人,保存到本地的文件中Cookie中. Name,value – 声明时 new Cooki ...
随机推荐
- MyBatisPlus快速入门
MyBatisPlus快速入门 官方网站 https://mp.baomidou.com/guide 慕课网视频 https://www.imooc.com/learn/1130 入门 https:/ ...
- JDOJ 1775: 求N!中0的个数
JDOJ 1775: 求N!中0的个数 JDOJ传送门 Description 求N!结果中末尾0的个数 N! = 1 * 2 * 3 ....... N Input 输入一行,N(0 < N ...
- VIJOS-P1078 松鼠吃果子
洛谷 P2069 松鼠吃果子 https://www.luogu.org/problemnew/show/P2069 JDOJ 1256: VIJOS-P1078 松鼠吃果子 https://neoo ...
- 【2019.7.16 NOIP模拟赛 T1】洗牌(shuffle)(找环)
找环 考虑每次洗牌其实是一次置换的过程,而这样必然就会有循环出现. 因此我们直接通过枚举找出每一个循环,询问时只要找到环上对应的位置就可以了. 貌似比我比赛时被卡成\(30\)分的倍增简单多了? 代码 ...
- wpf “{DependencyProperty.UnsetValue}”不是属性“Background”的有效值。异常
, 在wpf模板中, 有一个Background绑定的值不存在导致的异常, 我的是有这个没有导致的错误, 自己添加之后就没有了
- golang中判断两个slice是否相等
在golang中我们可以轻松地通过==来判断两个数组(array)是否相等,但遗憾的是slice并没有相关的运算符,当需要判断两个slice是否相等时我们只能另寻捷径了. slice相等的定义 我们选 ...
- 妖娆的HTML
初涉前端之HTML 1.首先是Web服务的本质,是怎么工作的?(基于python的网络实现) import socket server = socket.socket() server.bind((' ...
- MySQL-InnoDB-MVCC多版本并发控制
一.MySQL可重复读级别下,因为MVCC引起的BUG,下图1为相应的Java代码,其中事务1的生命周期最长,循环开启的事务2.3.4...与事务1并行 ,数据的读取只会成功一次,后面的读不到新增数据 ...
- .NET Core创建Worker Services
.NET CORE 3.0新增了Worker Services的新项目模板,可以编写长时间运行的后台服务,并且能轻松的部署成windows服务或linux守护程序.如果安装的vs2019是中文版本,W ...
- 在 C++ 中使用 QML 对象
看过了如何在 QML 中使用 C++ 类型或对象,现在来看如何在 C++ 中使用 QML 对象. 我们可以使用 QML 对象的信号.槽,访问它们的属性,都没有问题,因为很多 QML 对象对应的类型,原 ...