57

我正在尝试构建一个调用 JSP 页面的 Servlet,类似于以下内容:

public void doGet(HttpServletRequest req, HttpServletResponse resp)
        throws IOException, ServletException {
    req.getRequestDispatcher("/WEB-INF/main.jsp").forward(req, resp);
}

我需要这个 Servlet 来响应域的根目录(例如:http ://example.com/ ),所以我在 web.xml 中使用了以下映射:

<servlet-mapping>
    <servlet-name>MainServlet</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

我遇到的问题是这匹配所有内容,因此当调度程序转发到“/WEB-INF/main.jsp”时,这匹配 url 模式,因此 Servlet 再次运行。这会导致一个循环运行,直到它因java.lang.StackOverflowError而死。

如何在不阻止其他脚本可运行的情况下匹配根目录?

4

8 回答 8

49

使用空模式,例如

<servlet-mapping>
    <servlet-name>MainServlet</servlet-name>
    <url-pattern></url-pattern>
</servlet-mapping>

servlet 3.0 规范已经阐明了这一点:

空字符串 ("") 是一种特殊的 URL 模式,它精确映射到应用程序的上下文根

所以它至少应该适用于 3.0 容器,并且我已经验证它适用于 Jetty 8

于 2012-02-29T17:20:22.510 回答
29

在 app engine 上使用 web.xml 的 welcome-file 元素对我有用。这是我的:

<web-app>
    <servlet>
        <servlet-name>RootServlet</servlet-name>
        <servlet-class>com.foo.RootServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>RootServlet</servlet-name>
        <url-pattern>/foo</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
        <welcome-file>foo</welcome-file>
    </welcome-file-list>
</web-app>
于 2010-12-14T19:57:34.587 回答
7

最初的问题没有提到他们正在尝试在 App Engine 上映射根 servlet - 这在 Tomcat(以及据我所知的其他 servlet 容器)上很容易,但 App Engine 不是普通的 servlet 容器。

我用 servlet 构建 Web 应用程序的常规方法是扩展 HttpServlet,添加一个带有标题、内容、错误、消息等的“页面”对象,并将输出转发到 JSP 模板。在 App Engine 中工作绝对是一场噩梦。

  • JSP 文件不能在开头没有“/”的情况下“命名”。
  • JSP 文件不能在子目录中
  • Servlet 不能使用“/”url 模式映射到应用程序的根目录

这是我的 web.xml (为简洁而编辑),它终于奏效了。

<web-app>
  <servlet>
    <!-- this servlet needs to redirect to a NamedDispatcher
         called "template" -->
    <servlet-name>Home</servlet-name>
    <servlet-class>my.domain.HomeSv</servlet-class>
  </servlet>
  <servlet>
    <!-- jsp file must apparently be in root directory and have "/" at
         start of path -->
    <servlet-name>template</servlet-name>
    <jsp-file>/template.jsp</jsp-file>
  </servlet>
  <servlet-mapping>
    <!-- map your home servlet to somewhere other than "/" -->
    <servlet-name>Home</servlet-name>
    <url-pattern>/home</url-pattern>
  </servlet-mapping>
  <welcome-file-list>
    <!-- make your Home servlet the welcome file -->
    <welcome-file>home</welcome-file>
  </welcome-file-list>
</web-app>

我对验证这一切并不是特别科学——但它现在似乎对我有用,我对此感到非常高兴。

于 2009-09-10T06:25:21.807 回答
4

您可以使用 JSTL 或其他方式使用以下代码在根目录中创建一个名为 index.jsp 的欢迎文件。

<c:redirect url="/main"/>

因此,在 web.xml 文件中,您将拥有以下内容:

<welcome-file-list>
    <welcome-file>index.jsp</welcome-file>        
</welcome-file-list>

所以任何请求root的人都会被重定向到/main。现在您的 servlet 可以映射到 main。

<servlet-mapping>
    <servlet-name>MainServlet</servlet-name>
    <url-pattern>/main</url-pattern>
</servlet-mapping>
于 2009-06-23T02:10:38.393 回答
1

尝试从模式中删除“*”,即

<url-pattern>/</url-pattern>
于 2009-06-23T05:53:09.090 回答
1

在另一个线程URL 模式中提到了一个解决方案,用于使用 URLrewrite -> http://tukey.org/urlrewrite/在 web.xml 中进行 servlet 映射

于 2009-08-20T15:05:25.167 回答
0

Have you tried the below? (Note the missing *, which is a wild card and is the reason that your configuration catches everything.)

<servlet-mapping>
        <servlet-name>MainServlet</servlet-name>
        <url-pattern>/index.jsp</url-pattern>
</servlet-mapping>

(Edited as per comments from just /.)

于 2009-06-23T04:40:12.980 回答
0

您不能重定向到 WEB-INF。servlet 容器永远不会为该文件夹中的文档提供请求。

如果您希望您的应用程序(不仅仅是一个 servlet,而是整个应用程序)在根上下文(“ http://www.domainname.com/ ”的“/”)下可用,那么您需要设置一个上下文它的条目 - 不是 servlet 映射。

使用 Tomcat,您可以添加一个新<Context>映射(在大约 3 个不同的可能位置之一)。

于 2009-06-23T02:12:16.300 回答