Javaweb has three major components, Servlet has been briefly introduced, frankly speaking, it is actually a class that we use to process specific business logic, need to go through certain configuration and rules to access, then this article will look at the other two components.

Filter

Let’s look at the definition of Filter. A filter is an object that performs filtering tasks on either the request to a resource (a servlet or static content), or on the response from a resource, or both. This is the definition in Java Doc, it is used to perform any request and response filtering and interception task, it is a reusable technology, can work on dynamic and static resources, can add one or more filter chains into the container, and a filter chain can be broken. As long as the doFilter () method is executed, it does not go to the next chain. Bluntly said before is any a request to the servlet can through one or more Filter, support change requests the first information, also can do some other things, of course, can be roughly divided into general functional certification (such as checking identity), security (such as XSS intercept), log buried point, data encryption, set up the coding work front. Any response may pass through one or more filters before it is returned to the client, such as recording the elapsed time of the request.

default public void init(FilterConfig filterConfig) throws ServletException {}

public void doFilter(ServletRequest request, ServletResponse response,
                     FilterChain chain)
        throws IOException, ServletException;

default public void destroy() {}
Copy the code

The init method is similar to the init() method of the Servlet. It is called by the container, and the container will pass in a specific FilterConfig based on the configuration, such as the initialization parameters, and the order in which the init is executed. DoFilter is the detailed implementation of our specific operations. Generally, when we need to declare a Filter, we only need to rewrite doFilter to meet the requirements. See an example

public class LogFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException  { System.out.println("logFilter init..." ); Filter.super.init(filterConfig); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { if (request instanceof HttpServletRequest && response instanceof HttpServletResponse) { System.out.println("http request"); Chain. DoFilter (request, response); // If the request is not satisfied, do not call this method to terminate the request. } } @Override public void destroy() { Filter.super.destroy(); }}Copy the code

Simply declare a Filter that prints logs. The difference is that the implementation of doFilter will be more complex, such as identifying URIs, HttpMethods, persistence, etc., but the overall flow will be the same. Note that we can specify the scope of a Filter, such as specifying requests to servlets or static resources that the Filter will intercept. In web.xml this is done using

. However, the < urL-pattern > tag in a

can only specify one matching rule, so you can declare multiple

to declare multiple matching rules, as long as their names refer to the same filter, like this


<filter>
  <filter-name>logFilter</filter-name>
  <filter-class>me.ppx.mvc.filter.LogFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>logFilter</filter-name>
  <url-pattern>*.jsp</url-pattern>
</filter-mapping>
<filter-mapping>
  <filter-name>logFilter</filter-name>
  <url-pattern>*.do</url-pattern>
</filter-mapping>
Copy the code

But to familiarize you with the days before web.xml, I’m going to register the Filter as a dynamic registry

public class AnimalServletContainerInitializer implements ServletContainerInitializer { @Override public void onStartup(Set<Class<? > > c, ServletContext CTX) {/ / manual registration servlet ServletRegistration. Dynamic servlet. = CTX addServlet (" initializerServlet ", new HttpServlet() { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {system.out.println (" this is registered programmatically "); }}); servlet.addMapping("/init"); / / register manually Filter FilterRegistration. Dynamic Filter = CTX. AddFilter (" logFilter, "new logFilter ()); // dispatchertype. REQUEST indicates requests directly from the client filter.addMappingForServletNames(EnumSet.of(DispatcherType.REQUEST),true,"initializerServlet"); // filter.addMappingForUrlPatterns(); }}Copy the code

Use ServletContext register their Filter, addMappingForServletNames method is used to register matching rules at the same time, this method is by specifying the name of the servlet, you can write more, It takes a variable string argument, and of course you can register a matching rule using the addMappingForUrlPatterns method, which specifies the URL, which is a collection type argument, depending on what you want. In addition, The Servlet3.1 specification states that the Service method must run in the same thread as all filters applied to the servlet.

Listener

The listener is notified of something happening in the Web container, and we override the listener to do something else when something interesting happens. There are several listeners specified in the Sevlet3.1 specification, and I’ll choose one that will be helpful for subsequent understanding.

  • ServletContextListener

It is a life-cycle event that occurs when the Servlet context is created, the init method of Filter is executed after the method is executed, or the Servlet context is about to close

Public interface ServletContextListener extends EventListener {// Just created default public void Default public void contextDestroyed(ServletContextEvent sce) {}}Copy the code

The contextInitialized method is executed before any filters and servlets are initialized. Remember that the Servlet specification explicitly specifies that only ServletContainerInitiali can be used to register servlets and filters programmatically Zer onStartup method of registered or ServletContainerInitializer contextInitialized, only demonstrated in front of the first, you can now demonstrate the second

public class PPXServletContextListener implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { System.out.println("context init..." ); ServletContext context = sce.getServletContext(); ServletRegistration.Dynamic servlet = context.addServlet("ppxlistener", new HttpServlet() { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {system.out.println (" Listener requested "); } @override public void init() throws ServletException {system.out.println (" register with ServletContextListener "); }}); servlet.setLoadOnStartup(3); servlet.addMapping("/listen"); } @Override public void contextDestroyed(ServletContextEvent sce) { ServletContextListener.super.contextDestroyed(sce); }}Copy the code

Now there is almost nothing in web.xml. So far, nothing is needed except for the listener. This is just an evolution

<listener>
    <listener-class>me.ppx.mvc.initializer.listener.PPXServletContextListener</listener-class>
</listener>
Copy the code

Then start the container directly. Note that in web. XML, listener>filter>servlet, otherwise an error will be reported. You don’t have to worry about that if you register programmatically, so it’s kind of convenient for us developers

conclusion

This is the end of the introduction to servlets. My intention is not to give you a detailed introduction to the use and details of servlets, but to give you an impression of what the earliest web development was like, even though servlets are no longer directly used for Web development. We also need to understand its core features, which will be very helpful for our subsequent understanding of SpringMVC and SpringBoot, after all, they are optimized on this basis. My ability is limited, if there is a mistake in the place please comment correct, thank you.