【问题标题】:Why Filter checks the included *.js files?为什么过滤器检查包含的 *.js 文件?
【发布时间】:2012-03-31 18:00:19
【问题描述】:

在我的 Web 应用程序(Apache Tomcat 7、JSP、Servlet)中,我使用了过滤器。在doChain 方法中,我输入了以下代码:


public void doFilter(ServletRequest request, ServletResponse response, 
                    FilterChain chain) throws IOException, ServletException {

        HttpServletRequest req = (HttpServletRequest) request;
        System.out.println(req.getServletPath());

//... until doFilter
}

现在,我不明白为什么有时在控制台中我打印了 JSP 中包含的 JavaScript 文件路径(任何 *.js 文件)。 *.css 文件不会发生这种情况,只有 *.js 文件会发生这种情况。更重要的是,我每次访问 Servlet 时都不会打印 *.js 文件。我觉得那是随机打印的。

有人对此有解释吗? 为什么会随机发生?

谢谢。

编辑:实际上它也发生在 *.png 文件中。但考虑到这个问题的随机性,其他文件(包括 CSS)的行为可能相同。

注意:

  1. 我尝试根据页面路径进行身份验证,这就是我尝试这样做的原因。问题是我不想考虑 *.js 页面。
  2. 如果您想要一些代码,请告诉我。

更新

servlet 中的一个通用代码:



@WebServlet("/site/network") public class NetworkSettingsServlet extends HttpServlet {

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    //... business logic goes here

    request.getRequestDispatcher("/site/network/network_view.jsp").forward(
            request, response);
    //TODO log this authentication
}

}

还有 network_view.jsp 代码:



<?xml version="1.0" encoding="UTF-8" ?>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<%@include file="/site/fragments/lang.jspf"%>
<fmt:setLocale value="${siteLanguage}" />
<fmt:setBundle basename="i18n.network.network" var="networkBundle" />
<fmt:setBundle basename="i18n.home.home" var="homeBundle" />

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" href="/netnfork/stylesheets/commons.css" />
<script type="text/javascript" src="/netnfork/site/scripts/network/network_scripts.js"></script>
<title><fmt:message key="common_title" bundle="${homeBundle}" /></title>
</head>
<html>

html code here

</html>

这就是我的代码中的模式。

【问题讨论】:

  • 是的,我们可以从web.xml 中看到 servlet 映射。另外,如果你直接从浏览器或者curl访问js文件,消息是不是也随机打印出来的?
  • @TomaszNurkiewicz 当我直接访问 JSP 文件时,我没有将 *.js 文件打印到控制台,但由于某些逻辑,JSP 会抛出错误。无论如何,这不应该影响我感兴趣的行为。与web.xml相关:如您所见,我使用Servlet3.0注释。

标签: jsp servlets servlet-filters


【解决方案1】:

我知道两种解决方案:

  1. 您可以为 js 文件添加“默认”servlet。

所以,web.xml 看起来像这样:

<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.js</url-pattern>
</servlet-mapping>

2 您必须在过滤器类中添加 shouldExclude() 方法。 如果您不想传递 *.js 文件,这是一个示例:

public void doFilter(ServletRequest request, ServletResponse response, 
                FilterChain chain) throws IOException, ServletException {

    if(shouldExclude(req)) {
          chain.doFilter(req, res);

    }
}



private boolean shouldExclude(ServletRequest req) {
     if(req instanceof HttpServletRequest) {
         HttpServletRequest hreq = (HttpServletRequest) req;
         return (hreq.getRequestURI().endsWith(".js"));
     }
     return false;
}

【讨论】:

  • 感谢您的解决方案。只是一个问题:default 是我的 Servlet 名称(因此可以替换为任何其他名称)还是标准名称(您不能更改)?
  • 它是标准名称,因此您无法更改它。 DefaultServlet 是为 Tomcat 中的静态资源(jpg、html、css、gif 等)提供服务的 servlet。您可以查看source code 了解更多信息。
  • 嘿,我尝试了你的两种方法,但它根本不起作用!
  • 抱歉,我忘了在过滤器中添加 shouldExclude() 调用。请检查我编辑的答案。
  • #1 毫无意义。它已经由默认 servlet 提供服务。
【解决方案2】:

当它没有被调用时,那么有问题的资源只是从浏览器缓存中加载的。这是一件好事,因为它节省了网络带宽和服务器负载,从而提高了双方的性能。

如果您真的坚持必须在每次请求时从服务器下载所有这些资源,那么您需要扩展过滤器以添加指示浏览器不 缓存这些响应。

HttpSerlvetResponse res = (HttpServletResponse) response;
res.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
res.setHeader("Pragma", "no-cache"); // HTTP 1.0.
res.setDateHeader("Expires", 0); // Proxies.

不要忘记在测试前清除浏览器缓存。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-31
    • 1970-01-01
    • 2020-06-03
    相关资源
    最近更新 更多