session和cookie
会话:用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话。
session和cookie的区别:
Cookie:
Cookie是客户端技术,程序把每个用户的数据以cookie的形式写给用户各自的浏览器。当用户使用浏览器再去访问服务器中的web资源时,就会带着各自的数据去。这样,web资源处理的就是用户各自的数据了。
Session:
Session是服务器端技术,利用这个技术,服务器在运行时可以为每一个用户的浏览器创建一个其独享的session对象,由于session为用户浏览器独享,所以用户在访问服务器的web资源时,可以把各自的数据放在各自的session中,当用户再去访问服务器中的其它web资源时,其它web资源再从用户各自的session中取出数据为用户服务。
java中把Cookie封装成了javax.servlet.http:Cookie类。每个cookie都是Cookie类的对象。
Cookie具有不可跨域名性。
Cookie有效期:Cookie的maxAge决定这Cookie的有效期。getMaxAge()和setMaxAge()读写maxAge属性。maxAge为正,则表示会在maxAge秒之后自动消失。maxAge为负,关闭浏览器窗口即失效。默认maxAge为-1,maxAge为0表示删除该Cookie。
Cookie的修改,删除:删除某个Cookie,只需要新建一个同名的Cookie。并将maxAge设置为0.并添加到response中覆盖原来的Cookie。
Cookie类的方法:
public Cookie(String name,String value)
setValue与getValue方法
setMaxAge与getMaxAge方法
setPath与getPath方法
setDomain与getDomain方法
getName方法
Cookie细节:
1.一个Cookie只能标识一种信息,它至少含有一个标识该信息的名称(NAME)和设置值(VALUE)。
2.一个WEB站点可以给一个WEB浏览器发送多个Cookie,一个WEB浏览器也可以存储多个WEB站点提供的Cookie。
3.浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4KB。
4.如果创建了一个cookie,并将他发送到浏览器,默认情况下它是一个会话级别的cookie(即存储在浏览器的内存中),用户退出浏览器之后即被删除。若希望浏览器将该cookie存储在磁盘上,则需要使用maxAge,并给出一个以秒为单位的时间。将最大时效设为0则是命令浏览器删除该cookie。
5.注意,删除cookie时,path必须一致,否则不会删除
//代表网站首页
public class DemoCookie extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
out.print("您上次访问的时间是:");
//获取用户的时间cookie
Cookie cookies[] = request.getCookies();
for(int i = 0; cookies != null && i < cookies.length; i ++){
//得到cookie存入的时间,是毫秒值,所以是个长整数。
long cookieValue = Long.parseLong(cookies[i].getValue());
Date date = new Date(cookieValue);
out.print(date.toLocaleString());
}
//给用户回送最新的访问时间
Cookie cookie = new Cookie("lastAaccessTime", System.currentTimeMillis() + "");
//设置cookie的最大的有效期
cookie.setMaxAge(1*30*24*3600);
//设置cookie的存放路径,(/网站)
cookie.setPath("/day7");
response.addCookie(cookie);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
}
实现浏览记录的效果:
//代表首页的servlet
public class DemoCookie2 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
//输出网站的所有商品
out.write("本网站有如下商品:<br/>");
Map<String, Book> map = Db.getAll();
for(Map.Entry<String, Book> entry : map.entrySet()){
Book book = entry.getValue();
out.print("<a href='/day7/servlet/DemoServlet3?id="+ book.getId() +"' target='_blank'>" + book.getName() + "</a></br>");
}
//显示用户浏览过的商品
Cookie cookies[] = request.getCookies();
for(int i = 0; cookies != null && i < cookies.length; i ++){
if(cookies[i].getName().equals("bookHistory")){
String ids[] = cookies[i].getValue().split("\\,");
for(String id : ids){
Book book = (Book) Db.getAll().get(id);
out.print(book.getName() + "<br/>");
}
}
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
}
//模拟数据库
class Db{
//linkedHashMap在内存中存放的顺序,才是自己想要的顺序
private static Map<String, Book> map = new LinkedHashMap();
static{
map.put("1", new Book("1", "java开发", "哈哈", "不怎么样的书"));
map.put("2", new Book("2", "jdbc详解", "兮兮", "还好吧样的书"));
map.put("3", new Book("3", "哦好大的彻", "资质", "一般般样的书"));
map.put("4", new Book("4", "学车从开发", "单位", "得得样的书"));
map.put("5", new Book("5", "学车V地方发", "单感叹号", "干部深入沟通"));
}
public static Map getAll(){
return map;
}
}
//javabean
class Book{
private String id;
private String name;
private String author;
private String description;
//无参构造函数
public Book() {
super();
// TODO Auto-generated constructor stub
}
//有参构造函数
public Book(String id, String name, String author, String description) {
super();
this.id = id;
this.name = name;
this.author = author;
this.description = description;
}
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 String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
//显示商品详细信息的servlet
public class DemoServlet3 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
//根据用户带过来的id,显示商品的详细信息
String id = request.getParameter("id");
Book book = (Book) Db.getAll().get(id);
out.write(book.getId() + "<br/>");
out.write(book.getAuthor() + "<br/>");
out.write(book.getName() + "<br/>");
out.write(book.getDescription() + "<br/>");
//构建cookie,回写给浏览器。
String cookieValue = buildCookie(id, request);
Cookie cookie = new Cookie("bookHistory", cookieValue);
cookie.setMaxAge(1*30*24*3600);
cookie.setPath("/day7");
response.addCookie(cookie);
}
//构建cookie
private String buildCookie(String id, HttpServletRequest request) {
//用户没有带cookie值 bookHistory=null 看了 1号书, 保存的 bookHistory=1
//用户带cookie值而且值包含当前值的ID号 bookHistory=2,5,1 当前看的1 保存的《返回来的》 bookHistory=1,2,5
//用户带cookie值而且值没有包含当前值的ID号 bookHistory=2,5,4 而当前看的又是 1 保存的cookie最多只能是3个, bookHistory=1,2,5
//用户带cookie值而且值没有包含当前值的ID号bookHistory=2,5,并且也没有超出3. 而当前看的又是 1 bookHistory=1,2,5
String bookHistory = null;
//判断用户的cookie,得到所有的cookie
Cookie cookies[] = request.getCookies();
for(int i = 0; cookies != null && i < cookies.length; i ++){
//判断有没有带bookHistory这个值:
if(cookies[i].getName().equals("bookHistory")){
//得到带过来的cookie值
bookHistory = cookies[i].getValue();
}
}
// bookHistory=null 1 bookHistory=1
//如果没有带值过来,直接返回id此时的id为1
if(bookHistory==null){
return id;
}
//以逗号分割id号。把数组转为一个集合
List l = Arrays.asList(bookHistory.split("\\,")); //[3,4] //数组 链接
LinkedList<String> list = new LinkedList();
list.addAll(l);
//如果包含这个id,先把他移除,在把他放在第一位
if(list.contains(id)){
// bookHistory=3_1_5 1 bookHistory=1_3_5
list.remove(id);
list.addFirst(id);
}else{
//链表里面的值,已经达到最大值,
if(list.size()>=3){
// bookHistory=3_2_5 1 bookHistory=1_3_2
//删除最后一个,再把当前的值放到第一个
list.removeLast();
list.addFirst(id);
}else{
// bookHistory=3_2 1 bookHistory=1_3_2
list.addFirst(id);
}
}
StringBuffer sb = new StringBuffer(); //2_3_4
for(String lid: list){
//分割
sb.append(lid + ",");
}
//
return sb.deleteCharAt(sb.length()-1).toString();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
}
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
session:
在WEB开发中,服务器可以为每个用户浏览器创建一个会话对象(session对象),注意:一个浏览器独占一个session对象(默认情况下)。因此,在需要保存用户数据时,服务器程序可以把用户数据写到用户浏览器独占的session中,当用户使用浏览器访问其它程序时,其它程序可以从用户的session中取出该用户的数据,为用户服务。
Session和Cookie的主要区别在于:
Cookie是把用户的数据写给用户的浏览器。
Session技术把用户的数据写到用户独占的session中。
Session对象由服务器创建,开发人员可以调用request对象的getSession方法得到session对象。
session的生命周期:服务器会更新Session的最后访问时间,并维护该session。
session的有效期:
session的常用方法:
setMaxInactiveInterval(int interval) //设置有效时间,注意是以秒为单位。Tomcat中的session默认超时时间为20分钟。可以在web.xml中改变Session的默认超时时间。
<session-config>
<session-timeout>50</session-timeout> //单位为分钟
</session-config>
getMaxInactiveInterval(int interval) //获取有效时间
setAttribute(String name, Object value)://以一个指定的名称将一个对象添加到session作用域中
getAttribute(String name)//通过制定名称获取作用域中的对象
removeAttribute(String name)//通过制定名称移除作用域中的对象
getAttributeNames()//获取所有的作用域中的对象
禁用Cookie后servlet共享数据导致的问题。
解决方案:URL重写
response. encodeRedirectURL(java.lang.String url)
用于对sendRedirect方法后的url地址进行重写。
response. encodeURL(java.lang.String url)
用于对表单action和超链接的url地址进行重写
URL地址重写:是对客户端不支持Cookie的解决方案。原理:将用户Session的id信息重新写到URL地址中。服务器能够解析重写后的URL获取Session的id。HttpServletResponse类提供了encodeURL(String url),来实现URL地址重写。
<td>
<a href="<%=response.encodeURL("index.jsp?c=1&wd=java")%>">dede</a>
</td>
页面重定向:URL地址:
<%response.sendRedirectURL("aa.jsp")%>
//购买
public class SessionDemo extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//得到用户session
HttpSession session = request.getSession(); //服务器为用户生成session,再用cookie回写给用户(这个cookie是没有有效期的),再次访问的时候,浏览器会带着这个cookie来访问服务器,寻找服务器之前生成的session
//request.getSession(false); //只需要得到session,没必要创建session
String sessionId= session.getId(); //得到session的id号,回写cookie,覆盖cookie,判断是否是同一个用户
Cookie cookie = new Cookie("JSESSION", sessionId);//服务器回写的session的名称是jsession
cookie.setPath("/day7"); //要和SessionDemo2里面的存放session路径相同
cookie.setMaxAge(30 * 60); //设置有效期
response.addCookie(cookie);
//存到用户的session里面
session.setAttribute("name", "啊哈哈");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
}
//结账
public class SessionDemo2 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
//得到用户session
HttpSession session = request.getSession();
//根据session里面的关键字取出值
String product = (String) session.getAttribute("name");
out.write("您购买的商品是:" + product);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
}