I. Introduction filters
Filter depends on the filter servlet container
this is the interceptor can not do. In the Java Web, you incoming request, response filter out some advance information, or to set some parameters in advance, and then pass the servlet or
who struts of action for business logic, such as address filtering out illegal url (instead of login.do request, if the user is not logged are filtered out), or incoming servlet or struts
before the action unified character set, or to get rid of some of the illegal character (chat room often used some curse words). It is a linear filter process, after coming url, after checking,
can keep the original process continues downward, the next filter, the servlet receives.
Second, the role of the filter
Filter functions can be realized :
1) authorized user Filter: Filter responsible for checking the user request, filtered illegal request user upon request.
2) Log Filter: Detail Record some special user request.
3) responsible for decoding the Filter: decoding request including non-standard coding.
4) change the XML content XSLTFilter and so on.
Filter ways to achieve the above functions :
1) Before reaching the HttpServletRequest Servlet, intercept customers HttpServletRequest.
2) The need to check HttpServletRequest, may modify the header and data HttpServletRequest.
3) Before HttpServletResponse reach the client, intercepting HttpServletResponse.
4) The need to check HttpServletResponse, and data may be modified HttpServletResponse head.
Third, the filter implementation
SpringMVC framework is a mature excellent java web development framework, study design framework will help us better understand and grasp the spring MVC, design and write more in line with the structure and code.
This section is in the reading frame SpringMVC filter arranged to filter the encoding process is an example to learn how to set a filter in a frame.
FIG spring-web.jar packet structure shown above, Spring of the web package is provided with many filters, and these filters are located org.springframework.web.filter naturally achieve the javax.servlet.Filter,
But the way to achieve the following categories :
(1) direct implementation Filter, this type of filter is only CompositeFilter;
(2) extend the abstract class GenericFilterBean, such realization the javax.servlet.Filter, only one of this type of filters, i.e. for DelegatingFilterProxy;
(3) extend the abstract class OncePerRequestFilter, such as a direct subclass of GenericFilterBean, this type of filter comprises CharacterEncodingFilter, HiddenHttpMethodFilter, HttpPutFormContentFilter, RequestContextFilter and ShallowEtagHeaderFilter;
(4) extend the abstract class AbstractRequestLoggingFilter, such as a direct subclass of OncePerRequestFilter, this type of filter comprises CommonsRequestLoggingFilter, Log4jNestedDiagnosticContextFilter and ServletContextRequestLoggingFilter.
Filter on what position the container structure?
Before filter on web resources, web resources that it can reach the request application (it can be a Servlet, Jsp a page, or even an HTML page) before intercepting incoming requests and intercepted before it is returned to the client request output . Filter: used to intercept the request, in between the client and the requested resource, object code reuse. Filter chain, which first configuration in web.xml, which on the first call. You can also configure some initialization parameters in the filter.
Java is not a standard Filter Servlet, it can not handle the user request, the client can not generate a response. HttpServletRequest mainly used for pretreatment may be, HttpServletResponse post-treatment is a typical processing chain.
Create a Filter in just two steps :
(1) Filter processing class to create:
(2) disposed in web.xml Filter.
Create a Filter must implement javax.servlet.Filter defines three methods in the interface.
• void init (FilterConfig config): used to complete the Filter initialization.
• void destroy (): Filter for destruction before the complete recovery of certain resources.
• void doFilter (ServletRequest request, ServletResponse response, FilterChain chain): to achieve filtering, which is to increase in response to each request, and additional processing.
Filter filter also has the life cycle: init () -> doFilter () -> destroy (), driven by the filter element in the deployment file.
Referring encoding filter to see how to achieve exemplary
<!-- 编码处理过滤器 --> <filter> <filter-name>encodingFilter</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> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>*.do</url-pattern> </filter-mapping>
Wherein, filter-class is a class filter Filter, init-prama injection parameter is set
url-pattern Filter-mapping the type of filtering url
The class hierarchy
CharacterEncodingFilter r class inherits OncePerRequestFilter class
public class CharacterEncodingFilter extends OncePerRequestFilter
The OncePerRequestFilter class also inherited the GenericFilterBean class
public abstract class OncePerRequestFilter extends GenericFilterBean
public abstract class GenericFilterBean implements
Filter, BeanNameAware, EnvironmentAware, ServletContextAware, InitializingBean, DisposableBean
Encoded code disposed core
@Override protected void doFilterInternal( HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { if (this.encoding != null && (this.forceEncoding || request.getCharacterEncoding() == null)) { request.setCharacterEncoding(this.encoding); if (this.forceEncoding) { response.setCharacterEncoding(this.encoding); } } filterChain.doFilter(request, response); }
Wherein a filter filterChain chain, represents the next filter then performed after the completion of the implementation of this filter
the difference
When we use a filter, usually do not need to know GenericFilterBean, OncePerRequestFilter and AbstractRequestLoggingFilter, but does not prevent us understand these categories, in respect of the above, AbstractRequestLoggingFilter inherited from OncePerRequestFilter, OncePerRequestFilter inherited from GenericFilterBean, so we know, genericFilterBean is a more convenient type of filter any super class that is implemented to obtain the value of the main init-param set from web.xml file, then initialize filter (of course, which can override the init method subclasses ).
OncePerRequestFilter inherited from GenericFilterBean, it will know how to acquire properties and their values in the configuration file, so the focus is not on value, but rather to ensure that, after receiving a request, each filter is performed only once, its subclasses Filter only need to focus on the specific implementation that is doFilterInternal.
AbstractRequestLoggingFilter is an extension of OncePerRequestFilter, which in addition to all the features of the genetic parent class and the ancestor class, but also doFilterInternal decided the filter before and after the execution of the event, its subclasses concerned with beforeRequest and afterRequest.
Overall, these three categories are a part of the functions performed Filter, of course, the specific implementation of provisions by their subclasses, if you need to implement own filters, you may be required according to the above inheritance class.
Custom filter
Same name parameter setting method may be set automatically initialized
package com.my.dm.filter; import java.io.IOException; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.web.filter.OncePerRequestFilter; public class TestFilter extends OncePerRequestFilter{ private Logger logger =LogManager.getLogger(TestFilter.class); private String demo; /** * @return the demo */ public String getDemo() { return demo; } /** * @param demo the demo to set */ public void setDemo(String demo) { this.demo = demo; } @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { // TODO Auto-generated method stub // 请求的uri String url = request.getRequestURI(); String hoString = request.getRemoteHost(); String ip = getIPAddress(request); logger.info("url : " + url); logger.info("ip : " + ip); logger.info("demo : " + demo); // forwards the request to the destination the FilterChain.doFilter (Request, Response); } public void the destroy () { } public void the init () { } // Get real IP public static String getIPAddress (the HttpServletRequest Request) { String = null IP ; // the X-Forwarded-the For-: Squid service agent String = IPAddresses request.getHeader ( "the X-Forwarded-the For-"); IF (IPAddresses == null || ipAddresses.length () == 0 || "Unknown." equalsIgnoreCase (IPAddresses)) { // the proxy-Client the IP-: Apache service proxy IPAddresses = request.getHeader ( "the proxy-Client-the IP"); } if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) { //WL-Proxy-Client-IP:weblogic 服务代理 ipAddresses = request.getHeader("WL-Proxy-Client-IP"); } if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) { //HTTP_CLIENT_IP:有些代理服务器 ipAddresses = request.getHeader("HTTP_CLIENT_IP"); } if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) { //X-Real-IP:nginx服务代理 ipAddresses = request.getHeader("X-Real-IP"); } // Some networks via multi-layer proxy, then get to the ip there will be more, are generally separated by a comma (,), and the first to be true ip IP client if (ipAddresses! = Null && ipAddresses ! .length () = 0) { IP = ipAddresses.split ( ",") [0]; } // still not obtained, and finally by request.getRemoteAddr (); Get if (ip == null || ip .length () == 0 || "Unknown" .equalsIgnoreCase (IPAddresses)) { IP = request.getRemoteAddr (); } return ip.equals ( "0: 0: 0: 0: 0: 0: 0:. 1" ) "127.0.0.1":? ip; } }
<!-- 获取登陆者信息 --> <filter> <filter-name>testFilter</filter-name> <filter-class>com.my.dm.filter.TestFilter</filter-class> <init-param> <param-name>demo</param-name> <param-value>112.2.36</param-value> </init-param> </filter> <filter-mapping> <filter-name>testFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
[21:31:48:620] [INFO] - url : /dm/device/toUploadFile - com.my.dm.filter.TestFilter.doFilterInternal(TestFilter.java:46) [21:31:48:641] [INFO] - ip : 127.0.0.1 - com.my.dm.filter.TestFilter.doFilterInternal(TestFilter.java:47) [21:31:48:641] [INFO] - demo : 112.2.36 - com.my.dm.filter.TestFilter.doFilterInternal(TestFilter.java:49)
Since the main reference:
https://www.cnblogs.com/lukelook/p/11079113.html
https://www.jianshu.com/p/82ae825b849b