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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1030302/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 22:27:30  来源:igfitidea点击:

How can I map a "root" Servlet so that other scripts are still runnable?

javagoogle-app-engineservletsweb.xml

提问by Jeremy Logan

I'm trying to build a Servlet that calls a JSP page similar to the following:

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

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

I need this Servlet to respond to the domain's root (eg: http://example.com/) so I'm using the following mapping in the web.xml:

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

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

The problem I'm having is that this matches EVERYTHING, so when the dispatcher forwards to "/WEB-INF/main.jsp" this matches the url-pattern so the Servlet gets run again. This results in a loop that runs until it dies with a java.lang.StackOverflowError.

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

How can I match the root without preventing other scripts from being runnable?

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

回答by Vincent Ramdhanie

You can create a welcome file named index.jsp in the root with the following code using JSTL or otherwise.

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

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

So in the web.xml file you will have this:

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

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

So anyone requesting the root will be redirected to /main. Now your servlet can be mapped to main.

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

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

回答by matt b

You can't redirect to WEB-INF. A servlet container will never serve requests for documents in that folder.

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

If you want your application (not just a servlet, but the entire application) to be available under the root context ("/" of "http://www.domainname.com/"), then you need to set up a context entry for it - not a servlet mapping.

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

With Tomcat, you add a new <Context>mapping(in one of about 3 different possible places).

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

回答by Stu Thompson

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 /.)

(根据刚刚的评论编辑/。)

回答by Gennady Shumakher

Try just to remove '*' from the pattern, i.e.

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

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

回答by Tomasz

A solution is mentioned in another thread URL Pattern for servlet mapping in web.xmlusing URLrewrite -> http://tuckey.org/urlrewrite/

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

回答by Sam Lowry

The original question doesn't mention that they're trying to map a root servlet on App Engine - it's easy on Tomcat (and other servlet containers as far as I know) but App Engine isn't a normal servlet container.

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

My normal way of building a web application with servlets is to extend HttpServlet, add a "page" object with title, content, errors, messages etc. and for output forward to a JSP template. This has been an absolute nightmare getting working in App Engine.

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

  • JSP files can't be "named" without a "/" at the beginning.
  • JSP files can't be in a subdirectory
  • Servlets can't be mapped to the root of your application with a "/" url-pattern
  • JSP 文件不能在开头没有“/”的情况下“命名”。
  • JSP 文件不能在子目录中
  • Servlet 无法使用“/” url-pattern 映射到应用程序的根目录

Here's my web.xml (edited for brevity) which finally worked.

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

I haven't been particularly scientific about validating all this - but it seems to work for me now and I'm pretty happy about that.

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

回答by Jeb

Using the welcome-file element of web.xml worked for me, on app engine. Here's mine:

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

回答by nilskp

Use an empty pattern, e.g.

使用空模式,例如

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

The servlet 3.0 spec has clarified this:

servlet 3.0 规范阐明了这一点:

The empty string ("") is a special URL pattern that exactly maps to the application's context root

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

So it should at least work on a 3.0 container, and I've verified that it works on Jetty 8

所以它至少应该在 3.0 容器上工作,我已经验证它在 Jetty 8 上工作