会话的特点:
多次请求,多次交互,直到关闭浏览器
解决的问题:每个客户端保存自己的数据
SevletContext,request和会话技术的区别:
ServletContext的作用域是整个应用,不能区分浏览器。
request作为域对象,其值只能在一次请求中有效。有局限性,例如实现购买商品并且结账的功能中,要求必须买一个商品就结账。
保存会话数据的两种技术。
Cookie
Cookie是客户端技术,程序把每个用户的数据以cookie的形式写给用户各自的浏览器。当用户使用浏览器再去访问服务器中的web资源的时候,就会带着各自的数据。注意:第一次访问时候没有Cookie数据。
HttpSession
Session是服务器端技术,服务器为每一个用户创建一个独享的HttpSession对象。
Cookie API
response接口定义了一个addCookie方法,用于在其响应头中增加一个Set-Cookie头字段。Cookie只能存字符串。
reque法st接口定义了一个getCookies方法,用于提取客户端提交的Cookie。
一个Cookie只能标识一种信息。它至少含有一个标识该信息的名称和设置值。
一个web站点可以给一个浏览器发送多个Cookie,一个web浏览器也可以存储多个web站点提供的Cookie
如果创建一个Cookie,并将他发送到游览器中,默认情况是一个会话级别的cookie,即存储在浏览器的内存中。用户退出浏览器后即被删除。
如果希望浏览器将该cookie存储在磁盘上,则需要命令maxAge,并且给出一个秒的时间。将最大时间设置为0表示立即删除该cookie.
Cookie的属性
name:名称不能唯一确定一个Cookie。路径可能不同
value:不能存中文
path:默认值是写Cookie的那个程序的访问路径。
例如:http://localhost:8080/day10_00_cookie/servlet/ck1的写的路径
path就是/day10_00_cookie/servlet/ 看当前创建cookie的资源文件路径。
客户端在访问服务器的时候,根据访问路径来决定是否带着cookie到服务器,当前访问的路径如果是cookie的path开头的路径,浏览器就带,否则不带。
服务器端的路径”/”表示的是当前应用路径。
- 显示最后依次登录的代码
public class CookieDemo1 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
//获取客户端保存的最后访问时间
Cookie[] cookies = request.getCookies();//获取客户端的所有Cookie对象
for (int i = 0;cookies!=null && i < cookies.length; i++) {
if("lastAccessTime".equals(cookies[i].getName())){//判断当前Cookie中的name是否是想要的cookie
long l = Long.parseLong(cookies[i].getValue());//如果是想要的Cookie,则把Cookie中的value取出
out.write("你的最后访问时间为:"+new Date(l).toLocaleString());//yyyy-MM-dd
}
}
out.print("<a href='"+request.getContextPath()+"/servlet/clear'>clear</a>");
//创建cookie,
Cookie ck = new Cookie("lastAccessTime",System.currentTimeMillis()+"");
//设置cookie的有效时间,单位是秒
ck.setMaxAge(60*5);//保存时间为5分钟
//设置cookie的path
//ck.setPath("/day10_00_cookie");
//ck.setPath(request.getContextPath());// /day10_00_cookie
ck.setPath("/");// /day10_00_cookie
//把cookie信息写回到客户端
response.addCookie(ck);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
//时间的清除
public class ClearServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//创建一个Cookie对象
Cookie ck = new Cookie("lastAccessTime", "");
ck.setPath("/");//要设置被删除Cookie的path,否则可能会删错对象
ck.setMaxAge(0);//相当于删除
response.addCookie(ck);//将ck写回客户端缓存
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
- 新打开的一个浏览器能否访问之前浏览器的cookie?
取决于是否将cookie存放在磁盘中,且二者path路径是否一致 - 登录记住用户名的代码实现
public class DoLoginServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
//获取表单数据
String userName = request.getParameter("userName");
String pwd = request.getParameter("pwd");
String remember = request.getParameter("remember");
Cookie ck = new Cookie("userName", userName);
ck.setPath("/");
//处理业务逻辑
//分发转向
if("tom".equals(userName)&&"123".equals(pwd)){
if(remember!=null){
ck.setMaxAge(Integer.MAX_VALUE);//设置Cookie的有效保存时间
}else{
ck.setMaxAge(0);//删除 Cookie
}
response.addCookie(ck);//将Cookie写回到客户端
out.write("登录成功!");
}else{
out.write("登录失败!");
//设置2秒跳到重新登录
response.setHeader("refresh", "2;url="+request.getContextPath()+"/servlet/login");
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
public class LoginServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
String userName ="";
String checked = "";
//得到客户端保存的Cookie数据
Cookie[] cookies = request.getCookies();
for (int i = 0;cookies!=null && i < cookies.length; i++) {
if("userName".equals(cookies[i].getName())){
userName = cookies[i].getValue();
checked = "checked='checked'";
}
}
out.write("<form action='"+request.getContextPath()+"/servlet/doLogin' method='post'>");
out.write("用户名:<input type='text' name='userName' value='"+userName+"'/><br/>");
out.write("密码:<input type='password' name='pwd'/><br/>");
out.write("<input type='checkbox' name='remember' "+checked+" />记住用户名<br/>");
out.write("<input type='submit' value='登录'/><br/>");
out.write("</form>");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
Cookie历史记录的实现
Session
session和ContentTest的区别:
Session只能有一个用户,ContentTest可以有多个用户.
session是依赖于Cookie存在的,每一个浏览器都有一个SessoinID,被服务器创建并且存在Cookie中。Session的默认存活时间是30分钟(无操作状态下 )
HttpSession和Cookie的区别
HttpSession是一个域对象
cookie是客户端技术,只能存储字符串,HttpSession是服务端技术,可以存储对象。常见的API
void setAttribute(String name, Object value)
Oblect getAttribute(Strinf name)
void removeAttribute(String name);
HttpSession getId();
setMaxInactiveInterval(int interval);设置session的存在时间
invalidate()此对话无- getSession的方法执行原理
1.获取名称为JSESSIONID的cookie的值
2.没有这样的cookie,创建一个新的HttpSession对象,分配一个唯一的SessionID,并且向客户端写入一个名为JSESSIONID=sessionID的cookie.’
3.有这样的Cookie,获取cookie的值,从服务器的内存中根据ID找到那个HttpSession对象。
找到了,继续取出服务,找不到从2开始。 生命周期
创建:浏览器第一次访问服务器的动态资源
存活时间:默认30分钟(电脑处在无操作状态)
死亡:超时
设置有效时间:在web.xml中加入以下:<session-config> <session_timeout>1</session-timeout> </session-config> 表示1分钟
客户端禁用Cookie后的回话问题
解决方案:
在主页上给出提示,不要禁用
重写全部的URL:语法:response.encodeURL(String url)
request.getSession必须写
代码
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.itheima.entity.Book;
import com.itheima.util.DBUtil;
public class AddCart extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
//根据id得到书
String id = request.getParameter("id");
Book book = DBUtil.findBookById(id);
//得到session对象
HttpSession session = request.getSession();
//从session中取出list(购物车)
List<Book> list = (List<Book>)session.getAttribute("cart");
if(list==null){
list = new ArrayList<Book>();
}
list.add(book);
session.setAttribute("cart", list);//把list放回到session域中
out.print("购买成功!");
String url = request.getContextPath()+"/servlet/showAllBooksServlet";
response.setHeader("refresh", "2;url="+response.encodeURL(url));
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.itheima.entity.Book;
import com.itheima.util.DBUtil;
public class ShowAllBooksServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
request.getSession();
out.print("本网站有以下好书:<br/>");
Map<String, Book> books = DBUtil.findAllBooks();
for (Map.Entry<String, Book> book : books.entrySet()) {
String url = request.getContextPath()+"/AddCart?id="+book.getKey();
out.print("<a href='"+response.encodeURL(url)+"' >"+book.getValue().getName()+"</a><br/>");
}
String url2 = request.getContextPath()+"/servlet/showCart";
out.print("<a href='"+response.encodeURL(url2)+"'>查看购物车</a>");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.itheima.entity.Book;
public class ShowCart extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.print("购物车有以下商品:<br/>");
HttpSession session = request.getSession();
//得到session对象
List<Book> books = (List<Book>)session.getAttribute("cart");
if(books==null){
out.print("你还什么都没买呢");
response.setHeader("refresh", "2;url="+request.getContextPath()+"/servlet/showAllBooksServlet");
//response.sendRedirect(request.getContextPath()+"/servlet/showAllBooksServlet");
return;
}
for (Book book : books) {
out.write(book.getName()+"<br/>");
}
//session.setMaxInactiveInterval(10);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
public class Book implements Serializable{
private String id;
private String name;
private double price;
private String author;
public Book(String id, String name, double price, String author) {
super();
this.id = id;
this.name = name;
this.price = price;
this.author = author;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
@Override
public String toString() {
return "Book [id=" + id + ", name=" + name + ", price=" + price
+ ", author=" + author + "]";
}
}
public class DBUtil {
private static Map<String, Book> books = new HashMap<String, Book>();
static{
books.put("1", new Book("1", "金瓶梅", 20, "王瑞鑫"));
books.put("2", new Book("2", "葵花宝典", 20, "杨成毅"));
books.put("3", new Book("3", "九阴真经", 30, "陈光"));
books.put("4", new Book("4", "玉女心经", 10, "陈志家"));
}
//得到所有书
public static Map<String, Book> findAllBooks(){
return books;
}
/**
* 根据id查找指定的书
* @param id
* @return
*/
public static Book findBookById(String id){
return books.get(id);
}
}
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.dsna.util.images.ValidateCode;
public class CodeServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
ValidateCode vc = new ValidateCode(110, 25, 4, 9);
//向session中保存验证码
request.getSession().setAttribute("scode", vc.getCode());
vc.write(response.getOutputStream());
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
public class DoLogin extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
//获取表单数据
String userName = request.getParameter("userName");
String pwd = request.getParameter("pwd");
String code = request.getParameter("code");
//从session中获取验证码
String scode = (String) request.getSession().getAttribute("scode");
//处理业务逻辑
if("tom".equals(userName)&&"123".equals(pwd)){
//分发转向
if(!code.equalsIgnoreCase(scode)){
request.setAttribute("msg", "验证码错误");
request.getRequestDispatcher("/index.jsp").forward(request, response);
}
out.print("登录成功!");
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
public class SessionDemo1 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String name = request.getParameter("name");
if(name!=null){
name = new String(name.getBytes("iso-8859-1"),"UTF-8");
}
//得到一个HttpSession对象
HttpSession session = request.getSession();
session.setAttribute("name", name);
response.getWriter().write(session.getId());
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
public class SessionDemo2 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
//得到一个HttpSession对象
HttpSession session = request.getSession();
String name = (String) session.getAttribute("name");
if(name!=null){
out.print(name);
}else{
out.print("你不能直接访问此资源!");
}
out.print(session.getId());
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}