🌸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");