手机扫码查看
Javaweb教程:servlet状态管理
servlet状态管理
servlet生命周期
阶段一:实例化(调用构造方法)
实例化阶段是servlet生命周期中的第一步,由servlet容器调用
servlet的构造器创建一个具体的servlet对象的过程。
阶段二:初始化(init方法)
servlet在被加载实例化之后,必须要初始化它。在初始阶段,init()方法会被调用
阶段三:就绪/服务
servlet被初始化以后就处于能够响应请求的就绪状态。
阶段四:销毁
servlet容器在销毁servlet对象时会调用destroy方法来释放资源。
====================================
servlet线程安全问题
线程安全问题
因为每次请求都会创建一个线程,如果多人同时请求,那么就会存在多个线程
操作同一个servlet对象,那么如果在对应的方法中操作了成员变量,就有可能
产生线程安全的问题
如何保证线程安全
1.synchronize
将存在线程安全问题的代码放到同步代码块中
2.实现SingleThreadModel接口(已过时)
servlet实现singleThreadModel接口后,每个线程都会创建servlet实例
3.尽可能只使用局部变量

====================================
servlet初始化参数
web.xml方式
<init-param>
<param-name>name</param-name>
<param-value>张三</param-value>
</init-param>
1.init-param元素用来定义servlet启动的参数,可以定义多个
2.param-name表示参数名称
3.param-value表示参数值
注解方式
@WebServlet(name = "initServlet",value = "/is",
initParams = {@WebInitParam(name = "username", value = "zhangsan"),
@WebInitParam(name = "password",value = "123456")})
dopost()方法里添加
ServletConfig sc=this.getServletConfig();
String uname=sc.getInitParameter(“uname”);
String password=sc.getInitParameter(“password”);
sout(uname+”:”+password);
====================================
状态概念以及cookie基础
状态管理概述
为什么需要状态管理
HTTP协议是无状态的,不能保存每次提交的信息,即当服务器返回与请求相对应的应答之后,
这次事务的所有信息就丢掉了。
什么是状态管理
web应用中的会话是指一个客户端浏览器与web服务器之间连续发生的一系列请求和响应过程。
状态管理的两种模式
1.客户端状态管理技术:将状态保存在客户端。代表性的是cookie技术
2.服务器状态管理技术:将状态保存在服务器端。代表性的是session技术(服务器传递sessionID时需要使用cookie的方式)
什么是cookie
Cookie是在浏览器访问WEB服务器的某个资源时,由WEB服务器在HTTP响应消息头中附带传送给浏览器的一小段数据,
WEB服务器传送给各个客户端浏览器的数据是可以各不相同的。
一旦WEB浏览器保存了某个Cookie,那么它在以后每次访问该WEB服务器时,都应在HTTP请求头中将这个Cookie回传给WEB服务器。
WEB服务器通过在HTTP响应消息中增加Set-Cookie响应头字段将Cookie信息发送给浏览器,浏览器则通过在HTTP请求消息中
增加Cookie请求头字段将Cookie回传给WEB服务器。
一个Cookie只能标识一种信息,它至少含有一个标识该信息的名称(NAME)和设置值(VALUE)。
一个WEB站点可以给一个WEB浏览器发送多个Cookie,一个WEB浏览器也可以存储多个WEB站点提供的Cookie.
浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4KB
如何创建cookie
//创建cookie
CooKie ck=new CooKie(“name”,”abc”);
//设置cookie路径,当前服务器下
ck.setPath(“/”);
//cookie生命周期:负数—>浏览器内存里,0–>失效,正数–>生效时间(秒)
ck.setMaxAge(-1);
//让浏览器添加cookie
response.addCookie(ck);
====================================
cookie的查询、修改
查询
Cookie[] cookies = request.getCookies();
if(cookies.length!=0){
for (Cookie cookie : cookies) {
String name = cookie.getName();
if("username".equals(name)){
if("zhangsan".equals(cookie.getValue())){
System.out.println("当前已经登陆过了");
}
}
}
}
修改跟创建一样
只需要保证cookie的名和路径一致即可修改
cookie的生存时间
默认-1,浏览器关闭失效
取值说明:
>0有效期,单位秒
=0失效
<0内存存储
====================================
cookie生命周期和共享范围
ck.setPath(“/”);//设置cookie路径,当前服务器下
ck.setMaxAge(-1);//cookie生命周期
====================================
cookie的编码和解码
编码
URLEndoer.encode(“姓名”,”UTF-8″)
解码
URLDecoder.decode(name,”UTF-8″).equals(“姓名”);
====================================
优点
可配置到期规则:Cookie可以在浏览器会话结束时到期,或者可以在客户端计算机上无限期存在,
这取决于客户端的到期规则,不需要任何服务器资源,cookie存储在客户端并在发送后由服务器读取。
简单性:Cookie是一种基于文本的轻量结构,包含简单的键值对。
数据持久性:虽然客户端计算机上Cookie的持续时间取决于客户端上的Cookie过期处理和用户干预,
Cookie通常是客户端上持续时间最长的数据保留形式
缺点
大小受到限制:大多数浏览器对Cookie的大小有4096字节的限剖,尽管在当今新的浏览器和
客户端设备版本中,支持8192字节的Cookie大小已愈发常见。
用户配置为禁用:有些用户禁用了浏览器或客户端设备接收Cookie的能力,因此限制了这一功能。
潜在的安全风险:Cookie可能会被墓改。用户可能会操纵其计算机上的Cookie,
这意味着会对安全性造成潜在风险或者导致依赖于Cookie的应用程序失败。
====================================
session基础
什么是session
session用于跟踪客户端的状态,session指的是在一段时间内,单个客户端与web服务器的一连串相关的
交互过程。
在一个session中,客户可能会多次请求访问同一个网页,也有可能请求访问各种不同的服务器资源。
session工作原理
session被用于表示一个持续的连接状态,在网站访问中一般指代客户端浏览器的进程从开启到结束的过程。
session其实就是网站分析的访问(visits)度量,表示一个访问的过程。
session的常见实现形式是cookie(session cookie),即未设置过期时间的cookie,这个cookie的默认生命周期
为浏览器会话期间,只要关闭浏览器窗口,cookie就消失了。实现机制是当用户发起一个请求的时候,
服务器会检查该请求中是否包含sessionid,如果未包含,则Tomcat会创造一个名为JSESSIONID的输出
cookie返回给浏览器(只放入内存,并不存在硬盘中),并将其以HashTable的形式写到服务器的内存里面;
当已经包含sessionid时,服务端会检查找到与该session相匹配的信息,如果存在则直接使用该sessionid,
若不存在则重新生成新的session。这里需要注意的是session始终是有服务端创建的,并非浏览器自己生成的。
如何获得session
//获取session对象,先判断请求内容里是否包含了session。如果没有则会自动创建
HttpSession session=request.getSession();
sout(“Id:”+session.getId());//唯一标记
sout(“最后一次访问时间,毫秒”+session.getLastAccessedTime());
sout(“获取最大的空闲时间,单位秒”+session.getMaxInactiveInterval());//默认session失效时间30分钟
sout(“获取session的创建,单位毫秒”+session.getCreationTime());
如何使用session绑定对象
使用HttpSession的setAttribute(属性名,object)方法
如何删除session
使用HttpSession的invalidate方法
====================================
Session超时
什么是session超时:HttpSession的最后一次访问时间和当前时间的差距大于了指定的最大空闲时间,这时服务器就会销毁Session对象。默认的空闲时间为30分钟。
修改session缺省时间限制:
1 使用HttpSession的session.setMaxInactiveInterval(20*60);设置,单位秒
2 在web.xml中配置 ,单位分钟
<session-config>
<session-timeout>20</session-timeout>
</session-config>
不冲突
session失效的几种情况:
1、超过了设置的超时时间
2、主动调用了invalidate方法
3、服务器主动或异常关闭
注意:浏览器关闭并不会让Session失效
====================================
浏览器禁用cookie的后果
如果浏览器禁用cookie,session还能用吗?
答:不能,但有其他的解决方案
服务器默认情况下,会使用cookie的方式将sessionID发送给浏览器,如果用户禁止cookie,
则sessionID不会被浏览器保存,此时,服务器可以使用如URL重写这样的方式来发送sessionID
使用session区分每个用户的方式:
1.使用cookie
2.座位隐藏域嵌入html表单中,附加在主体的URL中,通常作为指向其他应用程序页面的链接,即URL重写
什么是URL重写
浏览器在访问服务器上的某个地址时,不再使用原来的那个地址,而是使用经过改写的地址,
即,在原来的地址后面加上了sessionID
如何实现URL重写
如果是链接地址和表单提交,使用response.encodeURL(String url)生成重写后的URL
String s=response.encodeURL(“项目/资源”);
sout(s);
writer.println(“<a href=”"+s+"”>”+”跳转”+”</a>”);
如果重定向,使用response.encodeRedirectURL(String url)生成重写后的URL
String s=response.encodeRedirectURL(“项目/资源”);
response.sendRedirect(s);
====================================
session超时
什么是session超时
HttpSession的最后一次访问时间和当前时间的差距大于了指定的最大空闲时间,这时服务器就会
销毁session对象,默认的空闲时间是30分钟
如何修改session的缺省时间限制
1.HttpSession的session.setMaxInactiveInterval(20*60);//设置,单位秒
2.在web.xml中配置,单位分钟
20
session失效的几种情况
1.超过了设置的超时时间
2.主动调用invalidate方法
3.服务器主动或异常关闭
注意:浏览器关闭并不会让session失效
====================================
验证登录
//1.获取session
HttpSession session = request.getSession();
//2.获取用户名
String username1 = (String) session.getAttribute("username");
UsersDao ud=new UsersDaoImpl();
//3.查询所有用户
List<Users> all = ud.getAll();
//4.遍历所有用户
for (Users users : all) {
//如果获取到的用户名为空
if(username1==null) {
//从表单获取用户传入的值
String username = request.getParameter("username");
String password = request.getParameter("password");
//将用户输入的值与数据库里的用户数据比较
if( users.getUsername().equals(username)
&& users.getPassword().equals(password) ){
//用户输入正确将用户名存入作用域
session.setAttribute("username",username);
//登录后跳转到首页
response.sendRedirect("/servlets/home.html");
return;
}else{
//如果用户输入的值不匹配则跳转到登陆失败页面
response.sendRedirect("/servlets/filed.html");
return;
}
}else{//如果用户已登录则跳转到首页
response.sendRedirect("/servlets/home.html");
return;
}
}
退出登录
HttpSession session = request.getSession();
session.removeAttribute("users");
session.invalidate();
response.sendRedirect("/servlets/login.html");
====================================
验证码登录
Validateservlet:
导jar包ValidateCode.jar
ValidateCode code=new ValidateCode(120,60,4,1);//宽、高、几个字符、干扰线
String code1 = code.getCode();
HttpSession session = request.getSession();
session.setAttribute("code",code);//通过session把验证码存入作用域
code.write(response.getOutputStream());
html:
验证码<input name=”validate” type=”text” /><img src=”项目/Validateservlet” />
====================================
ServletContext对象
什么是ServletContext?ServletContext:servlet上下文
当WEB服务器启动时,会为每一个WEB应用程序(webapps下的每个目录就是一个应用程序)创建一块共享的存储区域
ServletContext也叫做“公共 区域”,也就是同一个WEB应用程序中,所有的Servlet和JSP都可以共享同一个区域。
ServletContext在WEB服务器启动时创建,服务器关闭时销毁。
如果获得servlet上下文
方式一:GenericServlet提供了getServletContext()方法。(推荐)
方式二:ServletConfig提供了getServletContext()方法。
方式三:HttpSession提供了getServletContext()方法。
方式四:HttpServletRequest提供了getServletContext()方法。(推荐)
servlet上下文的作用及特点
作用:
1.获取真实路径
request.getServletContext().getRealPath("/");
2.获取容器附加信息
String serverInfo = request.getServletContext().getServerInfo(); String contextPath = request.getServletContext().getContextPath(); String contextPath1 = request.getContextPath();
3.全局容器
//设置信息到全局容器中
request.getServletContext().setAttribute("msg","共享信息");
//获取数据
String msg = (String) request.getServletContext().getAttribute("msg");
response.getWriter().write(msg);
System.out.println(msg);
//移除数据
request.getServletContext().removeAttribute("msg");
特点:
唯一性: 一个应用对应一个servlet上下文。
一直存在: 只要容器不关闭或者应用不卸载,servlet上下文就一直存在。
====================================
web.xml文件配置servletContext参数
<!– 配置应用程序的初始化参数 –>
<context-param>
<param-name>appname</param-name>
<param-value>xxx管理系统</param-value>
</context-param>
<context-param>
<param-name>appversion</param-name>
<param-value>2.0</param-value>
</context-param>
//获取servlet上下文参数
String appname=application.getInitParameter(“appname”);
String appversion=application.getInitParameter(“appversion”);
System.out.println(appname+”…”+appversion);
====================================
ServletContext统计Servlet访问次数
ServletContext sc = request.getServletContext();
Integer num = (Integer) sc.getAttribute("num");
if (num == null) {
num=1;
sc.setAttribute("num",num);
}else{
num++;
sc.setAttribute("num",num);
}
response.getWriter().write("总访问:"+num+"次");



发表回复