response.addCookie(c);
案例:上次访问网站的时间:
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); Cookie [] cs = request.getCookies(); Cookie findC = null; if(cs!=null){ for(Cookie c : cs){ if("lastTime".equals(c.getName())){ findC = c; } } } if(findC == null){ response.getWriter().write("您是第一次访问本网站!"); }else{ Long lastTime = Long.parseLong(findC.getValue()); response.getWriter().write("您上次访问时间是:"+new Date(lastTime).toLocaleString()); } Date date = new Date(); Cookie c = new Cookie("lastTime",date.getTime()+""); c.setMaxAge(3600*24*30); c.setPath(request.getContextPath()); //c.setDomain(".baidu.com"); response.addCookie(c); }
当程序第一次调用到request.getSession()方法时说明客户端明确的需要用到session此时创建出对应客户端的Session对象.
当session超过30分钟(这个时间是可以在web.xml文件中进行修改的)没有人使用则认为session超时销毁这个session.*如果服务器是正常关闭,还未超时的session会被以文件的形式保存在服务器的work目录下,这个过程叫做session的钝化.下次再正常启动服务器时,钝化着的session会被恢复到内存中,这个过程叫做session的活化.
得到Session,没有就创建://检查一下当前浏览器有没有session,有就直接来来用,没有就创建一个session
HttpSession session = request.getSession();
我们可以手动的发送JSESSIONID cookie,名字和path设置的和自动发送时一样,但是设置一下MaxAge,使浏览器除了在内存中保存JSESSIONID信息以外还在临时文件夹中以文件的形式保存,这样即使重开浏览器仍然可以使用之前的session
利用原理:实现在用户关闭浏览器后,借助于Cookie技术,重写原来一模一样的Session来实现登陆浏览器后仍然能够看到以前的信息:
//下面这行代码利用session原理,实现在关闭浏览器后再次登录仍然有用户信息。 //实际上是在session之前将sessionID写回到客户端,在临时文件夹中保存 HttpSession session = request.getSession(); Cookie jc = new Cookie("JSESSIONID",session.getId()); //之前设置了setMaxAge,这次是从浏览器的临时文件中取sessionID jc.setPath(request.getContextPath()); jc.setMaxAge(1800); response.addCookie(jc); session.setAttribute("prod", prod);
*url重写的方法一旦发现浏览器带回了任意cookie信息,则认为客户端没有禁用cookie,就不会再进行重写操作
经典实例:对于URL重写技术主要解决了用户禁用了Cookie,我们让用户在关闭浏览器之后重新打开浏览器时仍然能够显示用户信息的功能,但是实际生活中用的不多,像淘宝网站,超链接是亿级以上的,不可能用URL重写来解决问题的。
<% request.getSession(); String url1 = request.getContextPath()+"/servlet/BuyServlet?prod=电视机"; url1 = response.encodeURL(url1); String url2 = request.getContextPath()+"/servlet/BuyServlet?prod=冰箱"; url2 = response.encodeURL(url2); String url3 = request.getContextPath()+"/servlet/PayServlet"; url3 = response.encodeURL(url3); %> <a href="<%= url1 %>">电视机</a> <a href="<%= url2 %>">冰箱</a> <a href="<%= url3 %>">结账</a>
!!用户登录注销
登陆界面:login.jsp
<pre name="code" class="java"> <h1>我的网站-登录</h1><hr> <form action="${pageContext.request.contextPath }/servlet/LoginServlet" method="POST"> 用户名:<input type="text" name="username"/> 密码:<input type="password" name="password"/> <input type="submit" value="登录"/> </form>
在LoginServlet中,检查用户名是否正确,如果正确就导向主页,如果不正确给予提示用户名或密码不正确:
request.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); //1.获取用户名密码 String username = request.getParameter("username"); String password = request.getParameter("password"); //2.查询数据库检查用户名密码 if(UserDao.valiNamePsw(username, password)){ //3.如果正确登录后重定向到主页 request.getSession().setAttribute("user", username); response.sendRedirect(request.getContextPath()+"/loginout/index.jsp"); return; }else{ //4.如果错误提示 response.getWriter().write("用户名密码不正确!"); }
在主页index.jsp界面:显示用户的登陆状态,然后若已经登陆提示欢迎回来用户可以注销
<h1>我的网站</h1><hr> <% //获取session中的登录状态 String user = (String)session.getAttribute("user"); %> <% if(user == null || "".equals(user)){//用户没有登录 %> 欢迎光临!游客! <a href="${pageContext.request.contextPath }/loginout/login.jsp">登录</a> <a href="#">注册</a> <% }else{//用户登录过 %> 欢迎回来!<%=user %>! <a href="${pageContext.request.contextPath }/servlet/LogoutServlet">注销</a> <% } %>
//1.杀死session if(request.getSession(false)!=null && request.getSession().getAttribute("user")!=null){ request.getSession().invalidate(); } //2.重定向到主页 response.sendRedirect(request.getContextPath()+"/loginout/index.jsp");
UserDAO
public class UserDao { private UserDao() { } private static Map <String,String>map = new HashMap<String, String>(); static{ map.put("张三丰", "111"); map.put("张翠山", "999"); map.put("张无忌", "888"); map.put("赵敏", "777"); } public static boolean valiNamePsw(String username,String password){ return map.containsKey(username) && map.get(username).equals(password); } }
防止表单重复提交:两种方法,第一种是前台js校验第二种前台传入一个随机数random并放到Session,第一次登陆后,后台将Session中的random移出,当再次登陆后,Session中的random已经为空了,不执行再次登陆注册的业务逻辑。
login.jsp
<script type="text/javascript"> var isNotSub = true; function canSub(){ if(isNotSub){ isNotSub = false; return true; }else{ alert("请不要重复提交!!!"); return false; } } </script> </head> <body> <% Random r = new Random(); int valinum = r.nextInt(); session.setAttribute("valinum",valinum+""); %> <form action="${pageContext.request.contextPath }/servlet/ResubServlet" method="POST" onsubmit="return canSub()"> 用户名:<input type="text" name="username"/> <input type="hidden" name="valinum" value="<%=valinum %>"/> <input type="submit" value="注册"/> </form> </body>
后台Servlet代码:
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); try { Thread.sleep(4*1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } String username = request.getParameter("username"); String valinum = request.getParameter("valinum"); String valinum2 = (String) request.getSession().getAttribute("valinum"); if(valinum2!=null && !"".equals(valinum2) && valinum.equals(valinum2)){ request.getSession().removeAttribute("valinum"); System.out.println("向数据库中注册一次:"+username); }else{ response.getWriter().write("from web:不要重复提交!!"); } }