假设我们有一些具有下一个结构的项目:
web articles main.jsp sidearts.jsp central.jsp forum main.jsp css js WEB-INF web.xml
请注意,此时我们还没有前置控制器。
在部署了一些方面(让它为'asdf')后,我们可以使用下一个网址访问我们的网页:
http://localhost:8080/asdf/articles/main.jsp http://localhost:8080/asdf/forum/main.jsp and so on..
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)更改目录名称(articles-&gt; arts);但后来我们得到了很多新的URL(比如http://localhost:8080/asdf/arts/main.jsp
),我认为它可能是bug的来源。
答案 0 :(得分:1)
您可能会将servlet与过滤器混淆。使用servlet,将没有无限循环。您的JSP页面将始终通过精确模式进行映射,无论是显式模式(如果它们是预编译的)还是隐式模式(如果未预编译,则通过相对于webapp root的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>
将ArticlesController
servlet映射到/articles/*
,将发生以下情况:
http://localhost:8080/asdf/articles/main
URL将由您的servlet处理,因为它与JSP的模式不匹配。但是,匹配两个模式的http://localhost:8080/asdf/articles/main.jsp
URL将映射到JSP页面而不是servlet,因为servlet容器将始终更喜欢与通配符匹配完全匹配(这是J2EE规范的一部分)
答案 1 :(得分:0)
由于您使用的是MVC,因此您应该让客户端(即浏览器)访问视图,在这种情况下是jsp。在对其执行操作时,应从视图中调用控制器servlet。在控制器中处理操作后,您将重定向到下一个视图(可能与启动操作的视图相同。)
使servlet url-pattern匹配到一个真实的目录,因为它告诉容器选择servlet而不是该目录的默认页面。