Talking about the java filter Filter <the most understandable explanation>

I. Brief Introduction

Filter in Servlet is a server-side program that implements javax.servlet.Filter interface. Its main purpose is to filter character encoding and make some business logic judgments, such as access to pages. Its working principle is that as long as you configure the web.xml file to intercept client requests, it will help you intercept requests, at this time you can unify the request or response (Request, Response) coding, simplify the operation; at the same time, you can make logical judgments, such as whether the user has logged in, whether or not access to the request. Pages and so on. It starts with the start of your web application, initializes only once, and then intercepts related requests. It is only destroyed when your web application stops or redeploys. Here's a code example to see how it works.
2. Code examples

package test.filter; 
import ...; 
/**
 * Introduce the use of filter, take setting code as an example
 */
public class MyFilter implements Filter { 
  private FilterConfig config = null; 
  private boolean isFilter = false;
  
  public void destroy() { 
   System.out.println("MyFilter Prepare for destruction..."); 
  } 
  
  public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain chain) throws IOException, ServletException { 
   // Mandatory Type Conversion 
   HttpServletRequest request = (HttpServletRequest)arg0; 
   HttpServletResponse response = (HttpServletResponse)arg1; 
   // Get the encoding set of web.xm settings and set it to Request and Response   
   request.setCharacterEncoding(config.getInitParameter("charset"));   
   response.setContentType(config.getInitParameter("contentType"));   
   response.setCharacterEncoding(config.getInitParameter("charset"));   
   // Forward the request to the destination to continue execution
   chain.doFilter(request, response);
  } 
  
  public void init(FilterConfig arg0) throws ServletException { 
   this.config = arg0; 
   if(isFilter){
      System.out.println("MyFilter Initialization..."); 
   }
  } 
  
  private void setIsFilter(boolean isFilter){
	this.isFilter = isFilter;
  }
}

Then configure the filter in web. xml:

 <filter>
 	<filter-name>MyFilter</filter-name>
 	<filter-class>test.filter.MyFilter</filter-class>
 	<init-param>
 		<param-name>isFilter</param-name>
 		<param-value>true</param-value>
 	</init-param>
 </filter>
 <filter-mapping>
 	<filter-name>MyFilter</filter-name>
 	<url-pattern>/*</url-pattern>
 	<dispatcher>REQUEST</dispatcher> <!-- No configuration dispatcher Is the default request Modal -->
 	<dispatcher>FORWARD</dispatcher>
 	<dispatcher>ERROR</dispatcher>
 	<dispatcher>INCLUDE</dispatcher>
 </filt

3. Detailed introduction

What do you usually do in the doFilter method?

1. By controlling the invocation of the chain.doFilter method, we can decide whether we need to access the target resources.

For example, you can verify user rights and so on. Determine whether the user has access to certain resources, have permission to release, do not execute the chain.doFilter method without permission.
2. Before calling the chain.doFilter method, do some processing to achieve some purpose.
For example, to solve the problem of Chinese random code and so on. Before the doFilter method, you can execute the encoding that sets the request encoding and response. The request interface can even be encapsulated and decorated to deal with the Chinese scrambling of get request (rewriting the corresponding request.getParameter method).
3. After calling the chain.doFilter method, do some processing to achieve certain purposes.
For example, compress the whole web site. Before calling the chain.doFilter method, the response object is encapsulated and decorated with class A, rewriting getOutputStream and getWriter methods. Within Class A, the output content is cached into the ByteArray OutputStream stream. After the chain.doFilter method is executed, the ByteArray OutputStream stream in Class A is cached and compressed with the GZIPOutputStream stream.

Filter can not only specify which url-pattern matching resources to intercept through url-pattern. You can also specify which specific servlet to intercept by servlet-name (specifically for a servlet, which corresponds to the configuration of the servlet).

The dispatcher in the filter-mapping tag specifies how the resources intercepted by the filter are invoked by the Servlet container, which can be REQUEST,INCLUDE,FORWARD and ERROR, default REQUEST. Users can set up multiple <dispatcher> sub-elements to specify how Filter intercepts multiple calls to resources.

REQUEST:

When the user accesses the page directly, the Web container will call the filter. If the target resource is accessed through the include() or forward() method of RequestDispatcher or in an ERROR case, the filter will not be invoked.

INCLUDE:

If the target resource is accessed through the include() method of RequestDispatcher, the filter will be invoked. In addition, the filter will not be called.

FORWARD:

If the target resource is accessed through the forward() method of RequestDispatcher, the filter will be invoked, otherwise, the filter will not be invoked.

ERROR:

If the error attribute = examError.jsp is specified in the page instruction of A.jsp page, if an exception occurs in A.jsp, it will jump to examError.jsp for processing. When you jump to examError.jsp, if the filter is configured with dispather of ERROR, it will intercept, otherwise it will not intercept.
4. Advanced Configuration (Allowing Agents to Inject Spring Beans)

Configure the filter DelegatingFilterProxy in web.xml:

<filter>
    <filter-name>permission</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    <init-param>
        <param-name>targetFilterLifecycle</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>
 <filter-mapping>
    <filter-name>permission</filter-name>
    <url-pattern>*.htm</url-pattern>
</filter-mapping>

Add in the spring bean configuration:

<bean id="permission" class="Your bean"></bean>

The id of the bean must be the same as filter-name. If you want to be different, you can configure it as follows:

<filter>
    <filter-name>permission</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
     <init-param>
        <param-name>targetFilterLifecycle</param-name>
        <param-value>true</param-value>
    </init-param>
    <init-param>
        <param-name>targetBeanName</param-name>
        <param-value>test</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>permission</filter-name>
    <url-pattern>*.htm</url-pattern>
</filter-mapping>

Add in the spring bean configuration:

<bean id="test" class="Your bean"></bean>

The above spring bean s must implement the Filter interface.

So what's the reason for this?

Answer: In this way, the filter represented by Delegating FilterProxy can be used as spring bean and managed by spring, that is, the life cycle of the filter can be managed by the Spring container. Moreover, if some instances of Spring container are needed in the filter, they can be injected directly through spring, and some configuration files can be read. These convenient operations can be configured and implemented through Spring.

If "targetFilterLifecycle" is set to True, then Filter.init() and Filter.destroy() are valid; if false, the two methods fail.

If you use Shiro (a powerful and easy-to-use Java security framework that performs authentication, authorization, cryptography, session management, etc.), you will usually use this Delegating Filter Proxy!

Keywords: Programming Spring JSP encoding xml

Added by blckspder on Fri, 23 Aug 2019 10:54:12 +0300