【问题标题】:What is FrontController design pattern? How much level is DispatcherServlet using it?什么是前端控制器设计模式? DispatcherServlet 使用了多少级别?
【发布时间】:2018-09-14 03:58:08
【问题描述】:

实际上,我正在尝试了解 DispatcherServlet 并知道它遵循 FrontController 设计模式。 在尝试理解 FrontController 设计模式时遇到了这个链接 FrontController from Oracle Doc reference 我是初学者,不太了解,但我了解的东西很少,如下所示

如果我们没有 FrontController,我们经常会尝试在多个控制器中复制代码,例如身份验证和授权。因此,如果我们将来想改变某些东西,可维护性就会成为一个大问题。所以有了frontController,我们就可以将基本功能移到frontController中,并且可以很容易地进行更改。

当我在采访中解释同样的事情时,他问我这些基本功能是什么。我告诉了 Internalization、viewResolver、Authentication、Authorization 等。现在再次问考虑一下,如果没有调度程序 Servlet,您如何处理每个控制器中的这些功能?

因为我基本上是一名桌面应用程序开发人员,所以我无法回答他的下一个问题。

这是我的问题

  1. 首先,我的理解正确吗?

  2. 如果我的理解是正确的,面试官的第二个问题如何回答?如果没有调度程序 Servlet,您将如何处理每个控制器中的这些功能?意思是让我写一些常用功能的伪代码。我不能,因为我是摇摆开发人员。有人可以向我解释一下,我们在控制器中重复一些示例代码,现在我们可以避免使用调度程序。

  3. 如果我们开始比较 DispatcherServlet 和 frontController 设计模式,我们可以说 LocaleResolver、HandlerMapping、ThemeResolver、ViewResolver、HandlerExceptionResolver、HandlerAdapter、MultipartResolver 等是 DispatcherServlet 的 Helper 类吗?

【问题讨论】:

    标签: java spring spring-mvc design-patterns front-controller


    【解决方案1】:

    前端控制器设计模式意味着应用程序中对资源的所有请求都将由单个处理程序处理,然后针对该类型的请求分派到适当的处理程序。前端控制器可以使用其他助手来实现调度机制。

    前端控制器设计模式可以通过以下两种方式之一实现。

    1. 使用 Servlet
    2. 使用过滤器

    Spring Framework 使用 DispatcherServlet 实现 FrontController 设计模式,用于拦截每个请求并委托给负责的控制器处理请求。

    如果面试官问你,如果你没有 DispatcherServlet 会发生什么,那么你如何管理所有这些身份验证和授权的事情,你可以简单地说我可以定义一个过滤器来拦截每个请求。过滤器应该负责调度、认证和授权的事情。 Struts 使用 Filter 来实现 FrontController 设计模式。

    【讨论】:

    • 您是否同意 dispatcherServlet 处理分散在所有控制器中的任何常见功能?如果是,您认为它们是什么?
    • 你认为dispatcherServlet处理身份验证和授权机制吗?
    • 没有 Spring 有 Spring Security 模块,它实际上使用过滤器链来管理身份验证和授权。 docs.spring.io/spring-security/site/docs/4.2.1.RELEASE/…
    • 好吧,你觉得我的第一条评论怎么样,暂时忘掉安全吧。
    • 是的,拥有前端控制器可以帮助您拥有一个中心位置,将每个请求放在首位。这样,您可以将所有通用逻辑放在那里,而无需将它们复制到每个组件中,并且还有助于维护,因为我们只需在一个地方进行更改。
    【解决方案2】:

    (1) FrontController 只是接收所有外部请求并将每个请求传递给适当处理程序的中心位置。正如您所解释的,因为这是所有请求的中心位置,它可用于执行所有常见的事情,如安全性、日志记录等。

    (2) DispatcherServlet实际上是Spring MVC的前端控制器。它拦截每个请求,然后将每个请求分派到已在 Spring Application Context 中注册的适当控制器。

    考虑一下如果没有dispatcher Servlet你怎么处理 每个控制器中的那些功能?

    对于这个,我不认为这个问题意味着您需要在每个控制器中编写相同的代码。 (如果是这样,那可不是个好主意)

    你可以做一些事情,比如实现一个单独的服务来做那些常见的事情(横切关注点),因为你可以编排所有即将到来的请求。

    【讨论】:

    • 您提到前端控制器可以处理所有常见功能。但是没有提到 dispatcherServlet 也在跟踪它的任何地方。就像它也帮助我们避免在控制器之间重复某些功能。请解释一下 dispatcherServlet 只用于重定向吗?
    • 内部化是作为前端控制器设计模式的dispatcherServlet在一个地方处理的一种常见功能吗?如果 dispatcherServlet 不存在,如何在所有控制器中处理?内部化逻辑是否会重复?
    【解决方案3】:

    前端控制器定义

    前端控制器负责处理所有的请求 一个网站。对于 Web 应用程序开发人员来说,它可能非常有用 结构,因为它允许开发人员的灵活性和能力 重用代码而不必一次又一次地添加。它提供了一个单一的操作点来处理对 J2EE Web 应用程序的所有请求,它将请求转发到特定的应用程序控制器以访问模型和视图以进行演示 分层资源。


    让我们检查 Dispatcher Servlet 的功能,看看它是否完全是前端: 考虑下图取自https://docs.spring.io/spring/docs/3.0.0.M4/reference/html/ch15s02.html

    如上图所示,前端控制器是为 MVC 模式。它被实现为javax.servlet.Servlet servlet,例如struts 中的ActionServlet、JSF 中的FacesServlet 和Spring MVC 中的DispatcherServlet。它处理传入的请求,并将请求委托给 特定的应用程序控制器。该应用程序控制器创建和更新模型,并将其委托给前端控制器进行渲染。最后,前端控制器确定具体的视图,并渲染该模型数据。

    现在将步骤视为:

    1. 用户单击浏览器或提交应用程序的 Web 表单。这 请求离开浏览器,带有一些附加信息或带有 共同信息。这个请求到达 Spring 的 DispatcherServlet,这是一个 与其他基于 java 的 Web 应用程序一样的简单 servlet 类。这是一个前线 Spring MVC 框架的控制器,并汇集所有传入的请求 通过单点。 Spring MVC 框架集中请求 使用此前端控制器进行流量控制。

    2. 用户单击浏览器或提交应用程序的 Web 表单。这 请求离开浏览器,带有一些附加信息或带有 共同信息。此请求到达 Spring 的 DispatcherServlet,这是一个 与其他基于 java 的 Web 应用程序一样的简单 servlet 类。这是一个前线 Spring MVC 框架的控制器,并汇集所有传入的请求 通过单点。 Spring MVC 框架集中请求 使用此前端控制器进行流量控制。

    3. 一旦特定的应用程序控制器由 Spring 的 DispatcherServlet 决定 在处理程序映射配置的帮助下,DispatcherServlet 调度 向所选控制器发出该请求。这是实际控制者,负责根据用户的请求及其参数处理信息。

    4. 一旦特定的应用程序控制器由 Spring 的 DispatcherServlet 决定 在处理程序映射配置的帮助下,DispatcherServlet 调度 向所选控制器发出该请求。这是实际控制者,负责根据用户的请求及其参数处理信息。

    5. 一旦特定的应用程序控制器由 Spring 的 DispatcherServlet 决定 在处理程序映射配置的帮助下,DispatcherServlet 调度 向所选控制器发出该请求。这是实际控制者,负责根据用户的请求及其参数处理信息。

    6. Spring MVC 的DispatcherServlet 将模型渲染到视图,并生成一个 模型信息的用户可读格式

    7. 最后,该信息创建一个响应,并将其返回给用户的浏览器 DispatcherServlet

    所以 Spring MVC 模块通过引入org.springframework.web.servlet.DispatcherServlet 类提供了开箱即用的前端控制器模式实现。这是一个简单的 servlet 类,也是 Spring MVC 框架的支柱。并且这个 Servlet 与 Spring IoC 容器集成在一起,以使 Spring 的依赖模式受益。 Spring 的 web 框架使用 Spring 进行自己的配置,所有的控制器都是 Spring bean。您可以在DispatcherServlet 中看到承认使用前端控制器设计模式的spring doc https://docs.spring.io/spring/docs/3.0.0.M4/reference/html/ch15s02.html


    专门回答您的问题:

    1. 是的,您的理解没问题,但要获得更好的视图,请参阅我的描述
    2. 当没有 DispatcherServlet 时,您需要定义一些东西来处理您需要的功能,最好的办法是编写一个过滤器,包括您的身份验证和授权逻辑
    3. 这些不是 Helper 类,因为它在 OOP 中有自己的定义,您可以将它们视为在 Spring 的前端控制器设计模式实现版本中发挥作用的组件

    更多信息:

    • 大部分定义来自 Dinesh Rajput 的 Spring 5 Design Patterns 一书,您可以参考这本书了解更多信息

    【讨论】:

    • 感谢您的努力和回答!在阅读完春季文档后,我什至阅读并了解了您在回答中提到的所有内容。我的问题中清楚地提到了不清楚的地方。正是我在我的问题中发布了 3 个问题。请回答这些。
    • 当然,我更新了我的答案,并在我的帖子末尾包含了您问题的具体答案
    猜你喜欢
    • 1970-01-01
    • 2011-01-31
    • 2014-05-04
    • 2015-11-30
    • 2011-06-23
    • 1970-01-01
    • 1970-01-01
    • 2012-08-31
    • 2018-09-29
    相关资源
    最近更新 更多