1

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

网络
  文章
    主.jsp
    sidearts.jsp
    中央.jsp
  论坛
    主.jsp
  css
  js
  网络信息
    web.xml

请注意,此时我们还没有前端控制器。

在部署了一些方面(让它成为'asdf')之后,我们可以使用下一个 URL 访问我们的页面:

http://localhost:8080/asdf/articles/main.jsp
http://localhost:8080/asdf/forum/main.jsp

等等..

main.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>

现在当我们请求 URL 时http://localhost:8080/asdf/articles/main,ArticlesController 处理这个请求并尝试包含articles/main.jsp。此时无限循环开始,因为 /articles/* 映射到 ArtsController。

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

我的变种是:

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

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

4

2 回答 2

1

您可能会将 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>

随着您的ArticlesControllerservlet 映射到/articles/*以下将发生:

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

于 2009-07-27T23:08:00.000 回答
0

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

使 servlet url-pattern 与真实目录匹配会搞砸,因为它告诉容器选择 servlet 而不是该目录的默认页面。

于 2009-07-29T02:47:06.387 回答