Servlet
程序、Listener
监听器、Filter
过滤器
过滤器它是 JavaEE 的规范,也就是一个接口
作用:
拦截请求和过滤响应。拦截请求常见的应用场景有权限检查、日记 *** 作、事务管理等等。
工作原理:
当客户端发出Web资源的请求时,Web服务器根据应用程序配置文件设置的过滤规则进行检查,若客户请求满足过滤规则,则对客户请求/响应进行拦截,对请求头和请求数据进行检查或改动,并依次通过过滤器链,最后把请求/响应交给请求的Web资源处理。请求信息在过滤器链中可以被修改,也可以根据条件让请求不发往资源处理器,并直接向客户机发回一个响应。当资源处理器完成了对资源的处理后,响应信息将逐级逆向返回。同样在这个过程中,用户可以修改响应信息,从而完成一定的任务。生命周期
构造器方法
和init()
方法在web工程启动时就会被执行,此时filter
过滤器已经被创建。- 每次拦截到请求时,就会执行
doFilter()
方法。- 在停止web工程时,就会执行
destroy()
方法,此时会销毁filter过滤器。
可以有多个过滤器,它们运行的先后顺序为:
①:web.xml配置文件
按照先后顺序,从上往下运行
②:注解配置文件
按照路径首字母的顺序运行
package com.zking.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
/**
* 设置过滤器配置文件
* @author Administrator
*
*/
@WebFilter("/LoginFilter")
public class LoginFilter implements Filter {
/**
* 销毁
*/
public void destroy() {
System.out.println("我是过滤器销毁 *** 作,我销毁了");
}
/**
* 过滤器 *** 作
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// 设置编码格式
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
// 放行
chain.doFilter(request, response);
System.out.println("我是过滤器 *** 作,编码格式过滤完毕");
}
/**
* 初始化
*/
public void init(FilterConfig fConfig) throws ServletException {
System.out.println("我是过滤器初始化 *** 作,我初始化了");
}
}
package com.zking.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
@WebFilter("/LoginFilter")
public class LoginFilter implements Filter {
/**
* 销毁
*/
public void destroy() {
System.out.println("我是过滤器销毁 *** 作,我销毁了");
}
/**
* 过滤器 *** 作
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
Object user = session.getAttribute("user");
// 如果等于 null,说明还没有登录
if (user == null) { servletRequest.getRequestDispatcher("/login.jsp").forward(servletRequest,servletResponse);
return;
}else {
// 让程序继续往下访问用户的目标资源
filterChain.doFilter(servletRequest,servletResponse);
}
System.out.println("我是过滤器 *** 作,编码格式过滤完毕");
}
/**
* 初始化
*/
public void init(FilterConfig fConfig) throws ServletException {
System.out.println("我是过滤器初始化 *** 作,我初始化了");
}
}
二:监听器
监听器就是一个实现特定接口的普通java程序,这个程序专门用于监听另一个java对象的方法调用或属性改变,当被监听对象发生上述事件后,监听器某个方法将立即被执行
在java体系中,servlet 监听器有八个接口,而我们常用的有三个:
监听器的分类:
- HttpServletRequestListener
- HttpSessionListener
- ServletContextListener
①.application监听器 1. 实现:ServletContextListener (常用) 重写:
- application 应用级别监听
- session 会话级别的监听
- request 请求级别的监听
//容器启动时调用
public void contextInitialized(ServletContextEvent event){
}
//容器消毁时调用
public void contextDestroyed(ServletContextEvent event){
}
ServletContextEvent事件方法:getServletContext() ----取得ServletContext对象,即上下文
event.getServletContext().getContextPath();
②.Session监听器
实现:HttpSessionListener (偶尔用)重写:
//session创建时调用
public void sessionCreated(HttpSessionEvent event){
}
//session销毁时调用
public void sessionDestroyed(HttpSessionEvent event){
}
HttpSessionEvent事件方法:
getSession() -----------取得当前的session
event.getSession().getId(); //得到session的ID
2:实现:HttpSessionAttributeListener (不用,性能差)
重写:
//增加属性时触发
public void attributeAdded(HttpSessionBindingEvent event){
}
//删除属性时触发
public void attributeRemoved(HttpSessionBindingEvent event){
}
//替换属性时触发
public void attributeReplaced(HttpSessionBindingEvent event){
}
HttpSessionBindingEvent事件方法:
- .getSession() ----------取得session
- .getName() -------------取得属性的名称
- .getValue() ------------取得属性的内容
event.getSession() //取得session
event.getName() //取得属性的名称
event.getValue() //取得属性的内容
③.request监听器
实现:ServletRequestListener (不用,性能差)
重写:
//请求开始时调用
public requestInitialized(ServletRequestEvent event){
}
//请求结束时调用
public requestDestroyed(ServletRequestEvent event){
}
ServletRequestEvent事件方法:
- .getServletRequest()-------取得ServletRequest对象
- .getServletContext()-------取得ServletContext对象
event.getServletRequest().getRemoteAddr(); //得到IP地址
event.getServletContext().getContextPath(); //得到当前路径
注意:
为什么说session监听器和request监听器一般都不用?
答:以request监听器为例,如果采用request监听,那就意味着每次请求都要触发一次监听,这大大降低了程率的效率,因此很少用
案例:监听在线人数
分析:创建一个会话就+1,销毁了会话则-1(在会话被创建时,往全局变量中+1;会话被关闭时,全局变量-1)
服务器停止则移除 count
public class AppListrener implements ServletContextListener,HttpSessionListener {
ServletContext app=null;
//容器销毁时调用
public void contextDestroyed(ServletContextEvent sce) {
// TODO Auto-generated method stub
System.out.println("容器销毁了");
}
//容器初始化时调用
public void contextInitialized(ServletContextEvent sce) {
// TODO Auto-generated method stub
System.out.println("容器初始化了");
app=sce.getServletContext();
Integer count=0;
app.setAttribute("cut", count);
System.out.println(count+"___");
}
//session创建时调用
public void sessionCreated(HttpSessionEvent arg0) {
// TODO Auto-generated method stub
System.out.println("session创建时调用");
Integer count=(Integer)app.getAttribute("cut");
if(count==null){
count=0;
}
count++;
System.out.println("创建时:"+count);
app.setAttribute("cut", count);
}
//session销毁时调用
public void sessionDestroyed(HttpSessionEvent arg0) {
// TODO Auto-generated method stub
System.out.println("session销毁时调用");
Integer count=(Integer)app.getAttribute("cut");
if(count==null){
count=0;
}
count--;
System.out.println("注销时:"+count);
app.setAttribute("cut", count);
}
web.xml文件的配置
com.servlet.AppListrener
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)