思路

使用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对象来获取

就是把当前项目的根目录(绝对路径)、参数中的路径拼接在一起。

最新文章

  1. bash获取properties文件资源
  2. ios每日一发--Leanclude数据云存储以及登录 注册账户
  3. node.js中log4js的使用
  4. Windows7 IIS7.5 HTTP Error 503 The service is unavailable 另类解决方案
  5. Todolist
  6. Mysql join语句解析
  7. [java面试题]最长的回文字符串中出现确定
  8. 线上问题debug过程(cat,grep,tr,awk,sort,uniq,comm等工具的综合使用)
  9. 设计模式 --&gt; (1)工厂模式
  10. 有货前端 Web-APM 实践
  11. django rest-framework 1.序列化 一
  12. SpringBoot使用Graylog日志收集
  13. 关于CPU 架构与指令集的一些个人理解
  14. day07----字符编码解码、文件操作(1)
  15. Django ORM操作的几个细节
  16. L322
  17. Linux 源代码在线(http://lxr.linux.no/linux/)。
  18. Mac在Finder中显示/usr、/tmp、/var等隐藏目录
  19. [小技巧]Mac上chrome打开触控板双指前进后退功能
  20. VS2010/MFC编程入门之二十五(常用控件:组合框控件Combo Box)

热门文章

  1. 题解:[ZJOI2014]璀灿光华
  2. Vue之挂载点、变量、事件、js对象、文本指令、过滤器、事件指令和属性指令
  3. 微信小程序 - Request | 路由跳转 | 本地存储
  4. 微信小程序音频背景播放
  5. 7.27 NOIP模拟测试9 随 (rand)+单(single)+题(problem)
  6. Linux性能优化实战学习笔记:第五十六讲
  7. [LeetCode] 139. Word Break 拆分词句
  8. JavaScript (JS)常用方法
  9. Salesforce 开发整理(七)配置审批流
  10. asp.net mvc移除X-AspNet-Version、X-AspNetMvc-Version、Server