20210715_过滤器和监听器
一、过滤器
一、Filter的工作流程
过滤器是一个驻留在服务器端的Web组件,可以截取用户端和资源之间的请求和响应信息,并对信息进行过滤
1. 过滤器的组成
- 过滤源,请求url的配置
- 所有符合规则的数据交互行为,过滤规则,doFilter中进行编写
-
2.创建一个过滤器
a) 实现javax.servlet.Filter接口
1) void destroy(); 销毁,再服务器关闭时调用,释放filter占用的资源
2)void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException;过滤规则,自动执行的过滤代码,我们需要自定义的部分,如果符合过滤规则,则通过chain放行,如果不符合规则,则做出处理
3)void init(FilterConfig filterConfig) throws ServletException;在服务器启动时自动调用,初始化Filter
b)进行注册,可以通过注册文件的形式或者配置文件的形式(web.xml); web.xml文件中进行注册<filter><filter-name>my</filter-name><filter-class>filter.MyFilter</filter-class><!-- 初始化参数的设置 --><init-param><param-name>charset</param-name><param-value>utf-8</param-value></init-param></filter>- ``
<filter-mapping><filter-name>my</filter-name><url-pattern>/*</url-pattern></filter-mapping>- ``
注解的方式@WebFilter(value="/*",initParams=@WebInitParam(name="charaset" ,value="utf-8"))
区别:
1). web.xml中相对比较写法繁琐一些,注解简单一点;
2). web.xml中后期可以随时更改,注解因为编译后为字节码文件,后期不容易修改
3.生命周期
4.多个过滤器同时存在
当有多个过滤器存在时,主要看url部分,范围大的先进行,范围小的后进入。
先进的后出;形成了一个链。
5.通过过滤器完成请求中的乱码处理
@WebFilter(value="/*",initParams=@WebInitParam(name="charaset" ,value="utf-8"))//过滤所有//filter.MyFilterpublic class MyFilter implements Filter{private String str="utf-8";- ``
@Overridepublic void init(FilterConfig filterConfig) throws ServletException {//获取到配置参数str=filterConfig.getInitParameter("charset")!=null?filterConfig.getInitParameter("charset"):str;}- ``
//在doFilter编写过滤规则@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {request.setCharacterEncoding(str);chain.doFilter(request, response);//代表放行,不会到目标资源去- ``
}@Overridepublic void destroy() {- ``
}- ``
-
6.通过过滤器完成认证
核心代码如下
@WebFilter(value= {"/html/*","/dept/*","/emp/*"})//这些请求都会进入到该过滤器public class LoginAuthenticationFilter implements Filter{/*** 只有登录才放行,没有登录,跳转到登录页面*/@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {HttpServletRequest req=(HttpServletRequest) request;HttpServletResponse resp=(HttpServletResponse) response;String lname= (String) req.getSession().getAttribute("lname");if("admin".equals(lname)) {chain.doFilter(request, response);}else {//req.getRequestDispatcher("/index.html").forward(req, response);resp.sendRedirect("/emp_sys_v2.0/index.jsp");}-
三、监听器
Listener 用于监听 java web程序中的事件,例如创建、修改、删除Session、request、context等,并触发响应的事件。
Listener 对应观察者模式,事件发生的时候会自动触发该事件对应的Listener。 Listener 主要用于对 Session、request、context 进行监控。servlet2.5 规范中共有 8 种Listener
不同功能的Listener 需要实现不同的 Listener 接口,一个Listener也可以实现多个接口,这样就可以多种功能的监听器一起工作。
8种监听器可以分为三类:
监听 Session、request、context 的创建与销毁,分别为 HttpSessionListener、ServletContextListener、ServletRequestListener
监听对象属性变化,分别为: HttpSessionAttributeListener、ServletContextAttributeListener、ServletRequestAttributeListener
监听Session 内的对象,分别为HttpSessionBindingListener 和 HttpSessionActivationListener。与上面六类不同,这两类 Listener 监听的是Session 内的对象,而非 Session 本身,不需要在 web.xml中配置。
1.实现的步骤
1)实现对应的接口
2)注册
使用配置文件 <listener><listener-class>listener.ApplicationListener</listener-class></listener>使用注解
-
使用监听器完成在线人数的统计
1)使用jsp页面作为欢迎页面
2)监听器代码 @WebListenerpublic class OnLineCount implements HttpSessionListener{- ``
@Overridepublic void sessionCreated(HttpSessionEvent se) {//获取到application对象ServletContext application=se.getSession().getServletContext();//获取到数据apllication对象中的值int count=application.getAttribute("count")==null?0:(Integer)application.getAttribute("count");//数量增加count++;application.setAttribute("count", count);- ``
}- ``
@Overridepublic void sessionDestroyed(HttpSessionEvent se) {//数量减少ServletContext application=se.getSession().getServletContext();//获取到数据apllication对象中的值int count=(Integer)application.getAttribute("count");//数量增加count--;application.setAttribute("count", count);- ``
}
使用监听器完成配置文件的读取
因为使用MyBatis框架是需要读取配置文件,读文件比较耗时,希望在项目启动时执行MyBatis中的静态代码块执行文件的读取- ``
@WebListenerpublic class ApplicatListener implements ServletContextListener{- ``
@Overridepublic void contextDestroyed(ServletContextEvent sce) {// TODO Auto-generated method stub- ``
}- ``
@Overridepublic void contextInitialized(ServletContextEvent sce) {//System.out.println("读文件的操作");//读取mybatis的相关配置文件,执行MyBatisUtil中的静态代码块// MyBatisUtil.session;try {//Class.forName就执行类的静态代码块的Class.forName("com.woniu.emp_sys.util.MyBatisUtil");} catch (ClassNotFoundException e) {e.printStackTrace();}- ``
}- ``
}

