Java Web filter and listener

filter

The filter is a component on the server side, which is used to filter the requests coming to the server and the responses returned by the server. For example, a filter determines whether the user is logged in to perform different operations, or requests to return an error message when there is no page. The filter is loaded and generated when the server service starts, and then the request and response between the user and the server must pass through the filter

1. Create a filter

To create a filter class, you need to implement the three methods of the Filter interface. Init () is the initialization method of the filter. This method is called after the web container creates the filter to read the filter parameters from the web.xml file. doFilter () completes the filtering operation. When the request request reaches the filter, it performs the doFilter () operation to process the request: forwarding, redirecting, or passing to the next filter. The response returned after performing the relevant operation will be returned to the Filter user. destroy () is called before the web container destroys the instance to release the resources occupied by the filter.

public class firstFilter implements Filter {
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("创建第一个过滤器");
    }

    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("第一个过滤器执行过滤之前");
        filterChain.doFilter(servletRequest,servletResponse);
        System.out.println("第一个过滤操作之后");
    }

    public void destroy() {
        System.out.println("销毁第一个过滤器");
    }
}

Register the filter in the web.xml file, the configuration is as follows:

Register a filter named FirstFilter as follows, its class is in filter.myFilter, and define the corresponding mapping to filter all url paths.

    <filter>
        <filter-name>FirstFilter</filter-name>
        <filter-class>filter.myFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>FirstFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

You can also register the filter by means of annotations. You do not need to manually configure it in the web.xml file. The annotations are automatically configured and registered as filters by the web container during deployment. The following is the equivalent method through annotations

@WebFilter(filterName = "firstFilter",value = {"/*"},dispatcherTypes = {DispatcherType.REQUEST})
public class firstFilter implements Filter {
    ......
}

The common properties of WebFilter are as follows:

2. Filter chain

When multiple filters are defined in the accessed URL, the user request will pass through multiple filters in the order in which they are registered in web.xml. After the access is completed, the response will be nested and returned, and finally returned to the user. This sequence is similar to the stack operation, and comes out first.

For example, define the chain execution result of two filters:

3. Filter classification

When configuring the filter, the <dispatcher> option can be selected for four

Various types of page requests are filtered, namely request, forward, include, and error. Different types of filters will only filter requests of this type.

Request request is the default filter type of <dispatcher>, it will filter the request request of the page, direct request or redirection are both request type.

forward will filter forwarding page requests. Those that pass the forwar () function or <jsp: forward> actions are all forwarding operations. As shown below, call the forward () function in the index.jsp page to forward to the regPage.jsp page , Define a filter forwardFilter for regPage.jsp page forwarding operation, when the user accesses the regPage.jsp page with a forwarding operation, it will pass this filter, and output in the console: forwarding filter

//在index.jsp页面进行转发到regPage.jsp

servletRequest.getRequestDispatcher("regPage.jsp").forward(servletRequest,servletResponse);

//定义转发过滤器
public class forwardFilter implements Filter {
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        System.out.println("转发过滤器");
        chain.doFilter(req, resp);
    }

    public void init(FilterConfig config) throws ServletException {

    }

}
//注册转发过滤器,针对regPage.jsp页面的转发类型请求进行过滤
    <filter>
        <filter-name>ForwardFilter</filter-name>
        <filter-class>filter.forwardFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>ForwardFilter</filter-name>
        <url-pattern>/regPage.jsp</url-pattern>
        <dispatcher>FORWARD</dispatcher>
    </filter-mapping>

Similarly, include filters the page's include behavior, and operations using getDispatcher (). Include () or <jsp: include> are include behaviors.

The error type refers to the filter that jumps to the specified page after an error occurs on the page. The following defines the page to jump to the exception.jsp page after a 404 error occurs, before passing the ERROR type filter errorFilter

    <error-page>
        <error-code>404</error-code>
        <location>/exception.jsp</location>
    </error-page>
    <filter>
        <filter-name>errorFilter</filter-name>
        <filter-class>filter.errorFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>errorFilter</filter-name>
        <url-pattern>/exception.jsp</url-pattern>
        <dispatcher>ERROR</dispatcher>
    </filter-mapping>

4. Load configuration information

The filter init () function can load the configuration information of the <init-param> tag in the web.xml file.

For example, when a website filter loginFilter needs to judge whether the user is logged in, after the user logs in, the information will be saved to the session, and the session will be judged in the filter. If you are already logged in, you can continue to visit other pages, otherwise if you are not logged in You need to jump to the login.jsp page to log in. However, the filter should not filter the login.jsp and fail.jsp pages of the failed login page again, which will cause an endless loop. Therefore, the exception pages that do not need to be filtered are saved in web.xml in the form of initialization parameters, loaded in the filter init () function, and doFilter () is used to determine whether the current path is an exception, and if so, the request is released.

In order to prevent garbled characters in Chinese, you need to set the request encoding format on the page, but it is too troublesome to set it on each page. You can set the request encoding in the filter, so that as long as the encoding of the page after the filter will take effect. The encoding method can be specified in the web.xml file, and then loaded into the filter.

    <filter>
        <filter-name>loginFilter</filter-name>
        <filter-class>filter.loginFilter</filter-class>
        <init-param> <!--设置不需要过滤的路径-->
            <param-name>passPath</param-name>
            <param-value>login.jsp;fail.jsp</param-value>
        </init-param>
        <init-param>    <!--设置编码方式-->
            <param-name>charset</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>loginFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
public class loginFilter implements Filter {
    private FilterConfig config;        //设置配置参数变量

    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;

        //读取配置文件中的编码并设置
        String charset = config.getInitParameter("charset");
        if (charset != null)
            request.setCharacterEncoding(charset);

        //判断路径是否属于配置文件中规定的路径,如果是则无需验证,放行请求
        String passPath = config.getInitParameter("passPath");
        String[] paths = passPath.split(";");
        for (String path : paths) {                
            if (request.getRequestURI().indexOf(path) != -1) {
                chain.doFilter(req, resp);
                return;
            }
        }

        //检查session是否有用户名信息,有代表已经登录可以访问,否则跳转到登录页面
        if (request.getSession().getAttribute("username") != null)
            chain.doFilter(req, resp);
        else
            response.sendRedirect("login.jsp");
    }

    public void init(FilterConfig config) throws ServletException {
        this.config = config;     //在初始化时加载配置参数
    }

}

Listener

Listener is a special class defined in Servlet, used to listen to events such as creation, attribute modification or destruction of ServletContext, HttpSession and HttpRequest domain objects (corresponding to three fields of application, session and request of jsp, respectively) Perform the operation. Listeners are often used to monitor client requests and server-side operations, such as counting online people, visits, and loading initialization information.

1. Create a listener

The listener is essentially a Java servlet class, but it implements some methods of the Listerner interface, such as the initialized and destroyed methods of the ServletContextListener interface, which correspond to the calls when the servlet is created and destroyed.

public class FirstListener implements ServletContextListener{
    // Servlet要求保留无参构造器
    public FirstListener() {
    }

    // web应用servlet部署时调用此方法
    public void contextInitialized(ServletContextEvent sce) {     
    }

    // servlet销毁时调用
    public void contextDestroyed(ServletContextEvent sce) {
    }
}

Next, you need to register the listener in web.xml, which is located in the FirstListener under the listener package:

    <listener>
        <listener-class>listener.FirstListener</listener-class>
    </listener>

No registration is required after servlet3.0, but annotated, add a line before the listener class declaration: @WebListener ("Description")

The web application starts the listener in the order of registration in the web.xml file , and the listener is started first, then the filter, and finally the servlet is loaded

2. Classification of listeners

1. Creation and destruction of listening objects

According to the monitored objects, it is divided into three types of listeners: the entire application, the session, and the request. The corresponding interfaces need to implement three interfaces: ServletContextListener, HttpSessionListenter, and ServletRequestListener. Monitor the creation and destruction of corresponding objects. The getXxx () method of the parameter object passed in through the method can get the currently called object. For example, se.getSession () can get the current session object, and then operate the object through the listener.

For example, the initialization parameter is obtained through the Servlet listener and set as the global parameter of the servlet, so that the parameter can be obtained in the entire application later

    <context-param>
        <param-name>initParam</param-name>
        <param-value>初始化参数</param-value>
    </context-param>
    @Override   //servlet创建时调用
    public void contextInitialized(ServletContextEvent sce) {
        //获取servlet初始化参数
        String initParam =sce.getServletContext().getInitParameter("initParam");
        //设置全局servlet参数
        sce.getServletContext().setAttribute("init",initParam);
    }

    @Override    //servlet销毁时调用
    public void contextDestroyed(ServletContextEvent sce) {

    }

The following is the monitoring of session and request listener creation and destruction

package listener;

import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;


public class FirstListener implements HttpSessionListener, ServletRequestListener {

    //servlet要求保留空构造器
    public FirstListener() {
    }

    @Override       //创建session时调用
    public void sessionCreated(HttpSessionEvent se) {
        se.getSession();
    }

    @Override       //session销毁时调用
    public void sessionDestroyed(HttpSessionEvent se) {

    }

    @Override       //request对象创建时调用
    public void requestDestroyed(ServletRequestEvent sre) {

    }

    @Override       //request销毁时调用
    public void requestInitialized(ServletRequestEvent sre) {

    }
}

2. Change of monitoring property

It is used to monitor when the object attributes in Servlet, Session and Request are changed. The inherited interfaces are ServletContextAttributeListener,
        HttpSessionAttributeListener, ServletRequestAttributeListener. All three interfaces need to implement three methods: attributeAdded (), attributeRemoved (), attributeReplaced ( ), But the parameter object passed in is different, for example, the parameter object corresponding to the Servlet is ServletContextAttributeEvent scae. The rest of the usage is similar. For example, the following through the request attribute listener to monitor its attribute creation, change, and delete operations

package listener;

import javax.servlet.*;

public class AttributeListener implements ServletRequestAttributeListener {

    // Public constructor is required by servlet spec
    public AttributeListener() {
    }

    @Override
    public void attributeAdded(ServletRequestAttributeEvent srae) {
        System.out.println("request添加属性:"+srae.getName());
    }

    @Override
    public void attributeRemoved(ServletRequestAttributeEvent srae) {
        System.out.println("request删除属性:"+srae.getName());
    }

    @Override
    public void attributeReplaced(ServletRequestAttributeEvent srae) {
        System.out.println("request修改属性:"+srae.getName());
    }
}

//--------------------listener.jsp页面创建并修改request属性-----------------
    <%
        request.setAttribute("request属性","request参数");
        request.setAttribute("request属性","request参数2");
    %>

Session binding interface HttpSessionBindingListener, passivation interface HttpSessionActivationListener does not need to create a special listener, but can be inherited and implemented in ordinary JavaBean class, for example, a Student class implements these two interfaces, when a Student object is bound / Unbind into the session, the corresponding method will be triggered, and similarly the object will be triggered when it is passivated / activated. The following is the Student class:

package modules;

import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
import javax.servlet.http.HttpSessionEvent;

public class Student implements HttpSessionBindingListener, HttpSessionActivationListener {                  
    private String name;                
    private int age;

    public Student() {                   
    }

    public String getName() {          
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public void valueBound(HttpSessionBindingEvent event) {
        System.out.println("Session绑定User对象" + event.getName());
    }

    @Override
    public void valueUnbound(HttpSessionBindingEvent event) {
        System.out.println("Session解绑User对象" + event.getName());
    }

    @Override
    public void sessionWillPassivate(HttpSessionEvent se) {
        System.out.println("Session钝化对象:" + se.getSource());
    }

    @Override
    public void sessionDidActivate(HttpSessionEvent se) {
        System.out.println("Session活化对象:" + se.getSource());
    }
}

//-----------------在jsp页面内绑定、解绑Student对象------------------------
    <%
        Student s1=new Student();
        session.setAttribute("student",s1);    //输出:Session绑定User对象student
        session.removeAttribute("student");     //输出:Session解绑User对象student
    %>

 

Published 124 original articles · Like 65 · Visit 130,000+

Guess you like

Origin blog.csdn.net/theVicTory/article/details/104349287