Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jsp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Design patterns 使用java servlet实现前端控制器的最佳实践_Design Patterns_Jsp_Servlets_Jakarta Ee_Front Controller - Fatal编程技术网

Design patterns 使用java servlet实现前端控制器的最佳实践

Design patterns 使用java servlet实现前端控制器的最佳实践,design-patterns,jsp,servlets,jakarta-ee,front-controller,Design Patterns,Jsp,Servlets,Jakarta Ee,Front Controller,假设我们有下一个结构的项目: web articles main.jsp sidearts.jsp central.jsp forum main.jsp css js WEB-INF web.xml 网状物 文章 main.jsp sidearts.jsp central.jsp 论坛 main.jsp css js WEB-INF web.xml 请注意,目前我们还没有前端控制器 使用某个方面(设为“asdf”)进行部署后,我们可以使

假设我们有下一个结构的项目:

web articles main.jsp sidearts.jsp central.jsp forum main.jsp css js WEB-INF web.xml 网状物 文章 main.jsp sidearts.jsp central.jsp 论坛 main.jsp css js WEB-INF web.xml 请注意,目前我们还没有前端控制器

使用某个方面(设为“asdf”)进行部署后,我们可以使用下一个URL访问我们的页面:

http://localhost:8080/asdf/articles/main.jsp http://localhost:8080/asdf/forum/main.jsp and so on.. http://localhost:8080/asdf/articles/main.jsp http://localhost:8080/asdf/forum/main.jsp 等等 jsp生成一些html并包括sidearts.jsp(通过jstl c:import或任何其他方式)

添加前端控制器后会发生什么

假设我们有servlet ArticlesController,它负责调度
某些请求和具有下一个映射的请求:

<servlet>
  <servlet-name>ArtsController</servlet-name>
  <servlet-class>org.forstackoverflow.ArticlesController</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>ArtsController</servlet-name>
  <url-pattern>/articles/*</url-pattern>
</servlet-mapping>

艺术控制器
org.forstackoverflow.ArticlesController
艺术控制器
/文章/*
现在当我们请求URL
http://localhost:8080/asdf/articles/main
,ArticlesController处理此请求并尝试包含articles/main.jsp。此时无穷循环开始,因为/articles/*映射到ArtsController

所述问题的正确解决方案是什么

我的变体是:

1) 为所有jsp文件进行映射(我认为这是不可接受的)


2) 更改目录名称(文章->艺术);但是我们得到了很多新的URL(比如
http://localhost:8080/asdf/arts/main.jsp
)我认为这可能是bug的来源

您可能会将servlet与过滤器混淆。有了servlet,就不会有无限循环。您的JSP页面将始终通过精确的模式进行映射,无论是显式(如果它们是预编译的)还是隐式(如果它们不是预编译的,则通过相对于webapp根的JSP文件路径)。这意味着您的“articles/main.jsp”实际上是一个具有以下映射的servlet:

<servlet-mapping>
  <servlet-name>name_does_not_matter_here</servlet-name>
  <url-pattern>/articles/main.jsp</url-pattern>
</servlet-mapping>

名字在这里无关紧要
/articles/main.jsp
ArticlesController
servlet映射到
/articles/*
时,将发生以下情况:


http://localhost:8080/asdf/articles/main
URL将由servlet处理,因为它与JSP的模式不匹配。但是,
http://localhost:8080/asdf/articles/main.jsp
匹配这两种模式的URL将被映射到JSP页面而不是servlet,因为servlet容器将始终更喜欢精确匹配而不是通配符匹配(这是J2EE规范的一部分)。

您可能会将servlet与过滤器混淆。有了servlet,就不会有无限循环。您的JSP页面将始终通过精确的模式进行映射,无论是显式(如果它们是预编译的)还是隐式(如果它们不是预编译的,则通过相对于webapp根的JSP文件路径)。这意味着您的“articles/main.jsp”实际上是一个具有以下映射的servlet:

<servlet-mapping>
  <servlet-name>name_does_not_matter_here</servlet-name>
  <url-pattern>/articles/main.jsp</url-pattern>
</servlet-mapping>

名字在这里无关紧要
/articles/main.jsp
ArticlesController
servlet映射到
/articles/*
时,将发生以下情况:


http://localhost:8080/asdf/articles/main
URL将由servlet处理,因为它与JSP的模式不匹配。但是,
http://localhost:8080/asdf/articles/main.jsp
匹配两种模式的URL将被映射到JSP页面,而不是servlet,因为servlet容器将始终更喜欢精确匹配而不是通配符匹配(这是J2EE规范的一部分)。

由于您使用的是MVC,您应该允许客户端(即浏览器)访问视图,本例中为jsp。当对控制器servlet执行操作时,应该从视图中调用它。在控制器中处理操作后,重定向到下一个视图(该视图可能与启动操作的视图相同)


让servlet url模式与真实目录匹配会把事情搞砸,因为它会告诉容器选择servlet而不是该目录的默认页面。

因为您使用的是MVC,所以应该让客户端(即浏览器)访问视图,在本例中是jsp。当对控制器servlet执行操作时,应该从视图中调用它。在控制器中处理操作后,重定向到下一个视图(该视图可能与启动操作的视图相同)


让servlet url模式与真实目录匹配会把事情搞砸,因为它会告诉容器选择servlet而不是该目录的默认页面。

当我回到家后,我可以发布POEAA中的示例。出于好奇,您想要实现自己的(基于servlet的)前端控制器的原因是什么?为什么不选择一个开放源码的MVC框架呢?回到家后,我可以发布POEAA的例子。出于好奇,你为什么要实现自己的(基于servlet的)前端控制器?为什么不选择现有的许多开源MVC框架中的一个呢?有没有一种方法可以在不需要额外拷贝的情况下多次部署同一个servlet?假设我写了一些CMS,我希望两个客户能够使用它-这是一个有效的用例吗?这是通过web.xml控制的吗?我不太清楚你的意思,或者它与原始问题的关系。。。如果“多次部署”的意思是“映射到不同的URL”,那么是的,您可以这样做。有没有一种方法可以多次部署同一个servlet而不需要它的额外副本?假设我写了一些CMS,我希望两个客户能够使用它-这是一个有效的用例吗?这是通过web.xml控制的吗?我不太清楚你的意思,或者它与原始问题的关系。。。如果“多次部署”的意思是“映射到不同的URL”,那么是的,您可以这样做。