Servlet过滤器、编码过滤、Servlet监听器

目录

过滤器

简介

编码过滤

登录检测

Servlet监听器

对Servlet上下文监听

对session监听


Servlet一共分为三类:基础Servlet、过滤器、监听器。

过滤器

简介

过滤器的本质在于过滤所有的非法操作,而且所有的过滤需要自动实现过滤操作。想要在WEB中实现过滤器,需要一个专门的程序类,这个类需要去实现javax.servlet.Filter接口,这个接口里面定义有三个方法:

  • 初始化:public void init(FilterConfig filterConfig) throws ServletException ;

| - 当容器启动后,过滤器就启动了

  • 执行过滤:public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException ;

  • 销毁过滤器:public void destroy()

范例:建议MyFilter过滤器程序类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package cn.ren.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;

public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("*** 初始化参数 ****" + filterConfig.getInitParameter("myparam"));
    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        System.out.println(" *** 过滤器执行前 *****");
        chain.doFilter(request, response);
        System.out.println(" *** 过滤器执行后 *****");
    }
    @Override
    public void destroy() {
        System.out.println("*** 销毁 ***");
    }

}

对于每个过滤器而言将用户的请求转发到目标位置需要利用FilterChain接口完成,这个接口;里面定义有 如下方法:

  • public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException

过滤器依然属于Servlet程序,所以依然需要在web.xml中进行配置

1
2
3
4
5
6
7
8
9
10
11
12
13
<filter>
    <filter-name>MyFliter</filter-name>
    <filter-class>cn.ren.filter.MyFliter</filter-class>
    <init-param>
        <param-name>myparam</param-name>
        <param-value>init_param</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>MyFliter</filter-name>
    <!-- 这里是过滤路径,设置为“/*”表示过滤所有路径,如果设置具体,则.. -->
    <url-pattern>/*</url-pattern>
  </filter-mapping>

所有的过滤器会根据器过滤路径自动进行执行,执行时一定要使用FilterChain接口中的doFilter()方法,将用户请求向后传递。

编码过滤

编码过滤主要是为了解决页面乱码的问题,如果所有的页面通过过滤器进行编码过滤,就不需要在每个页面上编写过滤代码。

范例:定义一个input.jsp页面

1
2
3
4
5
6
<body>
    <form action="show.jsp" method="post">
        信息:<input type="text" name="msg" id="msg" >
        <input type="submit" value="发送">
    </form>
</body>

范例:编写show.jsp页面

1
<h1>msg = ${param.msg}</h1>

范例:编写一个编码过滤器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package cn.ren.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;

public class EncodingFilter implements Filter {
    private String charset = "UTF-8" ;
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 可以通过初始化参数进行过滤器编码的同一配置,这样如果要更换编码,这样修改web.xml配置文件
        if(filterConfig.getInitParameter("charset") != null) {
            this.charset = filterConfig.getInitParameter("charset") ;
        }  
    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        request.setCharacterEncoding(this.charset);
        response.setCharacterEncoding(this.charset);
        chain.doFilter(request, response);
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
  <filter>
    <filter-name>EncodingFilter</filter-name>
    <filter-class>cn.ren.filter.EncodingFilter</filter-class>
    <init-param>
        <param-name>charset</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>EncodingFilter</filter-name>
    <!-- 这里是过滤路径,设置为“/*”表示过滤所有路径,如果设置具体,则.. -->
    <url-pattern>/*</url-pattern>
  </filter-mapping>

规范以后的开发程序使用编码过滤,不用在页面编写编码

登录检测

之后更。。。。。

Servlet监听器

Servlet监听器是对整个WEB状态进行监听,主要分为两种形式:application监听(ServletContext监听、整个容器监听)、session监听(用户的状态);

对Servlet上下文监听

实现对Servlet上下文监听,那么就需要两种监听处理:

  • 对Servlet上下文的状态监听:javax.servlet.ServletContextListener

| - 容器启动:public void contextInitialized(ServletContextEvent sce)

| - 容器销毁:public void contextDestroyed(ServletContextEvent sce)

| - ServletContextEvent 事件对象:public ServletContext getServletContext()

  • 对Servlet上下文属性监听:javax.servlet.ServletContextAttributeListener

|- 增加属性:public void attributeAdded(ServletContextAttributeEvent event)

|- 替换属性:public void attributeRemoved(ServletContextAttributeEvent event)

|- 删除属性: public void attributeReplaced(ServletContextAttributeEvent event)

|- ServletContextAttributeEvent事件对象:

|- 取得属性名称:public String getName()

|- 取得属性内容:public Object getValue()

范例:定义一个Servlet的整体监听

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package cn.ren.listener;

import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class MyListener implements ServletContextListener, ServletContextAttributeListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("*** 容器启动 ***" + sce.getServletContext().getRealPath("/"));
    }  
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("*** 容器销毁 ***" + sce.getServletContext().getRealPath("/"));
    }
    @Override
    public void attributeAdded(ServletContextAttributeEvent event) {
        System.out.println(" *** 增加application *** name = " + event.getName() + "、value = " + event.getValue());
    }
    @Override
    public void attributeRemoved(ServletContextAttributeEvent event) {
        System.out.println(" *** 删除application *** name = " + event.getName() + "、value = " + event.getValue());
    }
    @Override
    public void attributeReplaced(ServletContextAttributeEvent event) {
        System.out.println(" *** 替换application *** name = " + event.getName() + "、value = " + event.getValue());
    }
}

配置

1
2
3
  <listener>
    <listener-class>cn.ren.listener.MyListener</listener-class>
  </listener>
1
2
3
4
<%
    //application.setAttribute("msg", "www.baidu.com") ;
    application.removeAttribute("msg") ;
%>

对session监听

session监听指的是针对一个用户的状态监听,有两种:

  • session的状态监听:javax.servlet.http.HttpSeesionListener;

| - session创建:public void sessionCreated(HttpSessionEvent se) ;

| - session销毁:public void sessionDestroyed(HttpSessionEvent se) ;

| - HttpSessionEvent 事件: public HttpSession getSession()

  • seesion的属性监听:javax.servlet.http.HttpSessionAttributeListener

| - 增加属性:public void attributeAdded(HttpSessionBindingEvent event)

| - 替换属性:pbulic void attributeRemoved(HttpSessionBindingEvent event)

| - 销毁属性:public void attributeReplaced(HttpSessionBindingEvent event)

| - HttpSessionBindingEvent 事件:

| - public String getName()

| - public Object getValue()

| - public HttpSession getSession()

范例:观察Session

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package cn.ren.listener;

import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

public class SessionListener implements HttpSessionListener, HttpSessionAttributeListener {
    @Override
    public void sessionCreated(HttpSessionEvent se) {
        System.out.println("**** Session创建 ***" + se.getSession().getId());
    }
    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        System.out.println("**** Session销毁***" + se.getSession().getId());
    }
    @Override
    public void attributeAdded(HttpSessionBindingEvent event) {
        System.out.println("**** Session属性增加 ***" + event.getName() + "、" +  event.getValue());
    }
    @Override
    public void attributeRemoved(HttpSessionBindingEvent event) {
        System.out.println("****属性删除 ***" + event.getName() + "、" +  event.getValue());
    }
    @Override
    public void attributeReplaced(HttpSessionBindingEvent event) {
        System.out.println("****属性替换***" + event.getName() + "、" +  event.getValue());
    }
   
}
1
2
3
  <listener>
    <listener-class>cn.ren.listener.SessionListener</listener-class>
  </listener>

session有三种情况会销毁:

  • 【项目运行时】使用session.invalidate()方法销毁;
  • 【项目运行过程中】session过时销毁,默认时间是30分钟;
  • 【项目开发之中】web项目重新加载会销毁;

过时时间可以自定义:(时间单位为1分钟)

1
2
3
  <session-config>
    <session-timeout>1</session-timeout>
  </session-config>