当Web应用程序位于webapps的子目录中时,Jetty不会路由到servlet

Pet*_*ell 1 java servlets directory-structure jetty url-routing

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

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

http://localhost/shlaa
Run Code Online (Sandbox Code Playgroud)
  • 正确调用/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>
    
    Run Code Online (Sandbox Code Playgroud)

    {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> 
    
    Run Code Online (Sandbox Code Playgroud)

inf*_*k01 10

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

这是一个Web模块结构:

在此输入图像描述

现在,您<url-pattern>web.xml文件中定义的内容只是某个servlet 的逻辑/虚拟路径.同样,它不是 servlet类的物理位置的真实路径,而是逻辑路径 - 您可以根据需要进行构建.

好的,现在您必须将具有正确结构的webapp放在webapps目录中.例如,在上图中,Assembly Root表示您的webapp文件夹.因此,您可以直接获取该文件夹,也可以创建WAR(Web应用程序ARchive)并将其放在webapps目录下.并不是在webapps中你有一些目录,在那个目录中有几个webapps.所有Web应用程序必须位于webapps目录下.

因此,在您的情况下,如果您的webapp文件夹具有名称shlaa,则必须将该文件夹放在正确的位置webapp.期.

现在引用官方Java EE文档:

将URL映射到Web组件

收到请求时,Web容器必须确定应处理请求的Web组件.Web容器通过将请求中包含的URL路径映射到Web应用程序和Web组件来实现.URL路径包含上下文根,以及可选的别名:

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

设置组件别名

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

在您的情况下,您的webapp的URL将是 http://localhost:8080/shlaa

现在来自Jetty wiki docs(Jetty/Howto/SetContextPathto)的qoute:

使用WebAppProvider

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

简而言之,只需将您的Web应用程序放在webapps目录下即可使一切正常运行.至于<url-pattern>- 随意定义你喜欢的任何模式.

注意:实际上有几种配置Jetty的方法,即XML配置不是唯一的方法.有关详细信息,请参阅配置Jetty.

来自The Java™Servlet SpecificationVersion 3.0的引用:

第12章

将请求映射到Servlet

12.1 URL路径的使用

收到客户端请求后,Web容器将确定要将其转发到的Web应用程序.所选的Web应用程序必须具有与请求URL的开头匹配的最长上下文路径.URL的匹配部分是映射到servlet时的上下文路径.接下来,Web容器必须使用下面描述的路径映射过程找到servlet来处理请求.用于映射到servlet的路径是来自请求对象的请求URL减去上下文路径和路径参数.下面的URL路径映射规则按顺序使用.第一次成功匹配使用,未尝试进一步匹配:

  1. 容器将尝试查找请求路径与servlet路径的完全匹配.成功匹配选择servlet.

  2. 容器将递归地尝试匹配最长的路径前缀.这是通过使用'/'字符作为路径分隔符一次单击目录的路径树来完成的.最长匹配确定所选的servlet.

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

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

12.2映射规范

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

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

  • 以"*"开头的字符串 prefix用作扩展映射.

  • 空字符串("")是一个特殊的URL模式,它完全映射到应用程序的上下文根,即表单的请求http://host:port/<contextroot>/.在这种情况下,路径信息是'/',servlet路径和上下文路径是空字符串("").

  • 仅包含'/'字符的字符串表示应用程序的"默认"servlet.在这种情况下,servlet路径是请求URI减去上下文路径,路径信息为null.

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

用你的名字示例.

您的webapp名称是mapapp(它是应用程序根目录).您希望通过访问CommentController.do

http://localhost:8080/mapapp/shlaa/CommentController.do
Run Code Online (Sandbox Code Playgroud)

然后(如果满足目录结构等所有其他需求),请在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>
Run Code Online (Sandbox Code Playgroud)

/上面url-pattern中的第一个正斜杠()表示上下文根/上下文路径(在本例中为mapapp).
这样它就可以了.


这是一些有用的链接.

Java EE 5教程:

Java EE 6教程:

码头

希望这会帮助你.


UPDATE

对于Jetty特定配置,请参阅以下链接:
如何让Web应用程序仅响应特定端口