🌸Author Echo Pan
会话(Session)是指在一段时间内,某一客户与服务器之间一连串相关的交互过程。当前浏览器与服务器之间的多次请求和响应关系被称为一次会话。在一个会话中,用户可以多次访问同一网页,也可以访问该服务器的其他资源。
HttpServlet
接口位于javax.servlet.http
包,每一个Servlet
容器(如Tomcat
)都必须实现该接口。
当一个会话开始时,容器会创建一个HttpSession
对象,并为该对象分配一个唯一标识,即sessionID
。容器会把sessionID
保存在客户端的浏览器中。每当客户发出一个HTTP
请求时,容器就可以从客户端读取到sessionID
,并根据该标识找到对应的HttpSession
对象,从而获取客户的状态信息。
Httpsession session = HttpServletRequest.getSession([true]|[false]);
当参数为空或true
时,如果存在会话则返回该会话,不存在时则创建一个新会话并返回;当参数为false
时,如果会话不存在则返回null
。
setAttribute()
添加属性及属性值
getAttribute()
获取属性值,返回Object
类型
getAttributeNames()
获取所有属性名,返回一个数组
removeAttribute()
移除一个属性
getCreationTime()
获取会话创建的时间
getId()
获取会话ID
getLastAccessedTime()
获取最后一次访问会话的时间戳,毫秒
getMaxInactiveInterval()
获取会话有效期
isNew()
打开页面时,判断该页面的session是否是首次创建
setMaxInactiveInterval()
设置最大有效期,单位秒
Invalidate()
释放会话
假设我们在doGet()
方法中使用session
对象:
//先设置一个可供链接访问该servlet的注解
@WebServlet("/servlet/Counter");
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//设置中文编码
response.setContentType("text/html;charset=UTF-8");
//创建一个session
HttpSession session = request.getSession(true);
Object count = session.getAttribute("counter");
int counter=0;
//判断session参数是否存在
if(count == null){
counter=1;//不存在则给计数器赋值1,表示开始计数
session.setAttribute("Counter",counter);//更新session参数值
}else{
counter = Integer.parseInt(String.valueOf(count));//存在则获取session参数
counter+=1;//并表示计数加1
session.setAttribute("Counter",counter);//更新session参数
}
//下面输出试试看,尝试多刷新几次网页
PrintWriter out = response.getWriter();
out.println("计数器测试:第"+session.getAttribute("Counter")+"次");
out.flush;
out.close;
}
session
对象session.invalidate()
方法Servlet 2.3
新特性,用于拦截资源文件,实现访问控制、加密、解决中文乱码、日志记录等功能。
客户端请求: 位于服务器端的过滤器对请求内容进行预处理,再用处理好的请求去获取web资源(由Servlet
产生);
服务器响应: web资源的响应经过过滤器后处理,处理好再发送给客户端。
client –> request –> filter –> servlet
servlet –> response –> filter –> client
多个过滤器可以形成一个过滤器链,按照配置的顺序执行,最先截取请求的过滤器最后截取到响应。
Servlet
等组件的区别Servlet
组件是需要请求进入到web
容器后再对其进行处理的,而filter
则是“链接”在处理过程中,即在请求被容器获取并处理之前进行预处理,同理在响应信息被发送回客户端之前也可以进行后处理,是一个典型的处理链。
Filter API 位于javax.servlet
包中,一共有三个接口:
Filter
接口所有过滤器都必须实现Filter
接口,主要方法:init()
、doFilter()
、destroy()
。
init()
方法web
容器创建完Filter
实例后,会立即调用其init()
方法,在初始化过程中会向该实例传递一个包含Filter
配置和运行环境的FilterConfig
对象。
通过FilterConfig
对象可以获得ServletContext
对象(相当于applicaiton
范围)及过滤器的init-param
(通过getInitParameter()
方法)。
public void init(FilterConfig filterConfig) throws ServletException;
doFilter()
方法public void doFilter(ServletRequest request,ServletResponse,FilterChain chain)
throws IOException,ServletException;
其中request
和response
是传递过来的请求或响应,参数chain
代表当前Filter
对象的链,在该对象的doFilter()
方法中调用chain.doFilter(request,response)
方法可以把请求(响应)转发给下一个Filter
或目标程序去处理。
destroy()
方法public void destroy();
FilterChain
接口代表Filter
链,只有一个doFilter()
方法,是由Servlet
容器提供的。用来调用下一个过滤器或目标资源。
FilterConfig
接口用于检索过滤器名、初始化参数以及当前的Servlet
上下文。
返回部署的过滤器名:
public String getFilterName();
返回调用者所处的servlet上下文
public ServletContext getServletContext();
返回初始化参数,不存在时返回null
;返回初始化参数集合,不存在时返回空值。
public String getInitParameter(String name);//name为参数名
public Enumeration getInitParameterNames();//返回所有初始化参数名称的集合,没有则返回空值
Filter
简单应用过滤器实质上是一个实现了javax.servlet.Filter
接口的java
类。最原始的创建步骤是:
Filter
接口Myeclipse
创建过滤器新建 - 其他 - web - 过滤器
也可以现创建一个类,继承(implements)Filter
接口,再快速修复
由于过滤器在服务器启动时初始化,故修改后需要重启服务器生效。
web.xml
中配置<filter>
<filter-name>过滤器名</filter-name>
<filter-class>过滤器类</filter-class>
<init-param>
<param-name>参数名</param-name>
<param-value>参数值</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>过滤器名</filter-name>
<url-patterm>拦截的URL</url-pattern>
<servlet-name>拦截的servlet</servlet-name>
<dispatcher>拦截的调用方式</dispatcher>
</filter-mapping>
dispatcher
标签的参数取值为REQUEST
、ERROR
、INCLUDE
和FORWARD
,根据容器中目标资源被调用的方式决定是否触发过滤器。
注: 组件书写顺序不影响实际顺序,实际顺序参考 节点加载顺序 。对于拥有相同filter-name
的filter
和filter-mapping
配置节而言,filter-mapping
必须出现在filter
之后,否则当解析到filter-mapping
时,它所对应的filter-name
还未定义。
@WebFilter
中配置@WebFilter(filterName="FilterDemo1",
urlPatterns={"/*"},
servletNames={"MyServlet"},
initParams={
@WebInitParam(name="param1",value="value1")
}
)
其中,urlPattern
是匹配客户端请求URL
,servletNames
是匹配servlet
。
要求:创建一个过滤器,被执行时在控制台输出”您的请求已被拦截!“。
src
文件夹中创建包和类Filter
接口并实现方法doFilter()
方法中编写预处理代码,System.out.println("您的请求已被拦截!");
@WebFilter(urlPatterns="/*",
initParams= {
@WebInitParam(name="student",value="echo")
} )
public class FilterDemo1 implements Filter {
public FilterDemo1() {
}
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("您的请求已被拦截!");
chain.doFilter(request, response);
}
public void init(FilterConfig fConfig) throws ServletException {
}
}
我们可以通过Filter
统一解决中文乱码问题,只需要用过滤器拦截网页请求,然后把请求的编码格式替换成UTF-8
再继续提交就可以了。
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
session
对象HttpServletRequest httpRequest=(HttpServletRequest)request;
HttpSession session=httpRequest.getSession();
String value=(String)session.getAttribute("value");