Session案例
用户登入案例:
按一般的网站登入实例,用户在页面登入页输入账号、密码,验证通过后,在首页显示其“欢迎回来,xxx”.
首先完成登入页login.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>用户登入</title> </head> <body> <form action="/CookieSession/LoginServlet" method="post"> <p>账号:<input type="text" name="userName"/></p> <p>密码:<input type="password" name="password"/></p> <p><input type="submit" value="登入"/> </form> </body> </html>
然后再是登入失败的页面,加上失败后返回首页的链接
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>登入失败</title> </head> <body> <p>登入失败了,返回<a href="/CookieSession/login.html">登入</a> </body> </html>
接下来就是完成servlet了,首先写一个LoginServlet来验证其正确性,同时若是正确,我们让其跳转到另外的一个indexservlet页面,同时在浏览器显示登入成功的页面,如下
package com.gqx.SessionDemo; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class LoginServlet extends HttpServlet { /** * 处理登录的逻辑 */ private static final long serialVersionUID = 1L; public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); String name=request.getParameter("userName"); String password=request.getParameter("password"); if (name.equals("gqxing") && password.equals("123456")) { //登入成功 /* * context域对象:不合适,可能会覆盖数据。 * 首先假设用上request域对象,来实现页面的跳转页面数据的共享 */ request.setAttribute("userName", name); //添加保存共享的数据 request.getRequestDispatcher("/IndexServlet").forward(request, response); //请求的转发 }else { //登入失败,重定向跳回原页面 response.sendRedirect(request.getContextPath()+"/fail.html"); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); } }
在再次就是登入成功的目标servlet
package com.gqx.SessionDemo; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class IndexServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); PrintWriter write=response.getWriter(); //获取属性 String name=(String) request.getAttribute("userName"); String html="<html><body>欢迎回来,"+name+"</body></html>"; write.write(html); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); } }
这个时候我们可以看到登入的效果如图
这就是因为request域对象在这里要实现数据的共享,就要用到请求的转发,request对象和起初的那个loginServlet相关,一旦脱离,域对象里就没有数据了为null,这就要求我们这个网站全部都用到转发技术处理,显然这样是不切实际的。
于是我们就换另一域对象——session来做实验,如下:
package com.gqx.SessionDemo; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; public class LoginServlet extends HttpServlet { /** * 处理登录的逻辑 */ private static final long serialVersionUID = 1L; public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); String name=request.getParameter("userName"); String password=request.getParameter("password"); if (name.equals("gqxing") && password.equals("123456")) { //登入成功 /* * context域对象:不合适,可能会覆盖数据。 * 首先假设用上request域对象,来实现页面的跳转页面数据的共享 */ // request.setAttribute("userName", name); //添加保存共享的数据 // request.getRequestDispatcher("/IndexServlet").forward(request, response); //请求的转发 HttpSession session=request.getSession(); session.setAttribute("userName", name); //这个时候可以用到重定向技术 System.out.println("验证成功"); response.sendRedirect(request.getContextPath()+"/IndexServlet"); }else { //登入失败,重定向跳回原页面 response.sendRedirect(request.getContextPath()+"/fail.html"); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); } }
package com.gqx.SessionDemo; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; public class IndexServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); PrintWriter write=response.getWriter(); //获取属性 // String name=(String) request.getAttribute("userName"); //获取session对象对象 HttpSession session=request.getSession(false); if (session==null) { //没有登入成功(第一次访问本页面,或是没有对应的JSESSIONID,),跳到登入页面去 response.sendRedirect(request.getContextPath()+"/login.html"); return ; } //取出会话数据 String name=(String) session.getAttribute("userName"); if (name==null) { //当用户注销的时候,并没有将session删除,只删除了name(有可能其他必要的信息保存在了session中,故不可直接删除), //这个时候,还需要在返回登入页验证 response.sendRedirect(request.getContextPath()+"/login.html"); return; } String html="<html><body>欢迎回来,"+name+"</body></html>"; write.write(html); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); } }
这个时候就没有我们前面遇到的问题了,
我们可以在加一个功能,当用户想退出的时候,我们就需要另外设计注销的功能了,我们不能再用session销毁方法了,
session.invalidate(); //手动销毁
因为,我们在服务器端保存的session对象中有时候不仅仅包含着我们的名字信息,有可能还有其他方面的信息,需要在下次登入的时候读取,我们可以采用移除属性的方法
此时我们可以在indexServlet中添加一个安全退出连接
String html="<html><body>欢迎回来,"+name+",<a href="+request.getContextPath()+"/LogoutServlet>注销登入</a></body></html>";
在去添加一个LogoutServlet
package com.gqx.SessionDemo; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; public class LogoutServlet extends HttpServlet { /** * 移除名字属性,退出逻辑 * 删除掉session对象中指定的userName属性即可! */ private static final long serialVersionUID = 1L; public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { HttpSession session=request.getSession(false); //、删除session属性 if (session!=null) { session.removeAttribute("userName"); } //回到登入页面来 response.sendRedirect(request.getContextPath()+"/login.html"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); } }
效果如图
很希望自己是一棵树,守静、向光、安然,敏感的神经末梢,触着流云和微风,窃窃的欢喜。脚下踩着最卑贱的泥,很踏实。还有,每一天都在隐秘成长。