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

Explaining the FrontController pattern

In the Java EE world, we commonly work with complex projects that have similar
在javaee世界中,我们通常使用具有相似特性的复杂项目
functionalities and processes. Sometimes, using various controllers to handle a request is a
功能和流程。有时,使用不同的控制器来处理请求是
bad practice because it needs to be configured at multiple endpoints and incurs a large cost
错误的做法,因为它需要在多个端点进行配置,并且会产生很大的成本
of creation and maintenance. Consequently, creating a central point to treat a request is a
创建和维护。因此,创建一个处理请求的中心点是
very good solution, as it creates one point to manage all or a group of requests and then
非常好的解决方案,因为它创建一个点来管理所有或一组请求,然后
sends this request to the correct process. We can then treat all points that are common to all
将此请求发送到正确的进程。然后我们可以处理所有共同点
functionalities and send the request to a process to treat the questions that are not common
功能,并将请求发送到流程以处理不常见的问题
to all but are specific to one functionality. Some configurations, such as session
只有一个功能是特定的。一些配置,如会话
configuration, the maximum size limit of a request, cookie, and header, are common to all
配置,即请求、cookie和头的最大大小限制,对所有人都是通用的
requests and can be configured from a central point.
请求并可以从中心点进行配置。
The FrontController pattern is a pattern that creates a central manager to treat all
FrontController模式是一种创建中央管理器来处理所有问题的模式
requests or a request group of an application and then sends the requests to one specific
请求或应用程序的请求组,然后将请求发送到一个特定的
process, which is generally a command. This pattern is rarely used on common projects
进程,通常是一个命令。这种模式很少用于普通项目
because today we have some ready-made solutions, and implementing this pattern is
因为今天我们有一些现成的解决方案,而实现这种模式是
generally unnecessary. This pattern is used by frameworks such as JSF, Spring MVC, and
一般不需要。这个模式被JSF、springmvc和
struts. The following diagram depicts this pattern:
支持。下图描述了这种模式:

在这里插入图片描述

In the preceding diagram, we have FrontController, AbstractCommand, Command1, and
在前面的图表中,我们有FrontController、AbstractCommand、Command1和
Command2. FrontController receives all requests, treats some common points of the
命令2。FrontController接收所有请求,处理
request, and sends this request to the matching command. AbstractCommand is the
请求,并将此请求发送到匹配的命令。AbstractCommand是
abstract class of command. Command1 and Command2 are the subclasses of command,
命令的抽象类。Command1和Command2是command的子类,
which implement its correspondent logic.
实现了相应的逻辑。
In our case, we will have two pages—a homepage and a login page. If the user is logged in
在我们的例子中,我们将有两个页面-一个主页和一个登录页面。如果用户已登录
at the moment that a request is sent, then the application will launch the login page, and
在发送请求时,应用程序将启动登录页面,并且
then the homepage.
然后是主页。

Implementing FrontController

Here, we have an implementation of MyAppController, which is a FrontController to treat all the requests of an application:

package com.gary.book.chapter01;

import com.rhuan.action.Command.AbstractCommand;
import com.rhuan.action.Command.HomeCommand;
import com.rhuan.action.Command.LoginCommand;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(name = "MyAppController", urlPatterns = "/myapp/*")
public class MyAppController extends HttpServlet {
    
    
    private static Logger logger =
            LogManager.getLogger(MyAppController.class);
    private final String PAGE_ERROR = "/pageError.jsp";

    protected void doPost(HttpServletRequest request,
                          HttpServletResponse response) throws ServletException, IOException {
    
    
        processRequest(request, response);
    }

    protected void doGet(HttpServletRequest request,
                         HttpServletResponse response) throws ServletException, IOException {
    
    
        processRequest(request, response);
    }

    protected void processRequest(HttpServletRequest
                                          request, HttpServletResponse response)
            throws ServletException, java.io.IOException {
    
    
        String resultPage;
        AbstractCommand command = null;
        try {
    
    
            //Create a correspondent Command.
            if (request.getSession().getAttribute("USER") == null)
                command = new LoginCommand();
            else command = new HomeCommand();
            //Execute the Command that return a page.
            resultPage = command.execute();
        } catch (Exception e) {
    
    
            logger.error(e.getMessage());
            resultPage = PAGE_ERROR;
        }
        //Dispatch to correspondent page.
        getServletContext().getRequestDispatcher(resultPage)
                .forward(request, response);
    }
}

In the following code snippet, it is very important to note that urlPattern is used to
在下面的代码片段中,请注意urlPattern用于
define which requests a context will send to our controller. Here’s how we do this:
定义上下文将发送给控制器的请求。我们的方法如下:

//Defining the urlPattern to Front Controller
@WebServlet(name = "MyAppController", urlPatterns = "/myapp/*")
public class MyAppController extends HttpServlet {
    
    
 ...
}

On the urlPattern, the value is “/myapp/". As previously shown in the preceding code
在urlPattern上,值为“/myapp/
”。如前面的代码所示
snippet, this URL pattern (”/myapp/") establishes that all requests to the myapp URI are
这个URL模式(“/myapp/
”)确定对myapp URI的所有请求都是
sent to our controller. For example, http://ip:port/context/myapp/myfuncionality
发送给我们的控制器。例如,http://ip:端口/context/myapp/myfunctionality
is sent to our controller.
发送到我们的控制器。
When we implement this pattern, it is very important to pay attention to the use of
当我们实现这个模式时,注意使用
attributes on servlets, because all the class attributes on a servlet are shared with all threads
servlet上的属性,因为servlet上的所有类属性都与所有线程共享
or all requests.
或所有请求。

All GET requests or POST requests are sent to the processRequest method, which
所有GET请求或POST请求都被发送到processRequest方法,该方法
implements the logic to send the request to the respective command and executes the
实现将请求发送到相应命令的逻辑,并执行
respective logic. After the correct command is set, the respective command is executed and
各自的逻辑。设置正确的命令后,执行相应的命令,并
the page is dispatched. Here, we have the line that executes the command and dispatches
页面已发送。在这里,我们有一个执行命令和分派的行
the request to the correct page:
对正确页面的请求:

//Execute a Command resultPage = command.execute();

Dispatching the request to the corresponding page: //Dispatch to correspondent page. getServletContext().getRequestDispatcher(resultPage) .forward(request, response);

Implementing the commands

Here, we have AbstractCommand, which is an abstract class with one execute method. This is the abstract command, and the execute method is implemented on the subclasses:
这里,我们有AbstractCommand,它是一个带有一个execute方法的抽象类。这是抽象命令,execute方法在子类上实现:

public abstract class AbstractCommand {
    public abstract String execute(); }

In the following code snippet, we have the subclass HomeCommand, which is the implementation of AbstractCommand. The method execute() returns the path to the home page (/home.jsp):
在下面的代码片段中,我们有一个子类HomeCommand,它是AbstractCommand的实现。方法execute()返回主页的路径(/home.jsp):

public class HomeCommand extends AbstractCommand {
    
        @Override    public String execute() {
    
            return "/home.jsp";    } } 

Here, we have the LoginCommand subclass, which is the implementation of AbstractCommand. The execute() method returns the path to the login page (/login.jsp):
这里,我们有LoginCommand子类,它是AbstractCommand的实现。execute()方法返回登录页的路径(/login.jsp):

public class LoginCommand extends AbstractCommand {
    
        @Override    public String execute() {
    
            return "/login.jsp";    } }

猜你喜欢

转载自blog.csdn.net/Coder_Boy_/article/details/110385512