0
votes

In my web application (Apache Tomcat 7, JSP, Servlet), I use a filter. In the doChain method I put the following code:


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

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

//... until doFilter
}

Now, I can't understand why, sometimes, in console I have printed the JavaScript files path that are included in the JSP (any *.js file). It doesn't happen with *.css files, only with *.js files. Even more, the *.js files are not printed every time I access the Servlet. I seemed to my that is printed randomly.

Has anyone an explanation on this? Why that happens randomly?

Thanks.

EDIT: Actually it happens also with *.png files. But taking in account the random character of this issue, it's possible to behave the same with other files (including CSS).

NB:

  1. I try to make an authentication based on the page path, that's why I try to do that. The problem is that I don't want to take in account the *.js pages.
  2. If you want to some code, let me know.

UPDATED

A common code in 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
}

}

And the network_view.jsp code:



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

That's the pattern in my code.

2
Yes, we can benefit from seeing servlet mapping from web.xml. Also, if you access the JS file directly from your browser or curl, is the message printed randomly as well? - Tomasz Nurkiewicz
@TomaszNurkiewicz When I access direct the JSP file, I don't get the *.js file printed to the console, but the JSP throws error due to some logic. Anyway, that should not affect the behavior that I'm interested in. Related to web.xml: as you can see, I use Servlet3.0 annotations. - artaxerxe

2 Answers

1
votes

When it's not been called, then the resource in question is simply been loaded from browser cache. It's a Good Thing as it saves network bandwidth and server load and thus improves performance for the both sides.

If you really insist that all those resources must be downloaded from the server on every single request, then you need to extend the filter to add response headers which instructs the browser to not cache those responses.

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.

Don't forget to clear the browser cache before testing.

-2
votes

I know two solutions for this:

  1. You can add the 'default' servlet for js files.

So, web.xml looks like this:

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

2 You'd have to add shouldExclude() method in filter class. Here's an example if you don't want to pass *.js files:

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