Home >Java >javaTutorial >Detailed explanation of Filter in Java

Detailed explanation of Filter in Java

高洛峰
高洛峰Original
2017-02-08 11:41:051612browse

Filter Introduction

Filter is also called a filter. It is the most practical technology in Servlet technology. WEB developers use Filter technology to manage all web resources managed by the web server: such as Jsp, Servlet, Intercept static image files or static html files to achieve some special functions. For example, some advanced functions such as URL-level permission access control, sensitive vocabulary filtering, and response information compression can be implemented.

It is mainly used to pre-process user requests and can also post-process HttpServletResponse. The complete process of using Filter: Filter pre-processes the user request, then hands the request to Servlet for processing and generates a response, and finally Filter post-processes the server response.

Filter function

Intercepts the client's HttpServletRequest before the HttpServletRequest reaches the Servlet. Check the HttpServletRequest as needed and modify the HttpServletRequest header and data.

Intercept HttpServletResponse before it reaches the client. Check HttpServletResponse as needed and modify the HttpServletResponse header and data.

How to implement the interception function with the help of Filter

There is a doFilter method in the Filter interface. When the developer writes the Filter and configures which web resource to intercept, the WEB server will call the web resource every time. Before calling the service method of the resource, the doFilter method of the filter will be called first. Therefore, writing code in this method can achieve the following purposes:

Let a piece of code execute before calling the target resource.

Whether to call the target resource (that is, whether to allow users to access web resources).

When the web server calls the doFilter method, it will pass in a filterChain object. The filterChain object is the most important object in the filter interface. It also provides a doFilter method. Developers can decide whether to call this based on their needs. Method, when this method is called, the web server will call the service method of the web resource, that is, the web resource will be accessed, otherwise the web resource will not be accessed.

Filter development in two steps

Write a java class to implement the Filter interface and implement its doFilter method.

Use and elements in the web.xml file to register the written filter class and set the resources it can intercept.

Introduction to each node in web.xml configuration:

Specify a filter.

is used to specify a name for the filter. The content of this element cannot be empty. The

element is used to specify the fully qualified class name of the filter.

The element is used to specify initialization parameters for the filter. Its sub-element specifies the name of the parameter, and specifies the value of the parameter.

In the filter, you can use the FilterConfig interface object to access the initialization parameters.

The element is used to set the resources that a Filter is responsible for intercepting. The resources intercepted by a Filter can be specified in two ways: Servlet name and request path for resource access.

sub-element is used to set the registered name of the filter. This value must be the name of the filter declared in the element

Set the request path intercepted by the filter (the URL pattern associated with the filter)

Specifies the name of the Servlet intercepted by the filter.

Specifies the way in which the resources intercepted by the filter are called by the Servlet container. It can be one of REQUEST, INCLUDE, FORWARD and ERROR. The default is REQUEST. Users can set multiple sub-elements to specify Filter to intercept multiple calling methods of resources.

The values ​​that can be set by sub-elements and their meaning

REQUEST: When the user directly accesses the page, the web container will call the filter. If the target resource is accessed through the RequestDispatcher's include() or forward() method, then this filter will not be called.

INCLUDE: If the target resource is accessed through the include() method of RequestDispatcher, then this filter will be called. Otherwise, the filter is not called.

FORWARD: If the target resource is accessed through the forward() method of RequestDispatcher, then this filter will be called. Otherwise, the filter will not be called.

ERROR: If the target resource is called through the declarative exception handling mechanism, then this filter will be called. Otherwise, the filter will not be called.

Filter chain

In a web application, multiple Filters can be developed and written. The combination of these Filters is called a Filter chain.

The web server determines which Filter to call first based on the registration order of the Filter in the web.xml file. When the doFilter method of the first Filter is called, the web server will create a FilterChain object representing the Filter chain and pass it Give the method. In the doFilter method, if the developer calls the doFilter method of the FilterChain object, the web server will check whether there is another filter in the FilterChain object. If there is, the second filter will be called. If not, the target resource will be called.

Filter life cycle

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

Like the Servlet program we wrote, the creation and destruction of Filter is the responsibility of the WEB server. When the web application starts, the web server will create an instance object of Filter, call its init method, read the web.xml configuration, and complete the initialization function of the object, thereby preparing for interception of subsequent user requests (the filter object only will be created once, and the init method will only be executed once). Developers can obtain the FilterConfig object representing the current filter configuration information through the parameters of the init method.

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException;//拦截请求

This method completes the actual filtering operation. When the client requests access to the URL associated with the filter, the Servlet filter will first execute the doFilter method. The FilterChain parameter is used to access subsequent filters.

public void destroy();//销毁

Filter objects will reside in memory after creation and will be destroyed when the web application is removed or the server is stopped. Called before the web container unloads the Filter object. This method is only executed once in the Filter's life cycle. In this method, resources used by the filter can be released.

FilterConfig interface

When configuring the filter, the user can configure some initialization parameters for the filter. When the web container instantiates the Filter object and calls its init method, the filter initialization parameters will be encapsulated. The filterConfig object is passed in. Therefore, when developers write filters, they can obtain the following content through the method of the filterConfig object:

String getFilterName();//得到filter的名称。 String getInitParameter(String name);//返回在部署描述中指定名称的初始化参数的值。如果不存在返回null. Enumeration getInitParameterNames();//返回过滤器的所有初始化参数的名字的枚举集合。 public ServletContext getServletContext();//返回Servlet上下文对象的引用。

Filter use case

Use Filter to verify user login security control

Previous paragraph Time is involved in maintaining a project. After the user logs out of the system, he goes to the address bar to access the history. According to the URL, he can still enter the system response page. I checked and found that the request was not filtered to verify user login. Add a filter to solve the problem!

First configure in web.xml

<filter>
    <filter-name>SessionFilter</filter-name>
    <filter-class>com.action.login.SessionFilter</filter-class>
    <init-param>
        <param-name>logonStrings</param-name><!-- 对登录页面不进行过滤 -->
        <param-value>/project/index.jsp;login.do</param-value>
    </init-param>
    <init-param>
        <param-name>includeStrings</param-name><!-- 只对指定过滤参数后缀进行过滤 -->
        <param-value>.do;.jsp</param-value>
    </init-param>
    <init-param>
        <param-name>redirectPath</param-name><!-- 未通过跳转到登录界面 -->
        <param-value>/index.jsp</param-value>
    </init-param>
    <init-param>
        <param-name>disabletestfilter</param-name><!-- Y:过滤无效 -->
        <param-value>N</param-value>
    </init-param></filter><filter-mapping>
    <filter-name>SessionFilter</filter-name>
    <url-pattern>/*</url-pattern></filter-mapping>

Then write FilterServlet.java:

package com.action.login;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;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpServletResponseWrapper;/**
 *    判断用户是否登录,未登录则退出系统
 */public class SessionFilter implements Filter {    public FilterConfig config;    public void destroy() {        this.config = null;
    }    public static boolean isContains(String container, String[] regx) {        boolean result = false;        for (int i = 0; i < regx.length; i++) {            if (container.indexOf(regx[i]) != -1) {                return true;
            }
        }        return result;
    }    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest hrequest = (HttpServletRequest)request;
        HttpServletResponseWrapper wrapper = new HttpServletResponseWrapper((HttpServletResponse) response);

        String logonStrings = config.getInitParameter("logonStrings");        // 登录登陆页面
        String includeStrings = config.getInitParameter("includeStrings");    // 过滤资源后缀参数
        String redirectPath = hrequest.getContextPath() + config.getInitParameter("redirectPath");// 没有登陆转向页面
        String disabletestfilter = config.getInitParameter("disabletestfilter");// 过滤器是否有效

        if (disabletestfilter.toUpperCase().equals("Y")) {    // 过滤无效
            chain.doFilter(request, response);            return;
        }
        String[] logonList = logonStrings.split(";");
        String[] includeList = includeStrings.split(";");        if (!this.isContains(hrequest.getRequestURI(), includeList)) {// 只对指定过滤参数后缀进行过滤
            chain.doFilter(request, response);            return;
        }        if (this.isContains(hrequest.getRequestURI(), logonList)) {// 对登录页面不进行过滤
            chain.doFilter(request, response);            return;
        }

        String user = ( String ) hrequest.getSession().getAttribute("useronly");//判断用户是否登录
        if (user == null) {
            wrapper.sendRedirect(redirectPath);            return;
        }else {
            chain.doFilter(request, response);            return;
        }
    }    public void init(FilterConfig filterConfig) throws ServletException {
        config = filterConfig;
    }
}

In this way, all requests to the user can be completed, and user login must be verified through this Filter .

Prevent Chinese garbled characters filter

When the project uses the spring framework. When different character sets are used for encoding in the front-end JSP page and JAVA code, the data submitted by the form or the Chinese name file uploaded/downloaded will be garbled, so you can use this filter.

<filter>
    <filter-name>encoding</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name><!--用来指定一个具体的字符集-->
        <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
        <param-name>forceEncoding</param-name><!--true:无论request是否指定了字符集,都是用encoding;false:如果request已指定一个字符集,则不使用encoding-->
        <param-value>false</param-value>
    </init-param></filter><filter-mapping>
    <filter-name>encoding</filter-name>
    <url-pattern>/*</url-pattern></filter-mapping>

Spring+Hibernate's OpenSessionInViewFilter controls the session switch

When hibernate+spring is used together, if lazy=true (lazy loading) is set, then when reading data, After reading the parent data, hibernate will automatically close the session. In this way, when you want to use the data associated with it and the child data, the system will throw a lazyinit error. In this case, you need to use the OpenSessionInViewFilter filter provided by spring.

OpenSessionInViewFilter mainly maintains the Session state until the request sends all pages to the client, and does not close the session until the request is completed, thus solving the problems caused by delayed loading.

Note: OpenSessionInViewFilter configuration should be written in front of struts2 configuration. Because the tomcat container loads filters in order. If the configuration file writes the struts2 filter configuration first, and then the OpenSessionInViewFilter filter configuration, the loading order causes the session to be disconnected when the action obtains the data. Not managed by spring.

<filter><!-- lazy loading enabled in spring -->
    <filter-name>OpenSessionInViewFilter</filter-name>
    <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
    <init-param>
        <param-name>sessionFactoryBeanName</param-name><!-- 可缺省。默认是从spring容器中找id为sessionFactory的bean,如果id不为sessionFactory,则需要配置如下,此处SessionFactory为spring容器中的bean。 -->
        <param-value>sessionFactory</param-value>
    </init-param>
    <init-param>
        <param-name>singleSession</param-name><!-- singleSession默认为true,若设为false则等于没用OpenSessionInView -->
        <param-value>true</param-value>
    </init-param></filter><filter-mapping>
    <filter-name>OpenSessionInViewFilter</filter-name>
    <url-pattern>*.do</url-pattern></filter-mapping>

Web.xml configuration of Struts2

Using Struts2 in the project also requires configuring filters in web.xml to intercept requests and transfer them to Struts2 Action for processing.

Note: If the Struts2 version is before 2.1.3, the filter uses org.apache.struts2.dispatcher.FilterDispatcher. Otherwise use org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter. Starting from Struts2.1.3, the ActionContextCleanUp filter will be abandoned and the corresponding functionality will be included in the StrutsPrepareAndExecuteFilter filter.

Three initialization parameter configurations:

config parameter: Specify the configuration file to be loaded. Comma separated.

actionPackages parameter: Specify the package space where the Action class is located. Comma separated.

configProviders parameter: Custom configuration file provider, which needs to implement the ConfigurationProvider interface class. Comma separated.

<!-- struts 2.x filter --><filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class></filter><filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>*.do</url-pattern></filter-mapping>

For more detailed explanations of Filter in Java and related articles, please pay attention to the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn