【问题标题】:Jetty not routing to servlet when web application in sub directory of webapps当 web 应用程序位于 webapps 的子目录中时,Jetty 不会路由到 servlet
【发布时间】:2013-01-22 15:02:53
【问题描述】:

当我将应用程序文件夹放在 {JETTY_HOME}/webapps 目录中时,我有一个运行正常的 Web 应用程序(调用了 servlet)。

如果我将 Web 应用程序的副本放在 webapps 的子文件夹中,那么当我浏览到该站点时会调用所有静态文件,但我通过 ajax 调用的 servlet 返回 404。

http://localhost/shlaa
  • 正确调用 /shlaa/CommentController.do 没有错误。
http://localhost/mapapp/shlaa
  • 为 ajax 调用 /mapapp/shlaa/CommentController.do 返回 404

    两个路径 /WEB_INF 文件夹中的 web.xml 包含以下内容

    <servlet>
        <servlet-name>CommentController</servlet-name>
        <servlet-class>web.CommentController</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>CommentController</servlet-name>
        <url-pattern>/CommentController.do</url-pattern>
    </servlet-mapping>
    

    {JETTY_HOME}/etc 中的 jetty.xml 文件夹包含以下内容:

     <Call class="org.mortbay.jetty.webapp.WebAppContext" name="addWebApplications">
          <Arg><Ref id="contexts"/></Arg>
            <Arg><SystemProperty name="jetty.home" default="."/>/webapps</Arg>
          <Arg><SystemProperty name="jetty.home" default="."/>/etc/webdefault.xml</Arg>
          <Arg type="boolean">True</Arg>  <!-- extract -->
          <Arg type="boolean">True</Arg> <!-- parent priority class loading -->
      </Call> 
    

【问题讨论】:

  • 我注意到您的 servlet 模式中的 .do 扩展名。您是否有机会使用 struts ?
  • 你也说过localhost/shlaa 正确调用/mapapp/shlaa/CommentController.do 没有错误。你能分享一下配置吗?我很好奇它是如何工作的
  • @Zenil 不使用 struts - 只是养成了用这个结束 servlet 引用的习惯。
  • @Zenil 我已经在 webapps 根目录和 webapps/mapapp 目录中放置了一个 shlaa 的克隆应用程序,我已经更正了上面的参考
  • 在第一种情况下,您说它可以正常工作:localhost/shlaa 调用 /mapapp/shlaa/CommentController.do 。我想知道 这是如何 工作的。你的 web.xml 配置是什么?

标签: java servlets jetty url-routing directory-structure


【解决方案1】:

为了将 Java Web 应用程序正确部署到某个应用程序服务器或只是简单的 Web 容器(如您的情况),Web 应用程序(也称为 web 模块必须具有特定的结构。 Web 模块的顶级目录是应用程序的文档根

这是一个 Web 模块结构:

现在,您在 web.xml 文件中的&lt;url-pattern&gt; 中定义的只是一些 servlet 的 逻辑/虚拟 路径。同样,它不是到 servlet 类的物理位置的真实路径,而是一条逻辑路径 - 您可以根据需要自行构建。

好的,现在您必须将具有正确结构的 webapp 放在 webapps 目录中。例如,在上图中 Assembly Root 象征着你的 webapp 文件夹。因此,您可以直接获取该文件夹,也可以制作一个 WAR(Web 应用程序存档)并将其放在 webapps 目录下。并不是说在 webapps 中有一些目录,而在那个目录中有几个 webapps。所有的网络应用都必须在 webapps 目录下。

因此,在您的情况下,如果您的 webapp 文件夹的名称为 shlaa,您必须将该文件夹放在 webapp 的正下方。时期。

现在引用官方 Java EE 文档:

将 URL 映射到 Web 组件

当它收到一个请求时,web 容器必须确定哪个 web 组件应该处理请求。 Web 容器通过以下方式执行此操作 将请求中包含的 URL 路径映射到 Web 应用程序和 一个网页组件。 URL 路径包含上下文根,并且可选地, 别名:

http://host:port/context-root/alias

设置组件别名

别名标识应处理请求的 Web 组件。 别名路径必须以正斜杠 (/) 开头并以 字符串或带有扩展名的通配符表达式(例如, *.jsp)。由于 Web 容器会自动映射以 *.jsp 结尾的别名,因此您不必为 JSP 页面指定别名,除非您希望通过文件名以外的名称来引用该页面。

在您的情况下,您的网络应用程序的 URL 将是 http://localhost:8080/shlaa

现在引用 Jetty wiki 文档 (Jetty/Howto/SetContextPathto):

使用 WebAppProvider

WebAppProvider 的作用是查看 ${jetty.home}/webapps/ 任何可部署应用程序(例如 *.war)的目录,并部署 将它们放到与文件名同名的上下文中。例如, WebAppProvider 将 ${jetty.home}/webapps/MyApp-2.4.war 部署到 上下文/MyApp-2.4。还有特殊的root.war保留字 部署到上下文 / 中。虽然这是最简单的部署 机制,它牺牲了对部署细节的控制。

长话短说只需将您的网络应用程序放在 webapps 目录下即可让一切正常运行。 至于&lt;url-pattern&gt; - 随意定义你喜欢的任何模式。

注意:实际上有几种配置 Jetty 的方法,即 XML 配置不是唯一的一种。详情请见Configuring Jetty

引用The Java™ Servlet SpecificationVersion 3.0:

第 12 章

将请求映射到 Servlet

12.1 使用 的 URL 路径

在收到客户端请求后,Web 容器 确定要将其转发到的 Web 应用程序。网络 所选应用程序必须具有匹配的最长上下文路径 请求 URL 的开头。 URL的匹配部分是 映射到 servlet 时的上下文路径。 Web 容器接下来必须 使用路径映射定位 servlet 以处理请求 过程如下所述。用于映射到 servlet 的路径是 来自请求对象的请求 URL 减去上下文路径和 路径参数。下面的 URL 路径映射规则按顺序使用。 使用第一个成功的匹配,不再尝试匹配:
  1. 容器将尝试查找请求路径与 servlet 路径的完全匹配。成功的匹配选择 小服务程序。

  2. 容器将递归地尝试匹配最长的路径前缀。这是通过将路径树下移到一个目录来完成的 一次,使用“/”字符作为路径分隔符。最长的 match 确定选择的 servlet。

  3. 如果 URL 路径中的最后一段包含扩展名(例如 .jsp),则 servlet 容器将尝试匹配处理 延期申请。扩展被定义为 最后一个 '.' 字符之后的最后一段。

  4. 如果前三个规则都没有导致 servlet 匹配,则容器将尝试提供适合 请求的资源。如果为 应用程序,它将被使用。许多容器提供了隐含的 用于提供内容的默认 servlet。容器必须使用 区分大小写的字符串比较以进行匹配。

12.2 映射规范

在 Web 应用程序部署描述符中,使用以下语法来定义映射:

  • 以“/”字符开头并以“/*”后缀结尾的字符串用于 路径映射。

  • 以“*.”前缀开头的字符串用作扩展映射。

  • 空字符串 ("") 是一种特殊的 URL 模式,它完全映射到 应用程序的上下文根,即http://host:port/&lt;contextroot&gt;/ 形式的请求。 在这种情况下,路径信息是“/”,servlet 路径和上下文路径是 空字符串(“”)。

  • 仅包含 '/' 字符的字符串表示 应用。在这种情况下,servlet 路径是请求 URI 减去上下文路径 并且路径信息为空。

  • 所有其他字符串仅用于完全匹配。

以你的名字为例。

您的 webapp 名称是 ma​​papp(它是应用程序的根目录)。您希望通过

访问您的 CommentController.do
http://localhost:8080/mapapp/shlaa/CommentController.do

然后(如果满足所有其他要求,如目录结构等)在您的 web.xml 中输入以下内容:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                        http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    version="3.0">

    <servlet>
        <servlet-name>Comment Controller</servlet-name>
        <servlet-class>com.example.CommentController</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Comment Controller</servlet-name>
        <url-pattern>/shlaa/CommentController.do</url-pattern>
    </servlet-mapping>

</web-app>

上述url-pattern中的第一个正斜杠(/)代表上下文根/上下文路径mapapp 在这种情况下)。
这样就可以了。


这里有一些有用的链接。

Java EE 5 教程

Java EE 6 教程

码头

希望这会对你有所帮助。


更新

Jetty 的具体配置见此链接:
How to have a web app respond only on a specific port

【讨论】:

    【解决方案2】:

    这就是我认为正在发生的事情。

    仅在 webapps 根目录和 webapps/mapapp 中克隆您的应用程序 shlaa 不会将您的 servlet 克隆到新位置。

    静态内容有效,因为这些文件实际上存在于该位置,Jetty 会在正确的位置为它们提供服务

    对于 servlet,服务器只能识别一个位置,即 shlaa/web/WEB-INF/classes 中的位置 (由于您克隆了您的应用程序,我假设您的克隆将类似于 shla/mapapp/web/WEB-INF/classes)

    你要做的就是修改你的 web.xml 以便 shlaa/mapapp被识别

    例如:(尝试以下组合)

    <servlet-mapping>
        <servlet-name>CommentController</servlet-name>
        <url-pattern>/mapapp/CommentController.do</url-pattern>
    </servlet-mapping>
    

    【讨论】:

    • 克隆的应用程序在路径 webapps/mapapp/shlaa 中,我已将 webapps\mapapp\shlaa\WEB-INF\web.xml 中 CommentController 的 url 模式修改为 /mapapp/shlaa/CommentController。做,我在浏览到localhost/mapapp/shlaa/CommentController.do时仍然得到404@
    • @peter 你不应该试试 localhost/shlaa/mapapp/CommentController.do 吗?
    • 没有因为文件夹结构是webapp - mapapp - shlaa
    • @peter 我认为 slaa 是您的主要 Web 应用程序文件夹。由于 mapapp 是你的主文件夹,你应该把 /shlaa/CommentController.do 作为你的 web.xml 中的 url 模式
    • /shlaa/CommentController.do 作为url模式,浏览到localhost/mapapp/shlaa/CommentController.do时也返回404
    猜你喜欢
    • 1970-01-01
    • 2017-09-06
    • 1970-01-01
    • 2017-04-19
    • 2011-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多