3

[上下文] tomcat 7 - java 1.7

嘿大家; 我正面临着陌生人的工作。在我的 web.xml 文件中,我映射了这样的请求:

web.xml

<web-app>
    <filter>
        <filter-name>filter</filter-name>
        <filter-class>demo.DemoFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>filter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <servlet>
        <servlet-name>Servlet</servlet-name>
        <servlet-class>demo.DemoServlet</servlet-class>
    </servlet>

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

DemoFilter.java(实现过滤器)

@Override
public void doFilter( ServletRequest req, ServletResponse res, FilterChain chain )
        throws IOException, ServletException
{
    try
    {
        chain.doFilter(req, res);
    }
    catch ( Exception e )
    {
        System.err.println("error");
        ((HttpServletResponse) res).setContentType("text/html");
        ((HttpServletResponse) res).setStatus(HttpServletResponse.SC_NOT_FOUND);
        res.getWriter().write("foo");
    }
}

DemoServlet.java(扩展 HttpServlet)

@Override
protected void doGet( HttpServletRequest req, HttpServletResponse resp )
        throws ServletException, IOException
{
    System.err.println(req.getRequestURI());
    throw new RuntimeException("ERROR");
}

[1 = 预期结果]首先,当我尝试请求“/foo/bar”时,过滤器和 servlet 被调用(并且页面显示单词 'foo')。控制台结果:

/foo/bar    
error

[2 = Unexpected result]然后,当我尝试请求“/WEB-INF/foo/bar”时,什么都没有调用(我的过滤器和我的 servlet 没有被命中)并且我得到一个 Tomcat 错误报告:

HTTP Status 404 -

type Status report

message

description The requested resource is not available.
Apache Tomcat/7.0.30

编辑:在这里,我希望得到以下结果:

/WEB-INF/foo/bar    
error

我的目标是使用我的过滤器来处理异常(包括“/WEB-INF”调用)。

  • 为什么以“/WEB-INF/”开头的请求永远不会命中映射在“/*”模式上的过滤器/servlet?
  • 我们如何解决这个问题?

提前致谢!

PS:我想保留我当前的 web.xml 配置(“url-pattern”=“/*”;不使用“error-page”)


编辑我的问题被误解了。我不想在我的“WEB-INF”目录下提供文件访问。我想用我的过滤器和 Servlet (url-pattern='/*') 来处理每个请求,即使请求 URI 以“/WEB-INF/”开头。谢谢 !

4

5 回答 5

6

这里有一个重大的概念误解。中的资源/WEB-INF根本无法公开访问。您提出问题的方式表明并非如此。这个不对。我相信您只是以错误的方式询问了具体问题

根据评论,我了解到您想要记录访问的文件/WEB-INF以及 404 错误。我您实际上的意思是要在直接请求的资源旁边记录转发、包含和错误的资源。通常,转发和包含的资源确实是隐藏的,/WEB-INF以防止直接访问。

默认情况下,过滤器仅在直接请求的资源上调用,而不是在转发和包含的资源上,也不是在错误的资源上(如您的 404 尝试)。为此,您需要将适当的<dispatcher>条目添加到映射中:

<filter-mapping>
    <filter-name>filter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
    <dispatcher>ERROR</dispatcher>
</filter-mapping>

(它们中的每一个都是可选的;REQUEST完全不存在时是默认的)

这样,过滤器不仅会拦截直接请求的资源,还会拦截转发、包含和错误的资源。调度程序也将ERROR使其启动 404 错误。

于 2012-12-30T22:22:51.250 回答
2

WEB-INF 目录是 Web 应用程序的私有区域,WEB-INF 目录下的任何文件都不能通过像您指定的方式指定 URL 直接从浏览器访问。

Web 容器不会提供此目录的内容。但是,类可以访问此目录的内容,例如您在应用程序内的 web.xml 中映射的 servlet。

于 2012-12-30T18:41:51.083 回答
2

如果要限制对某些文件的直接 URL 访问,请将它们放在 WEB-INF 目录下。

从这里引用: http ://www.servletworld.com/servlet-tutorials/web-application-directory-structure.html

WEB-INF 目录是 Web 应用程序的私有区域,WEB-INF 目录下的任何文件都不能通过指定 URL 直接从浏览器访问,http://somesite/WEB-INF/someresource.html. Web 容器不会提供此目录的内容。但是,应用程序中的类可以访问 WEB-INF 目录的内容。因此,如果您不希望从 Web 浏览器直接访问 JSP 或 HTML 文档等任何资源,则应将其放在 WEB-INF 目录下。

于 2012-12-30T18:42:22.700 回答
0

发布的两个答案都是正确的,这对于您使用的任何应用程序服务器和 JDK 都是一样的。尽管从 servlet 规范 3.0 web.xml 是可选的,或者您可以使用 web-framgment.xml 来破坏 web.xml。

于 2012-12-30T19:01:45.000 回答
0

根据 servlet 规范,来自客户端的任何访问 WEB-INF/ 目录中资源的请求都必须返回一个 SC_NOT_FOUND(404) 响应。请参阅第 10.5 节目录结构。

https://download.oracle.com/otn-pub/jcp/servlet-3_1-fr-eval-spec/servlet-3_1-final.pdf https://download.oracle.com/otn-pub/jcp/servlet -3.0-fr-eval-oth-JSpec/servlet-3_0-final-spec.pdf

于 2020-02-21T19:30:37.990 回答