【Servlet02】请求转发与重定向、cookie、session (获取登录时间、商品浏览记录,丑陋简单购物车)
请求转发和重定向(面试考点)
重定向
- 早期写法
response.setStatus() - 重定向写法
response.sendRedirect(“跳转页面”); - 1、地址为资源路径地址
- 响应码302
- 2、两次请求,第一次请求后返回302和一个地址,浏览器根据这个地址进行第二次访问。
- 3、任意都可以跳转
- 4、效率稍微低一些,进行两次请求
- 5、后续请求没法用上一次的request的数据,或没办法用之前的对象
- 买可乐商店没有,去别的地方买
请求转发
- request.getRequestDispatcher(“跳转页面”).forward(request,response)
- 1、地址栏地址不变
- 响应码200
- 2、只有一次请求,服务端帮客户端做完了后面的工作
- 3、只能跳到自己项目下的
- 4、效率稍微高一些,只执行一次请求
- 5、可以用上一次的request对象
- 买可乐商店没有,老板帮忙买一个过来
cookie
- 小饼干,一份小数据,服务器给客户端存在客户端的一份数据
- 应用场景:自动登录,浏览记录,购物车
- 使用原因:http协议无状态,为了更好的用户体验和收集用户习惯
- 可以创建多个cookie
- 会话cookie
- 持久cookie
创建使用cookie
Cookie cookie = new Cookie("aa", "bb");
//给响应添加一个小饼干
response.addCookie(cookie);
- 在相应头中就会多出一个set-cookie的keyvalue值
获取客户端带来的cookie
Cookie[] cookies = request.getCookies();
if(cookies != null){
for(Cookie c : cookies){
String key = c.getName();
String value = c.getValue();
System.out.println(key+"+++"+value);
}
}
cookie的有效期
- 默认关闭浏览器后就消失
- 要写在addcookie前
//expiry:单位是秒
//正值:在这个数字过后cookie失效
//负值:关闭浏览器就失效默认为-1
cookie.setMaxAge(expiry);
cookie重新赋值
//重新赋值
cookie.setValue(xxx);
cookie指定域名
//只有指定域名才会带上cookie
cookie.setDomain(域名);
cookie指定地址
//只有访问域名下的这个路径才会带cookie
cookie.setPath(/路径);
cookie清除
//取到cookie
cookie.setMaxAge(0); // 设置立即删除,并没有delete方法
cookie案例
获取上次访问时间
- 分析:
- 第一次登录:
登录成功或失败给客户端加cookie - 不是第一次登录
登录成功或失败
获取cookie
更新时间(获取现在的时间戳)
if ("aaa".equals(username) && "123".equals(password)) {
Cookie[] cookies = request.getCookies();
Cookie cookie = CookieUtil.findCookie(cookies, "last");
if (cookie != null) {
long value = Long.parseLong(cookie.getValue()); // 把字符串转成long类型
response.getWriter().write("欢迎用户" + username + "上次登录时间:"+new Date(value));
cookie.setValue(System.currentTimeMillis()+"");
} else {
Cookie c = new Cookie("last", System.currentTimeMillis()+"");
c.setMaxAge(10); // 十秒有效时间
response.getWriter().write("欢迎用户" + username+"**********");
response.addCookie(c);
}
} else {
response.getWriter().write("登录失败");
}
获取商品浏览记录
- 新建jsp(java server page)最后会翻译成一个类(servlet)
更改编码方式
和写html一样 - 以符号分隔在浏览过的商品id保存在cookie中
- 动态web——jsp获得cookie
【<%xxx%>java语言 】
【<%=变量名%>输出变量值】
方法参数要啥给啥,对象的话
创建对象的几种手法:
- 直接new
- 单例模式 \ 提供静态方法
- 工厂模式构建 stu StuFactory
cookie的问题
- 保存在客户端有安全问题(可以存加密数据)
- 数据大小有限制4kb
- 为了解决出现了session
session
- 会话,基于cookie的一种会话机制
- 数据存放在服务器端,不存在安全隐患
创建使用session
HttpSession session = request.getSession();
得到会话id
session.getId();
存值,取值,移除值
session.setAttribute(name, value);
session.getAttribute(name);
session.removeAttribute(name);
session何时创建和销毁
- 创建
.getSession()
- 销毁 session是存放在服务器内存中的一份数据,可以持久化(Redis),及时关闭浏览器,session也不会销毁
1、关闭服务器
2、session会话时间过期(默认30分钟)
强制删除会话:session.invalidate();
session案例
简单购物车
- 商品为一个个超链接,每点击就向购物车添加一件商品
//商品jsp页面
<body>
<a href="SessionTest?id=0">111</a><br>
<a href="SessionTest?id=1">222</a><br>
<a href="SessionTest?id=2">666</a><br>
<a href="SessionTest?id=3">哈哈哈</a><br>
</body>
- 点击商品链接后界面,点击继续购物返回商品界面
//servlet
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
String fid = request.getParameter("id");
HttpSession session = request.getSession();
int id = Integer.parseInt(fid);
String[] names = {"111","222","666","哈哈哈"};
String name = names[id];
Map<String,Integer> map = (Map<String, Integer>) session.getAttribute("car");
if(map == null){
map = new LinkedHashMap<String, Integer>();
session.setAttribute("car", map);
}
if(map.containsKey(name)){
map.put(name, map.get(name)+1);
}else{
map.put(name, 1);
}
response.getWriter().write("<a href='shopping.jsp'>继续购物</a></br>");
response.getWriter().write("<a href='take.jsp'>结算</a></br>");
int mapsize = map.size();
response.getWriter().write(" "+mapsize+"**");
}
- 点击结算
//take.jsp结算界面
<body>
商品如下:
<%
Map<String,Integer> map = (Map<String,Integer>)session.getAttribute("car");
if(map != null){
for(String key : map.keySet()){
int value = map.get(key);
%>
<h3>名称:<%=key %>数量:<%=value %></h3>
<%
}
}
%>
</body>
清除购物车的实现
在结算界面添加清除链接,创建一个清除的servlet,在里面获得session
1、删除这个car session.removeAttribute(name);
2、直接强制删除会话 session.invalidate();
jsp页面导包快捷键
- alt + /