-2

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

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

Servlet 映射代码

这就是我尝试将 Servlet 映射到/META-INFURL 的方式。但它没有用:

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

小服务程序规范

Java Servlet 规范 3.1,章节 SRV.9.6 Web 应用程序存档文件:

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

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

4

4 回答 4

1

/META-INF//WEB-INF/文件夹是 Java Web 应用程序中的特殊文件夹。在正常情况下,任何正常的 servlet 容器都不会让您访问这些文件夹中的任何内容,因为它们通常包含非常敏感的数据,不会向公众公开。如果您的应用程序部署在<context>预期之下<context>/META-INF/*并且<context>/WEB-INF/*任何人都无法访问。

如果可能,请依赖另一个 URL;我认为没有充分的理由从/META-INF/.

但是,如果您确实需要此 URL 完全是这样,我会解决一个技巧并使用mod_proxy在您的应用程序前面设置一个 Apache Web 服务器。

在那里你可以说类似

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

(由 hart 编写,请务必检查确切的语法。)这会将所有外部请求重定向/META-INF/到您自己的应用程序/metaInf/文件夹,并且到外部世界,您似乎正在从/META-INF/.

但正如前面所说,除非你有非常具体的理由,否则你真的不想做某事。

于 2013-08-14T10:52:26.267 回答
1

I believe what you are asking is not possible at the application level. The specification talks only about the META-INF folder, but the URL is implied as well. I am using the term "implied" here because let's think for a minute the consequences of a server allowing you to do what you want.

If a server allowed the /appcontext/META-INF url to reach one of your filters/servlets then it has no way of knowing if you (the developer) would handle that case according to the specification or not. So strictly speaking, it does not fully conform to the specification. Even worse, it relies on the web developer to do that. If that was the case, then for every web application where the default behaviour was desired (i.e. META-INF to not be accessible), a developer would have to implement a servlet/filter to do something that the server should be doing in the first place (!)

So I believe that what you ask can only be available at a server level and only if the server allows you that i.e. if the server gives you a configuration option to do that, or allows you to write your own interceptor class to handle the request in a way different then the default behaviour.

In Tomcat 7 for example META-INF access is forbidden in the StandardContextValve class in its invoke() method:

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;
    }
    ...
}

So you would have to create your own Valve implementation (i.e. an AllowMetaInfAccessValve that would basically be a copy of the above class without that "disallow" check), package it in a jar and put it in the <TOMCAT_HOME>/lib folder.

Then in your server.xml you would declare something like below. Using that approach URLs that attempt to access the META-INF folder, would then reach your servlet and would be you own responsibility.

...
<Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true">
    ...
    <Valve className="com.mypackage.valves.AllowMetaInfAccessValve" allow="true"/>
    ...
</Host>
...

Update: To clarify my reasoning a little more: It is true that a servlet could do many things other than serving files from META-INF folder. But it could also do just that. Or even worse it would be sufficient for a web developer to just forget to forbid access, for the META-INF folder to become accessible.

The point here though is not what the servlet would or would not do. The point is: should the people that implemented the server depend on the web developer to conform to the specification? My guess is that they wouldn't feel too comfortable with that thought. A specification is basically a set of rules. If you want to be able to say "my server follows that set of rules" you cannot depend on what a third person would do. Put yourself in their shoes. What would you do? Would you depend on some developer or make sure that your server follows the rules?
I believe that most people would make the same decision i.e. by default forbid access and provide an extension point of some sort. Now if this is a good decision or a bad one, only time will tell. After all, specifications evolve too. I hope it is more clear now

于 2013-08-14T13:49:26.777 回答
1

使用“META-INF”作为上下文名称没有任何限制(据我所知,上下文名称根本没有限制——至少我在Servlet 3.0 规范中找不到任何内容)。

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

编辑:回复您的评论和问题编辑,尽管您的问题仍然令人困惑:

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

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

您可以做的一件事是添加一个自定义 404 响应来满足您的需求。

于 2013-08-07T20:43:59.813 回答
-1

Servlet 3 兼容容器

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

于 2013-08-07T21:19:10.377 回答