Filter filter and Listener listener

2023.10.26

Filter filter

Filter, as the name suggests, filters things. The filter in the Web is to filter the request. By using the filter, we can intercept the request and then handle it accordingly to achieve many special functions. Such as login control, permission management, filtering sensitive words, etc.

Filter can add code before the target Servlet program is executed, or add code after the target Servlet is executed. Filtering rules can be added before and after. Under normal circumstances, common code is written in filters. Therefore, code reuse can be achieved through filters.

If multiple filters are applied to the same resource or the same group of resources, the calling order is more important. At this time, you need to configure the web.xml file to control the order.

How to implement a filter?

  • Write a Java class to implement an interface: jarkata.servlet.Filter. And implement all methods in this interface.
    • init method: called after the Filter object is first created, and only called once.
    • doFilter method: As long as the user sends a request, it will be executed once. If N requests are sent, it will be executed N times. Write filtering rules in this method.
    • destroy method: called before the Filter object is released/destroyed, and only called once.

  • Configure Filter in the web.xml file. This configuration is very similar to Servlet. You can also use the annotation @WebFilter

ps: The life cycle of Filter is basically the same as the declaration cycle of Servlet. The only difference is that by default, Servlet objects will not create new objects when the server starts. By default, the Filter object will create a new object when the server starts.

ps:The priority of Filter is inherently higher than that of Servlet.

  • Whether the target Servlet is executed depends on two conditions:

    • First: Whether the code: chain.doFilter(request, response); is written in the filter.

    • Second: Whether the request path sent by the user is consistent with the request path of the Servlet.

Filter filter use case:

First write a filter class to implement the Filter interface:

package filter;

import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;

import java.io.IOException;

@WebFilter("*.do")
public class filter1 implements Filter {

    public filter1() {
        System.out.println("Construction without parameters was executed");
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("init method executed");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("doFilter method executed");
        //Execute the next filter. If the next filter is not a filter, execute the target program Servlet.
        filterChain.doFilter(servletRequest,servletResponse);
        System.out.println("doFilter method execution ends");
    }

    @Override
    public void destroy() {
        System.out.println("destroy method executed");
    }
}

chain.doFilter(request, response); The function of this line of code: Execute the next filter. If there is no filter below, execute the final Servlet.

Write two servlet classes:

Aservlet:

package filter;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

@WebServlet("/a.do")
public class Aservlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Aservlet's doget method was executed.");
    }
}

Bservlet:

package filter;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

@WebServlet("/b.do")
public class Bservlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Bservlet's doget method was executed");
    }
}

Note that the paths corresponding to the two servlets must end with “.do” because the path set by the previous filter is “*.do”.

Then enter in the browser: http://localhost:8080/servlet09/a.do

The console output is as follows:

Then enter in the browser: http://localhost:8080/servlet09/b.do

The console output is as follows:

If there are multiple filters:

① If you configure it with annotations: the order of filter execution is based on the Filter class name. For example: FilterA and FilterB, FilterA is executed first. Filter1 and Filter2, Filter1 is executed first.

②When configuring in the web.xml file, the execution order of Filter is: from top to bottom.

Listener listener

Listener is one of the three major components of the Web, the other two are Servlet (controller) and Filter (filter).

Listener can listen to the three major domain objects in JavaWeb: HttpServletRequest, HttpSession, and ServletContext (created and destroyed). Once the monitored object changes accordingly, appropriate actions should be taken.

What listeners are provided in the Servlet specification?

  • Under the jakarta.servlet package:

    • ServletContextListener (called when the context object is created and destroyed, the same below)

    • ServletContextAttributeListener (called when the data in the context domain is modified, the same below)

    • ServletRequestListener

    • ServletRequestAttributeListener

  • Under the jakarta.servlet.http package:

    • HttpSessionListener

    • HttpSessionAttributeListener

      • The listener needs to be annotated with the @WebListener annotation.

      • What is this listener listening for? It is the change of data in the session field. As long as the data changes, the corresponding method is executed. The main monitoring point is on the session domain object.

    • HttpSessionBindingListener

      • This listener does not need to be annotated with @WebListener.

      • Assuming that the User class implements this listener, the bind event is triggered when the User object is put into the session, and the unbind event is triggered when the User object is deleted from the session.

      • Assuming that the Customer class does not implement this listener, the bind and unbind events will not be triggered when the Customer object is placed in or deleted from the session.

    • HttpSessionIdListener (not commonly used)

      • When the session id changes, the only method in the listener will be called.

    • HttpSessionActivationListener (not commonly used)

      • Monitors the passivation and activation of session objects.

      • Passivation: The session object is stored from memory to a hard disk file.

      • Activation: Restore the session from the hard disk file to the memory.

Steps to implement a listener:

Taking ServletContextListener as an example, first write a class to implement the ServletContextListener interface and implement the methods inside. Configure the ServletContextListener in the web.xml file, or use the annotation @WebListener. Annotations are used directly here, the code is as follows:

package listener;

import jakarta.servlet.ServletContextEvent;
import jakarta.servlet.ServletContextListener;
import jakarta.servlet.annotation.WebListener;

//The ServletContextListener listener mainly monitors: the status of the ServletContext object.
@WebListener
public class MyServletContextListener implements ServletContextListener {

    /**
     * Methods in the listener do not require programmers to call them manually. It is called by the server after a special event occurs.
     * @param sce
     */
    @Override
    public void contextInitialized(ServletContextEvent sce) { // Server startup time point, if you want to execute a piece of code at this time, just write it.
        // This method is called when the ServletContext object is created.
        System.out.println("ServletContext object created.");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) { // Server shutdown time.
        // Now you can write code at this special moment, just write it. It will be called automatically by the server.
        // This method is called when the ServletContext object is destroyed.
        System.out.println("ServletContext object was destroyed.");
    }
}

At this time, start the server and the console displays as follows:

Shut down the server and the console displays as follows: