Java8设计模式最佳实战-设计模式概述(第六天学习记录)

Implementing the intercepting filter pattern using Java EE 8

To implement this pattern with the best practices of Java EE 8, we will use the servlet filter
为了用javaee8的最佳实践来实现这个模式,我们将使用servlet过滤器
from the Java Servlet specification. With the servlet filter, we can create an ordered request
来自Javaservlet规范。使用servlet过滤器,我们可以创建一个有序的请求
interceptor to treat the requests and responses. These interceptors are mapped by the URL
拦截器来处理请求和响应。这些拦截器由URL映射
pattern or servlet name. The servlet filter can be configured with XML (on web.xml) or
模式或servlet名称。servlet过滤器可以配置为XML(onweb.xml文件)或者
annotation. In our case, we will imagine that we want to create a log of all the requests that
注解。在我们的例子中,我们假设我们想要创建一个日志,记录所有请求
are sent to the server. We will also have two filters—one to log the access time and another
发送到服务器。我们还将有两个过滤器,一个记录访问时间,另一个
to log the information about the browser that the client is using. To log the access time, we
记录有关客户端正在使用的浏览器的信息。为了记录访问时间,我们
will create a filter called LogAccessFilter, and to log the browser information we will
我们将创建一个名为LogAccessFilter
create a filter called LogBrowserFilter.
创建一个名为LogBrowserFilter的筛选器来过滤浏览器信息。

Implementing LogAccessFilter

Here, we have the implementation of LogAccessFilter:

package com.gary.book.chapter01;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Date;

@WebFilter(filterName = "LogAccess", urlPatterns = "/*")
public class LogAccessFilter implements javax.servlet.Filter {
    
    
    private static Logger logger =
            LogManager.getLogger(LogAccess.class);

    public void destroy() {
    
    
    }

    public void doFilter(javax.servlet.ServletRequest req,
                         javax.servlet.ServletResponse resp, javax.servlet.FilterChain
                                 chain) throws javax.servlet.ServletException, IOException {
    
    
        //Gets the initial date of request.
        Date dateInitRequest = new Date();
        //Get IP of Client that sent a resquest.
        String ip = ((HttpServletRequest) req).getRemoteAddr();
        //Following to next filter. If none next filter exist, follows
        //for main logic.
        chain.doFilter(req, resp);
        //Gets the end date of request.
        Date dateEndRequest = new Date();
        //Logging the informations of IP and access time.
        logger.info("IP: " + ip + " Access time : "
                + Long.toString(dateEndRequest.getTime()
                - dateInitRequest.getTime())
                + " ms");
    }

    public void init(javax.servlet.FilterConfig config) throws
            javax.servlet.ServletException {
    
    
    }
}

As we can see in the code, to create one servlet filter, we need to create a class that
正如我们在代码中看到的,要创建一个servlet过滤器,我们需要创建一个类
extends javax.servlet.Filter and puts the @WebFilter annotation with filterName
继承javax.servlet.Filter并将@WebFilter注释与filterName放在一起
and urlPatterns parameters, which define the filter name and the URLs to filter, before
和urlPatterns参数,它们定义了过滤器名称和要过滤的url
the definition of class. The following is a snippet of code that demonstrates how to do that
class的定义。下面是一段代码,演示了如何做到这一点

@WebFilter(filterName = "LogAccess", urlPatterns = "/*")
public class LogAccessFilter implements javax.servlet.Filter{
    
    
 ...
}

Note that the servlet filter uses the chain of responsibility pattern to walk throughout the
注意,servlet过滤器使用责任链模式遍历整个
filters (objects that are servlet filter). The following is a snippet of code that uses a chain of
过滤器(servlet过滤器对象)。以下是使用
responsibility pattern:
责任模式:

chain.doFilter(req, resp);

In the preceding line of code, we established the filter name as LogAccess through
在前面的代码行中,我们将过滤器名称设置为LogAccess through
the filterName parameter. This will filter all requests, because
filterName参数。这将过滤所有请求,因为
the urlPatterns parameter has the "/" value. If we filter according to servlet name, we
urlPatterns参数具有“/
”值。如果我们根据servlet名称进行过滤,那么
need to use the following annotation:
需要使用以下注释:

//Servlet1 and Servlet2 are the servlets to filter.
@WebFilter(filterName = "LogAccess", servletNames =
{
    
    "servlet1","servlet2"})

The doFilter method is responsible for pre-processing and post-processing and
doFilter方法负责前处理和后处理以及
establishes when to follow the request to the next filter or servlet (main logic). To follow the
确定何时跟踪请求到下一个过滤器或servlet(主逻辑)。跟随
request to the next filter or servlet, the following code needs be executed:
请求下一个筛选器或servlet时,需要执行以下代码:

//Following to next filter or servlet.
chain.doFilter(req, resp);

When the preceding code is executed, the current filter executes only the next line when the
当执行前面的代码时,当前筛选器只执行下一行
other filters and servlets finish their processing.
其他过滤器和servlet完成它们的处理。

Implementing LogBrowserFilter

The implementation of LogBrowserFilter is as follows:

package com.gary.book.chapter01;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

@WebFilter(filterName = "LogBrowser", urlPatterns = "/*")
public class LogBrowserFilter implements Filter {
    
    
    private static Logger logger = LogManager.getLogger(LogBrowser.class);

    public void destroy() {
    
    
    }

    public void doFilter(ServletRequest req, ServletResponse resp,
                         FilterChain chain) throws ServletException, IOException {
    
    
        //Get userAgent that contain browse informations.
        String userAgent = ((HttpServletRequest) req).getHeader("UserAgent");
        //Get IP of Client that sent a resquest.
        String ip = ((HttpServletRequest) req).getRemoteAddr();
        //Logging the informations of IP and Browser.
        logger.info("IP: " + ip + " Browser info: " + userAgent);
        //Following to the next filter. If none next filter exist, follow to main logic.
        chain.doFilter(req, resp);
    }

    public void init(FilterConfig config) throws ServletException {
    
    
    }
}


In the preceding filter, we get the client IP and browser information and log them. The
在前面的过滤器中,我们获取客户端IP和浏览器信息并记录它们。这个
LogBrowserFilter operation is similar to that of LogAccessFilter.
LogBrowserFilter的操作与LogAccessFilter的操作类似。
To define the order of filter execution, we need to configure the web.xml and add the filter
要定义过滤器执行的顺序,我们需要配置web.xml文件再加上过滤器
mapping information. Here, we can see web.xml with its configuration:
映射信息。在这里,我们可以看到web.xml文件其配置:

<web-app version="3.1"
 xmlns="http://xmlns.jcp.org/xml/ns/javaee"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
 <filter>
 <filter-name>LogBrowser</filter-name>
 <filter-class>com.rhuan.filter.LogBrowserFilter</filter-class>
 </filter>
 <filter>
 <filter-name>LogAccess</filter-name>
 <filter-class>com.rhuan.filter.LogAccessFilter</filter-class>
 </filter>
</web-app>

The configurations defined in web.xml override the annotation configurations. Thus, if we
中定义的配置web.xml文件重写注释配置。因此,如果我们
put the urlPattern configuration on web.xml, then the configuration considered
启用urlPattern配置web.xml文件,然后考虑配置
is web.xml’s configuration. We don’t put the filter mapping information on web.xml
是web.xml文件的配置。我们不把过滤器映射信息放在web.xml文件
because this is already on the annotation configuration in the code.
因为这已经在代码中的注释配置上了。
The web.xml configuration defines the order—LogBrowserFilter will be called first,
这个web.xml文件配置定义将首先调用LogBrowserFilter的顺序,
followed by LogAccessFilter, and then the main logic (servlet).
接着是LogAccessFilter,然后是主逻辑(servlet)。

Deciding filter mapping

定义滤波器映射
Defining the mapping method is crucial to implementing the intercepting filter pattern.
定义映射方法是实现拦截过滤模式的关键。
This is because a bad method for mapping can impact the project directly and cause
这是因为不好的映射方法会直接影响项目并导致
rework. We have two filter mapping types—UrlPattern and servlet name.
返工。我们有两种过滤器映射类型UrlPattern和servlet name。
The use of UrlPatterns is indicated when we want to filter the HTTP Requests to nonspecific resources or files, but we also want to filter various unknown resources. Here are
当我们想过滤对非特定资源或文件的HTTP请求时,使用UrlPatterns是有指示的,但是我们也希望过滤各种未知资源。给你
some examples of this:
这方面的一些例子:
.jsp: This filters all requests to JSP pages. If one JSP page is added to the
.jsp:它过滤对jsp页面的所有请求。如果一个JSP页面被添加到
server, then the filter will filter the new JSP page without making any
服务器,则过滤器将过滤新的JSP页面,而不进行任何
modifications.
修改。
/
: This filters all requests to all resources or files on the server. If one resource or
/
:这将筛选对服务器上所有资源或文件的所有请求。如果一个资源或
file is added to the server, then the filter will filter this new resource or
文件已添加到服务器,则筛选器将筛选此新资源或
file without performing any modifications.
不执行任何修改。
/user/: This filters all requests to all resources or files on the server that have a
/user/
:这将筛选对服务器上具有
URI beginning with /user. If one resource or file that is accessed by a URI
以/user开头的URI。如果一个资源或文件被URI访问
beginning with /user is added on servlet, then the filter will filter this new
在servlet上添加了以/user开头的,然后过滤器将过滤这个新的
resource or file without performing any modifications.
不执行任何修改的资源或文件。
The servlet name used to map the filter indicates when you want to filter a specific servlet,
用于映射过滤器的servlet名称指示何时过滤特定的servlet,
independent of its urlPattern. This way of mapping allows us to modify one
独立于它的urlPattern。这种映射方式允许我们修改一个
urlPattern of the mapped servlet without performing any modifications on the filter.
未对筛选器执行任何修改的映射servlet的urlPattern。
Here are some examples:
以下是一些示例:
{servlet1}: This only maps the servlet named as servlet1. If the
{servlet1}:这只映射名为servlet1的servlet。如果
urlPatterns of servlet1 are modified, then the filter doesn’t need to be
servlet1的urlPatterns被修改,那么过滤器就不需要修改了
modified.
被改进的。
{servlet1,servlet2}: This maps two servlets named servlet1 and
{servlet1,servlet2}:这映射了两个名为servlet1和
servlet2. Its behavior is similar to the previous example shown, in which only
服务2。它的行为类似于前面的示例,其中只有
one servlet was mapped.
一个servlet 被映射了。

猜你喜欢

转载自blog.csdn.net/Coder_Boy_/article/details/110382614
今日推荐