如何映射“根”Servlet以便其他脚本仍可运行?

时间:2009-06-23 02:01:28

标签: java google-app-engine servlets web.xml

我正在尝试构建一个调用类似于以下内容的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-pattern匹配,以便Servlet再次运行。这会产生一个循环,直到它以java.lang.StackOverflowError消亡。

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

8 个答案:

答案 0 :(得分:45)

使用空图案,例如

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

servlet 3.0规范澄清了这一点:

  

空字符串(“”)是一个特殊的URL模式,它完全映射到   应用程序的上下文根

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

答案 1 :(得分:29)

使用web.xml的welcome-file元素为我工作,在app引擎上。这是我的:

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

答案 2 :(得分:7)

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

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

  • JSP文件不能在没有“/”的情况下“命名”。
  • JSP文件不能在子目录中
  • 无法使用“/”url-pattern
  • 将Servlet映射到应用程序的根目录

这是我的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>

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

答案 3 :(得分: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>

答案 4 :(得分:1)

尝试从模式中删除'*',即

<url-pattern>/</url-pattern>

答案 5 :(得分:1)

使用URLrewrite - &gt;在另一个线程URL Pattern for servlet mapping in web.xml中提到了一个解决方案。 http://tuckey.org/urlrewrite/

答案 6 :(得分:0)

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

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

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

答案 7 :(得分:0)

你试过以下吗? (请注意丢失的*,这是一张外卡,这是您的配置捕获所有内容的原因。)

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

(根据/的评论编辑。)