ServletContext对象
ServletContext 是整个应用的上下文,一个web程序只有一个ServletContext对象,在服务器启动的时候这个对象就会创建,服务器关闭的时候这个对象会销毁
获取对象
ServletContext servletContext = request.getServletContext();
//在HttpServlet中可以直接获取
ServletContext servletContext1 = this.getServletContext();
//通过session获取
ServletContext servletContext2 = request.getSession().getServletContext();
功能
1. 获取webapp目录下的文件的绝对路径
String realPath = servletContext.getRealPath("/files/" + filename);
2. 作用域 作用范围是整个项目 只要在这个项目中就都可以获取得到
//需要将数据放入作用域中
servletContext.setAttribute("list",list);
//java代码
List<User> list = (List<User>) servletContext.getAttribute("list");
//移除指定的数据
servletContext.removeAttribute("list");
//获取作用域中所有key的名称 可以通过遍历获取作用域中的所有数据
Enumeration<String> attributeNames = servletContext.getAttributeNames();
3. 获取文件的MIME类型
String mimeType = servletContext.getMimeType(realPath);
4. 获取全局的初始化参数
在web.xml文件中去配置全局初始化参数
<!--全局的初始化参数-->
<context-param>
<param-name>aaa</param-name>
<param-value>bbb</param-value>
</context-param>
可以通过ServletContext来获取
//获取全局初始化参数
String aaa = servletContext.getInitParameter("aaa");
//获取所有的名称
Enumeration<String> initParameterNames = servletContext.getInitParameterNames();
//遍历名称在通过上述方法即可获取所有的初始化参数
会话技术
主要涉及的内容是:session,cookie
什么是会话
一次会话:从浏览器打开指定的网站开始(第一次给这个网站发送请求),这个浏览器和这个服务器就建立了一次会话,这个期间无论打开多少个资源(进行多少次页面跳转,或者访问其他网页),访问多少次这个网站,直到有一方断开(浏览器关闭,服务器关闭,会话超时),这次会话才算是结束。这样的一个过程称为一次会话。
一次会话可以包含多次请求
一次会话中是可以共享数据的
会话技术主要包含:cookie和session
cookie
cookie: 客户端会话技术,一般来说是服务器创建,保存在客户端的一小段信息
if("save".equals(save)){//选择了记住账号
//创建了一个cookie的对象
Cookie cookie = new Cookie("username",username);
//默认情况下cookie在关闭浏览器后会被直接删除
//可以设置cookie的生命周期保存的更久一些
cookie.setMaxAge(60 * 60);//设置cookie的声明周期 单位是s 如果是-1 会话结束消失 0直接删除cookie 正数 从创建时间开始算起到指定的时间结束
cookie.setHttpOnly(true);//是否只支持请求携带cookie //是否支持js操作cookie
//true代表不支持 false代表支持
cookie.setPath("/userManager");//设置携带cookie的路径
cookie.setDomain("localhost");//设置域
//响应给客户端
response.addCookie(cookie);
}
//获取cookie
Cookie[] cookies = request.getCookies();
//如果请求中没有cookie的话 返回的是null
//如果客户端没有发送cookie给服务器 这个数组是个null
if(cookies != null){
for (Cookie cookie : cookies) {
if(cookie.getName().equals("username")){
String value = cookie.getValue();//获取到cookie的值
}
}
}
cookie的实现原理
主要是基于响应头 Set-Cookie 和请求头 Cookie来实现的
cookie的细节问题
1. 一次响应是否可以携带多个cookie
可以,只需要服务器创建多个cookie, 并且调用多次addCookie方法即可
但是cookie的名字不能相同 否则后面的会覆盖前面的
2. cookie的生命周期
在默认情况下,服务器响应给客户端以后,会话结束,cookie消失
cookie.setMaxAge(60 * 60); 来设置cookie的生命周期
1. 为负数的时候 浏览器关闭才会消失
2. 为0的时候 立即删除cookie
3. 为正数的时候,指定cookie的存活时间 单位是s
3. 服务器是否可以创建多个同名的cookie
不能,当存在多个同名cookie的时候后创建的会覆盖先创建的
4. cookie中是否可以存中文
在tomcat8之前的版本中是不能存中文的,直接将中文存入value是会报错的。如果在这个版本中需要存中文的内容 URLEncoder.encode() 对中文内容进行加密处理,获取的时候就需要进行解密
在tomcat8及以后的版本中,可以直接存中文了,但是还是有一些特殊符号需要加密解密处理
5. cookie是否可以在多个项目中共享
1. 一个tomcat中的多个项目
默认是不能的,如果真的需要就需要 cookie.setPath("/") //设置携带cookie的路径
就是访问那些路径的时候会携带cookie
2. 如果是不同的tomcat是否可以共享
默认是不能的,如果真的需要共享
cookie.setPath("/") 设置路径
设置域 域名 a.com www.a.com aa.a.com ...
cookie.setDomain(".a.com")
如果按照上面这种方式来配置的话 tomcat8.5及以后的版本会报错 因为8.5 添加了设置域名的规范
可以在tomcat的Context.xml文件中 添加一行代码,重新设置域名的规范
<CookieProcessor className="org.apache.tomcat.util.http.LegacyCookieProcessor"/>
虽然这样配置后理论上cookie就可以访问了,但是还需要浏览器的支持
一般来说浏览器为了安全起见,如果cookie的domain和响应cookie的域名不相同的时候,浏览器是不会保存这个cookie的
6. cookie的特点和作用
1. cookie存在于客户端的
2. 一般情况下cookie的大小不超过4kb及一个域名下不超过20个cookie
作用:
1. 一般来说cookie中存储的信息不能是敏感信息
2. 在未登录的时候可以使用cookie来完成客户端的身份识别(可以使用cookie来完成一个未登录版本的购物车)
1. 创建一个cookie,用来存储商品的id和数量 Cookie cookie = new Cookie("carts","1,1;2,3")
2. 添加商品到购物车中,只需要将商品的id和数量存入即可 Cookie cookie = new Cookie("carts","1,1;2,3")
3. 登录以后将cookie中的数据写入数据库
session
存在于服务器的一种会话技术,在一次会话中的多次请求都可以将数据存入session,通过session进行数据共享
session 存在于服务器的内存中
获取session
在一次会话中 如果之前没有获取过,就返回一个新的session,如果之前已经获取过就返回之前的session
HttpSession session = request.getSession();
如果参数为true和不传参是一样的效果 如果是false 如果之前有获取过就返回之前的,如果之前没有获取过就返回null
HttpSession session1 = request.getSession(true);
使用session
session 也是一个作用域
session.setAttribute(name,value);
Object attribute = session.getAttribute(name);
session.removeAttribute(name);
Enumeration<String> attributeNames = session.getAttributeNames();
session.invalidate();//销毁session对象
long creationTime = session.getCreationTime();//获取session的创建时间
long lastAccessedTime = session.getLastAccessedTime();//获取session的最后一次访问时间
boolean aNew = session.isNew();//是否为新的session
String id = session.getId();//获取session的id
session.setMaxInactiveInterval();//设置session的生命周期
目前为止学过的作用域有三个 作用域从小到大分别是 request < session < servletContext
session的实现原理
1. session的实现依赖于cookie
当第一次获取session的时候,session会自动创建一个cookie响应给客户端,这个cookie的name是JSESSIONID,value是session.getId(),这个cookie的存活时间默认是-1,浏览器关闭后就直接销毁cookie
session自动响应的这个cookie,在每一次请求的时候都会带上,通过cookie中的sessionid可以找到对应的session对象,这样的话就可以为用户创建对应的会话,而不会导致多个用户之间的数据紊乱
2. 当关闭浏览器,服务器没有关,对应的session销毁了么?
session没有销毁,session默认的存活时间是30分钟
当关闭浏览器,再次打开,找不到对应的session原因是,session自动产生的cookie在关闭浏览器的时候被销毁了,那么再次请求的时候请求中没有携带JSESSIONID的cookie,所以找不到对应的session
如果想要关闭浏览器后,再次打开依然可以找到原本的session
HttpSession session = request.getSession();
session.setAttribute("CUR_USER",user);
Cookie cookie = new Cookie("JSESSIONID",session.getId());
cookie.setPath("/userManager");
cookie.setMaxAge(60 * 60);
response.addCookie(cookie);
在获取session的时候可以手动写一个cookie,name为JSESSIONID,值为session.getId();给cookie设置一个生命周期,这样的话这个cookie在时间未到的时候就会持久化到浏览器中,那么即使浏览器关闭后再打开依然不会消失,请求中依然会携带这个cookie,session就可以找得到
3.session的生命周期
session默认是30分钟 (conf/web.xml中配置的)
session的生命周期是从最后一次访问开始计算的(long lastAccessedTime = session.getLastAccessedTime();) 而不是从创建开始计算(long creationTime = session.getCreationTime();) 如果一直没有操作session,30分钟后session会自动销毁,如果中途操作过session,那么存活时间又会刷新到30分钟
修改session的生命周期
1. conf/web.xml中 单位是分钟 会影响到该tomcat中的所有项目
<session-config>
<session-timeout>30</session-timeout>
</session-config>
2. 在项目的web.xml文件中 单位也是分钟 会影响到该项目中的所有session
<session-config>
<session-timeout>30</session-timeout>
</session-config>
3.session.setMaxInactiveInterval(s); 去配置 参数就是时间 单位是s 只会影响到调用这个方法的session
4. 浏览器没关,服务器关闭了 session销毁了么?
销毁了,因为关闭了服务器,服务器的内存就会被清空,那么session就销毁了
解决上述问题:目前主流的方案是使用redis,在服务器关闭之前将session存入redis,服务器关闭再打开后又从redis中读取原本的session数据
5. session什么时候会被销毁
1.服务器关闭后
2.调用session的销毁方法 session.invalidate();
3.时间到了session也会被销毁
面试题: cookie和session的区别
cookie
保存在客户端的
cookie的大小有限制
只能存储字符串类型数据
安全性较低
session
保存在服务器的
理论上大小是没有限制的
可以存储任意类型的数据
安全性较高
购物车实现
# 商品表
create table goods (
gid bigint primary key auto_increment,
gname varchar(50) not null,
gdesc varchar(100),
price decimal(11,2),
stock int default 0
)
# 用户表
create table user(
uid bigint primary key auto_increment,
username varchar(50) unique not null,
password varchar(50) not null
)
# 购物车表
create table cart(
cid bigint primary key auto_increment,
uid bigint
)
# 购物车详情表
create table cartinfo(
ciid bigint primary key auto_increment,
gid bigint,
counts int,
cid bigint
)
sion销毁了么?
销毁了,因为关闭了服务器,服务器的内存就会被清空,那么session就销毁了
解决上述问题:目前主流的方案是使用redis,在服务器关闭之前将session存入redis,服务器关闭再打开后又从redis中读取原本的session数据
5. session什么时候会被销毁
1.服务器关闭后
2.调用session的销毁方法 session.invalidate();
3.时间到了session也会被销毁
面试题: cookie和session的区别
cookie
保存在客户端的
cookie的大小有限制
只能存储字符串类型数据
安全性较低
session
保存在服务器的
理论上大小是没有限制的
可以存储任意类型的数据
安全性较高
购物车实现
```sql
# 商品表
create table goods (
gid bigint primary key auto_increment,
gname varchar(50) not null,
gdesc varchar(100),
price decimal(11,2),
stock int default 0
)
# 用户表
create table user(
uid bigint primary key auto_increment,
username varchar(50) unique not null,
password varchar(50) not null
)
# 购物车表
create table cart(
cid bigint primary key auto_increment,
uid bigint
)
# 购物车详情表
create table cartinfo(
ciid bigint primary key auto_increment,
gid bigint,
counts int,
cid bigint
)