原创声明:本文来源于本人另一博客【基于cookie使用过滤器实现客户每次访问自登陆一次】原创作品,绝非他处摘取,转载请联系博主
相信大家在各大网站都会遇到,登录时,在登录框出现下次免登陆/一个月免登陆的类似选项,本次博文就是讲解如何实现,在这记录一下,也算是做个备忘录,如果文中有错,欢迎大家指出
为啥说自登陆一次呢,因为当访问某个页面时,如果第一次自动登录失败时,你下次刷新访问时还再次走自动登录流程,就会出现死循环。
本篇博文代码示例框架为Spring MVC,下面就讲解实现该功能的需要掌握哪些知识:cookies与过滤器
1.cookies
我们看一下是如何保存cookies和如何删除cookies
保存cookies
String newUserName = null; try { newUserName = URLEncoder.encode(username, "UTF-8");//把用户名转码,防止用户名是中文,cookies保存中文取出会乱码 } catch (UnsupportedEncodingException e) { e.printStackTrace(); } Cookie nameCookie = new Cookie("username", newUserName); String pwdMd5Cook = MD5Util.MD5(Pwd); Cookie pwdCookie = new Cookie("pwd", pwdMd5Cook);// 保存加密后的密码 nameCookie.setMaxAge(60 * 60 * 24 * 365);// 用户名保存一年 pwdCookie.setMaxAge(60 * 60 * 24 * 30);// 密码保存30天 // 发送Cookie信息到浏览器 response.addCookie(nameCookie); response.addCookie(pwdCookie);
删除cookies,删除很简单,但值得注意的时,删除cookies,跟保存cookies一定要在同一个控制层,不然会找不到保存的cookies,导致删除不了
Cookie cookie = new Cookie("pwd", null); cookie.setMaxAge(0);// 删除密码cookie response.addCookie(cookie);
2.过滤器
import java.io.IOException; import java.io.PrintWriter; import java.net.URLDecoder; import java.util.HashMap; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; public class suicaiFilter implements Filter { @Override public void destroy() { } @Override public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException { HttpServletRequest req=(HttpServletRequest)request; HttpServletResponse res=(HttpServletResponse)response; HttpSession session = req.getSession(); String requestURI = req.getRequestURI(); String param = req.getQueryString(); String url = req.getServletPath(); if(param!=null){ url = url+"?"+param; } if(requestURI.contains("js") || requestURI.contains("css") || requestURI.contains("images")){ //不过滤css,js,images等静态资源 chain.doFilter(request, response); }else if(requestURI.contains("/info/")||requestURI.contains("/gys/")){ //过滤前台访问页面,跟前台个人中心(供应商后台),自动登录一次,登录不成功不进行操作,个人中心登录不成功,则跳到登录页面 ProviderInfo providerInfo = (ProviderInfo) session.getAttribute("providerInfo_gys"); String IsAutomaticLogin = (String) session.getAttribute("IsAutomaticLogin");//是否已经走过自动登录流程标识 if(requestURI.contains("/info/") && !requestURI.contains("/login")){ //访问门户等不需要必须登录的(登录除外),只尝试登录一次,如果不成功,不进行操作 if(providerInfo==null && IsAutomaticLogin == null){ req.getSession().setAttribute("goURL", url); res.sendRedirect(req.getContextPath() + "/common/automaticLogin"); }else if(providerInfo==null && IsAutomaticLogin != null ){ chain.doFilter(request, response); }else{ chain.doFilter(request, response); } }else if(requestURI.contains("/gys/")){//访问个人中心,自登陆一次,不成功跳转到登录页面 if(providerInfo==null && IsAutomaticLogin == null){ req.getSession().setAttribute("goURL", url); res.sendRedirect(req.getContextPath() + "/common/automaticLogin"); }else if(providerInfo==null && IsAutomaticLogin != null ){ session.setAttribute("redirectUrl", url); res.sendRedirect(req.getContextPath() + "/login.jsp?redirectUrl="+url); }else{ chain.doFilter(request, response); } }else{ chain.doFilter(request, response); } }else{ //不过滤 chain.doFilter(request, response); } } @Override public void init(FilterConfig arg0) throws ServletException { } }
从代码中可知,需要一个是否已经自动登录过的标识(IsAutomaticLogin),该标识是在走自动登录时(不管成不成功)保存起来的
3.整体代码展示
@Controller @RequestMapping("/common") public class CommonController{ /** * 自动登录方法 * @param request * @param response * @param username * @param pwd * @param ProviderInfo 供应商账户信息model * @return */ @RequestMapping("/automaticLogin") public String automaticLogin(HttpServletRequest request,ServletResponse response,@CookieValue(value = "username", required = false) String username,@CookieValue(value = "pwd", required = false) String pwd,ProviderInfo ProviderInfo) { // 保存需求登录前的链接 String goURL = (String) session.getAttribute("goURL"); if (username == null) {//cookies中没有用户名,肯定不需要自动登录 session.setAttribute("IsAutomaticLogin", "0"); return "redirect:" + goURL; } else { try { username = URLDecoder.decode(username, "UTF-8");//转义,防止中文 } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } // cookie失效 session一定为空,因为登录时,一定会把用户名保存在cookie中 if ("".equals(username) || username == null) {// 使用session登录不了,不进行任何操作,不在进入这个方法 session.setAttribute("IsAutomaticLogin", "0"); return "redirect:" + goURL; } else { // cookie中没有密码,判断session为不为空,如果为空,说明没有登录,如果不为空,说明,用户是选择不记住密码登录(所以cookie中没有密码) if ("".equals(pwd) || pwd == null) { ProviderInfo customer1 = (ProviderInfo) session.getAttribute("providerInfo_gys"); if (customer1 == null) {// 使用session登录不了,不进行任何操作,不在进入这个方法 session.setAttribute("IsAutomaticLogin", "0"); return "redirect:" + goURL; } else { // 已经登录,不再进入这个方法 return "redirect:" + goURL; } } else { // cookie中有密码,判断session为不为空,如果为空,说明没有登录,如果不为空,说明已经登录 ProviderInfo customer1 = (ProviderInfo) session.getAttribute("providerInfo_gys"); if (customer1 == null) {// 当前没有登录,调用cookies中的用户名跟密码进行登录 // 进行自动登录操作,登录成功后返回原来页面 ProviderInfo customer3 = ValidateDate(username); customer3.setPwd(pwd); customer3.setAccountType(6); ProviderInfo customer2 = infoService.login(customer3);//调用登录方法 if (customer2 == null) {// 自动登录失败,不再进入这个方法 session.setAttribute("IsAutomaticLogin", "0"); return "redirect:" + goURL; } else { // 登陆成功保存客户信息到session session.setAttribute("providerInfo_gys",customer2); return "redirect:" + goURL; } } else { return "redirect:" + goURL; } } } } /** * 用户登陆 * @param request * @param response * @param cus * @return */ @RequestMapping("/UserLogin") @ResponseBody public Map<String, Object> goLogin(HttpServletRequest request,HttpServletResponse response,@ModelAttribute("ProviderInfo") ProviderInfo cus) { /*省略一些逻辑判断*/ cus.setPwd(MD5Util.MD5(Pwd)); ProviderInfo providerInfo = infoService.login(cus); Map<String, Cookie> cookieMap = new HashMap<String, Cookie>(); if (providerInfo == null) { // 登陆失败,重新跳转到登陆页面 map.put("error", "密码错误"); return map; }else{ String newUserName = null; if (remember_me.equals("1")) {// 有选择一个月免登录 try { newUserName = URLEncoder.encode(username, "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } Cookie nameCookie = new Cookie("username", newUserName); String pwdMd5Cook = MD5Util.MD5(Pwd); Cookie pwdCookie = new Cookie("pwd", pwdMd5Cook);// 保存加密后的密码+"create" nameCookie.setMaxAge(60 * 60 * 24 * 365);// 用户名保存一年 pwdCookie.setMaxAge(60 * 60 * 24 * 30);// 密码保存30天 // 发送Cookie信息到浏览器 response.addCookie(nameCookie); response.addCookie(pwdCookie); session.setAttribute("IsAutomaticLogin",null); }else{//没有选择,删除上次可能已经选择自动登录时的密码 Cookie[] cookies = request.getCookies(); if (null != cookies) { for (Cookie cookie : cookies) { cookieMap.put(cookie.getName(), cookie); } } if (cookies != null) { for (int i = 0; i < cookies.length; i++) { if (cookieMap.containsKey("pwd")) { Cookie cookie = new Cookie("pwd", null); cookie.setMaxAge(0);// 删除密码cookie response.addCookie(cookie); } } } } // 登陆成功,保存当前user信息,保存客户信息到session map.put("ProviderInfo", providerInfo); map.put("goURL", session.getAttribute("goURL")); session.setAttribute("providerInfo_gys", providerInfo); return map; }else { map.put("error", "该供应商账号不存在"); return map; } } /** * 注销 * @return */ @RequestMapping("/logout") public String logout(HttpServletResponse response) { Map<String, Cookie> cookieMap = new HashMap<String, Cookie>(); Cookie[] cookies = request.getCookies(); if (null != cookies) { for (Cookie cookie : cookies) { cookieMap.put(cookie.getName(), cookie); } } if (cookies != null) { for (int i = 0; i < cookies.length; i++) { if (cookieMap.containsKey("pwd")) { Cookie cookie = new Cookie("pwd", null); cookie.setMaxAge(0);// 删除密码cookie response.addCookie(cookie); } } } session.setAttribute("providerInfo_gys", null); return "/index"; } }
到处,该功能示例讲解全部完成,如有不对的地方,欢迎大家在评论区指出。
相关推荐
毕业设计基于JavaWeb实现的一个备忘录系统项目源码。难度适中,新手自己可操作 备忘录 介绍 后端部分基于Servlet、Jdbc实现. 前端部分基于Layui、jqury实现。 一个简单的前后端分离Demo,前后端交互JSON数据格式 ...
1. 使用DOM解析器:一次性加载整个XML文档到内存,适合小规模数据处理。 2. 使用SAX解析器:事件驱动的方式,逐行读取XML,适合处理大型文件,节省内存。 3. XSLT(Extensible Stylesheet Language Transformations...
在Android平台上,开发一个备忘录应用程序涉及到多个关键知识点,这些知识点构成了Android应用的基础结构以及特定功能的实现。以下是对"android备忘录实现"这一主题的详细解析: 1. **Android开发环境**:首先,`....
这个“用android studio写的一个备忘录”项目,显然是一款基于Android Studio构建的备忘录应用,旨在帮助用户记录日常生活或工作中的重要事项。下面将详细介绍Android Studio、Android开发以及备忘录应用的相关知识...
开发人员需要设计和实现一个自定义的日历控件,用户可以通过该控件查看日期、添加、编辑和删除备忘录。日历控件通常会包含月份切换、日期选择、事件标记等功能,确保用户能直观地查看和管理日程。 四、数据库设计与...
【标题】"一个简单的备忘录APP,鸿蒙平台.zip" 涵盖了华为鸿蒙系统(HarmonyOS)的开发实践,旨在为开发者提供一个基础的备忘录应用程序的构建过程。这个项目名为“todo_harmonyOS-master”,显然是一个基于鸿蒙操作...
本篇将详细讲解如何使用Tkinter来实现一个简单的备忘录应用,涵盖增、删、改、查的基本功能。 首先,我们需要导入Tkinter库,并初始化窗口。在Python中,可以这样引入Tkinter库: ```python import tkinter as tk ...
【标题】"基于thinkphp的一个通讯备忘录" 指的是使用了ThinkPHP框架开发的一款用于记录和管理通信信息的系统。ThinkPHP是中国国内较为流行的一个开源PHP框架,它提供了一套完整的MVC(Model-View-Controller)模式,...
备忘录模式是一种行为设计模式,它允许在不破坏封装性的前提下,捕获和恢复一个对象的内部状态。在C++中实现备忘录模式,可以有效地帮助开发者在程序运行过程中保存对象的状态,以便在需要时恢复到之前的状态,这...
在安卓移动开发领域,创建一个备忘录应用是一项常见的任务,它可以帮助用户随时随地记录生活中的点滴。本项目名为“Mymemo”,显然是一款专为安卓设备设计的个人备忘录应用。下面将详细探讨这个项目可能涉及的关键...
在Android平台上开发一款备忘录应用,涉及到许多关键的技术点和功能实现,下面将详细讲解这些知识点。 首先,**Android应用程序框架**是整个项目的基础。Android SDK提供了丰富的API和工具,用于构建移动设备上的...
本文将深入探讨如何基于Android平台开发一个备忘录应用,通过分析“Android 备忘录源码.rar”中的代码,我们可以学习到以下几个关键知识点: 1. **用户界面设计**:从项目中包含的图片资源(如1_120916130147_1.png...
微信小程序实现的简易备忘录,可以记录代办事项,可以标记事项是否完成 微信小程序实现的简易备忘录,可以记录代办事项,可以标记事项是否完成 微信小程序实现的简易备忘录,可以记录代办事项,可以标记事项是否完成...
微信小程序 备忘录 (源码)微信小程序 备忘录 (源码)微信小程序 备忘录 (源码)微信小程序 备忘录 (源码)微信小程序 备忘录 (源码)微信小程序 备忘录 (源码)微信小程序 备忘录 (源码)微信小程序 备忘录 (源码)微信小...
微信小程序源码 备忘录(学习版)微信小程序源码 备忘录(学习版)微信小程序源码 备忘录(学习版)微信小程序源码 备忘录(学习版)微信小程序源码 备忘录(学习版)微信小程序源码 备忘录(学习版)微信小程序源码 备忘录(学习...
本篇将详细解析一个基于Android的备忘录应用源码,以便理解其核心功能和实现机制。 1. **项目结构分析** 备忘录应用的源码通常包含多个模块,如`app`(主应用程序)、`data`(数据处理)、`ui`(用户界面)等。`...
设计和实现一个类似个人备忘录的 Android APP ,数据库采用 SQLite (也可以直接访问 Web 端 MySQL 数据库、或提供 Web 接口访问 MySQL 数据库)。 1.用户注册和登录(这类 APP 一般面对个人,用户不需要分类别); ...
在Android平台上,开发一款备忘录程序是一项常见的实践任务,对于初学者来说,这是一个极好的起点,可以帮助他们理解和掌握Android应用的基本构建块。本项目主要涉及Android应用开发的基础知识,包括用户界面设计、...
基于C++的网页版备忘录系统源码+项目说明.zip基于C++的网页版备忘录系统源码+项目说明.zip基于C++的网页版备忘录系统源码+项目说明.zip基于C++的网页版备忘录系统源码+项目说明.zip基于C++的网页版备忘录系统源码+...
在IT行业中,尤其是在移动应用开发领域,创建一个具备闹钟功能的备忘录应用程序是非常常见的需求。本项目名为“备忘录(闹钟)”,它是一个Android应用,旨在帮助用户设置提醒,确保他们不会错过任何重要的事件或...