如何使用URL http:// localhost:8080 / appcontext / META-INF / index.html?

时间:2013-08-07 19:58:54

标签: java servlets

我有一个以http://localhost:8080/appcontext在本地运行的示例应用程序(上下文为/appcontext)。

现在,当我在浏览器中访问http://localhost:8080/appcontext/META-INF/index.html时,我想显示文字Hello, World!

Servlet映射代码

这就是我尝试将Servlet映射到/META-INF URL的方法。但它不起作用:

<?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_2_5.xsd" version="2.5"
>
    <servlet>
        <servlet-name>MyServlet</servlet-name>
        <servlet-class>com.example.mapmetainf.MyServlet</servlet-class>
    </servlet>

    <!--
    <servlet-mapping>
        <servlet-name>MyServlet</servlet-name>
        <url-pattern>/META-INF/index.html</url-pattern>
    </servlet-mapping>
    -->

    <!--
    <servlet-mapping>
        <servlet-name>MyServlet</servlet-name>
        <url-pattern>/META-INF/*</url-pattern>
    </servlet-mapping>
    -->

    <servlet-mapping>
        <servlet-name>MyServlet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
</web-app>

Servlet规范

Java Servlet Specification 3.1,Chapter SRV.9.6 Web Application Archive File:

  

此容器不得直接由容器作为内容提供,以响应Web客户端的请求,[...]。此外,任何访问META-INF资源的请求   必须使用SC_NOT_FOUND(404)响应返回目录。

这禁止直接映射.war的META-INF目录。但我不认为它禁止将Servlet映射到/appcontext/META-INF URL。

4 个答案:

答案 0 :(得分:1)

使用“META-INF”作为上下文名称没有任何限制(据我所知,对上下文名称没有任何限制 - 至少我找不到{{3 }})。

请求的根路径是/ META-INF,它将被分派到适当的servlet上下文。无法访问的实际信息META-INF将位于URL / META-INF / META-INF。

编辑:回复您的评论和问题修改,但您的问题仍然令人困惑:

至于使/context/META-INF/abc.file说“Hello world”或者其他什么,你已经回答了你自己的问题:

  

此外,任何访问META-INF目录中资源的请求都必须返回SC_NOT_FOUND(404)响应。

您可以做的一件事是添加一个自定义的404响应来完成您想要的任务。

答案 1 :(得分:1)

/META-INF//WEB-INF/文件夹是Java Web应用程序中的特殊文件夹。在正常情况下,没有合适的servlet容器可以让你访问这些文件夹中的任何,因为它们通常包含非常敏感的数据,不会暴露给普通公众。如果您的应用部署在<context>下,则预计任何人都无法访问<context>/META-INF/*<context>/WEB-INF/*

如果可能,请依赖其他网址;我认为没有充分理由从/META-INF/提供静态或动态页面。

但是,如果你真的需要这个URL,我会解决这个问题,并使用mod_proxy在你的应用程序前设置一个Apache Web服务器。

在那里你可以说像

RewriteCond     %{REQUEST_URI}  ^/META-INF/(.*)$                          [NC]
RewriteRule     ^(.*)$          /metaInf/$0                               [P,L]

(由hart撰写,请务必检查确切的语法。)这会将/META-INF/的所有外部请求重定向到您自己的应用程序/metaInf/文件夹,并向外界显示您正在服务来自/META-INF/的网页。

但正如所说的那样,除非你有非常具体的理由这样做,否则你不想做的事情。

答案 2 :(得分:1)

我相信你所要求的是在应用程序级别无法实现的。该规范仅讨论META-INF文件夹,但也暗示了URL。我在这里使用“暗示”一词,因为让我们想一下服务器允许你做你想做的事情的后果。

如果服务器允许/appcontext/META-INF url到达您的某个过滤器/ servlet,那么它无法知道您(开发人员)是否会根据规范处理该案例。严格来说,它并不完全符合规范。更糟糕的是,依靠Web开发人员来做。如果是这种情况,那么对于每个需要默认行为的Web应用程序(即META-INF无法访问),开发人员必须实现servlet / filter来执行服务器应该执行的操作第一名(!)

所以我相信你所要求的只能在服务器级别提供,并且只有服务器允许你这样做,即服务器为你提供配置选项,或者允许你编写自己的拦截器类来处理请求的方式与默认行为不同。

在Tomcat 7中,例如META-INF invoke()方法{}禁止访问public final void invoke(Request request, Response response) throws IOException, ServletException { // Disallow any direct access to resources under WEB-INF or META-INF MessageBytes requestPathMB = request.getRequestPathMB(); if ((requestPathMB.startsWithIgnoreCase("/META-INF/", 0)) || (requestPathMB.equalsIgnoreCase("/META-INF")) || (requestPathMB.startsWithIgnoreCase("/WEB-INF/", 0)) || (requestPathMB.equalsIgnoreCase("/WEB-INF"))) { notFound(response); // <-- Issues a response.sendError(HttpServletResponse.SC_NOT_FOUND); return; } ... }

Valve

所以你必须创建自己的AllowMetaInfAccessValve实现(即<TOMCAT_HOME>/lib基本上是上述类的副本而没有“禁止”检查),将它打包在一个罐子里然后放入它在server.xml文件夹中。

然后在你的META-INF中,你会宣布下面的内容。使用该方法,尝​​试访问... <Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true"> ... <Valve className="com.mypackage.valves.AllowMetaInfAccessValve" allow="true"/> ... </Host> ... 文件夹的URL将到达您的servlet,并由您自己负责。

META-INF

更新:为了澄清我的理由:除了从META-INF文件夹提供文件之外,servlet可以做很多事情。但它也可以做到这一点。或者更糟糕的是,对于Web开发人员来说,忘记禁止访问就足以让{{1}}文件夹变得可访问。

这里的重点不是servlet会做什么或不会做什么。关键是:实现服务器的人是否应该依赖Web开发人员来遵守规范?我的猜测是,他们不会对这种想法感到太舒服。规范基本上是一组规则。如果您希望能够说“我的服务器遵循这套规则”,那么您就无法依赖第三人的行为。把自己放在鞋子里。你会怎么做?您是否依赖某些开发人员或确保您的服务器遵守规则? 我相信大多数人会做出同样的决定,即默认禁止访问并提供某种扩展点。现在,如果这是一个好的决定或坏的决定,只有时间会证明。毕竟,规格也在不断发展。我希望现在更清楚了

答案 3 :(得分:-1)

与Servlet 3兼容的容器

WEB-INF / lib中JAR中的META-INF / resources目录中的任何内容都会自动公开为静态资源。