You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Christopher Schultz <ch...@christopherschultz.net> on 2009/06/02 19:15:56 UTC

Re: Caching of static content

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Jukka,

On 5/19/2009 7:58 AM, Jukka Raanamo wrote:
> I was trying to create a Filter that generates the some content as files (if
> required) into the file system and lets the default servlet handle the rest.

Interesting idea.

> However I noticed that if the uri was such that TC would interpret it as
> "static content" like /foobar.html - I would get a 404 on the first request.
> If the uri refers to more dynamic content such as /foobar.jsp - you don't
> get a 404.

Let's see your code...

>     public void doFilter(ServletRequest request, ServletResponse response,
>             FilterChain chain)
>             throws IOException, ServletException {
> 
>         HttpServletRequest httpRequest = (HttpServletRequest) request;
>         String uri = httpRequest.getRequestURI();
> 
>         // assumes not deployed as ROOT
>         String relativeURI = uri.substring(uri.indexOf("/", 1),
> uri.length());

Why assume non-ROOT deployment? It's just as easy to use
ServletContext.getContextPath() than it is to arbitrarily chop
characters out of a URI.

>         if (relativeURI.equals("/")) {
>             relativeURI = "index.jsp";
>         } else if (relativeURI.endsWith("/")) {
>             relativeURI += "index.jsp";
>         }

This seems like a bad idea: why not just leave the URI alone?

>         try {
> 
>             createFile(relativeURI);
> 
>             if (request.getParameter("include") != null) {
>                 httpRequest.getRequestDispatcher(relativeURI).
>                         include(request, response);

What is this "include" parameter? Is that something else for testing?
Why not set up better tests from outside (that use includes) rather than
trying to rig them this way?

>             } else if (request.getParameter("forward") != null) {
>                 httpRequest.getRequestDispatcher(relativeURI).
>                         forward(request, response);
>             } else {
>                 chain.doFilter(request, response);
>             }

You will definitely have to capture the response to the request which is
a non-trivial exercise. I have written code to do this (and more) which
can be found in the archives for this list here:
http://marc.info/?l=tomcat-user&m=123603411023864&w=2

>     private void createFile(String relativeURI) throws Exception {
>         String webAppDir = filterConfig.getServletContext().getRealPath("");
>         File contentFile = new File(webAppDir, relativeURI);
> 
>         contentFile.getParentFile().mkdirs();
> 
>         FileWriter writer = new FileWriter(contentFile);

This is going to be a problem. You should store your files somewhere
other than the webapp directory or things are going to be a real headache.

>         writer.write("<html><body>" +
>                 "<pre>" +
>                 "Current Servlet time: " + new Date() +
>                 "<br/>" +
>                 "Current JSP time:     <%=new java.util.Date()%><br/>" +
>                 "</pre>");

That doesn't seem to capture the server's response.... or are you just
trying to see if your technique will work before you implement everything?

It appears that you are trying to capture content, write a file into the
webapps directory, and then have the DefaultServlet serve that content
for you. That's not going to work because of two things:

1. Webapp deployment sometimes doesn't allow you write to the webapps
   (or other deployment) directory

2. The DefaultServlet does its own caching of directory information
   (which I find irritating, honestly) so that newly-created files
   are not always (or ever?) able to be served by it. You will probably
   have to do your own interception of the request and serve the bytes
   yourself. You have already seen that disabling caching makes this
   work.

Finally, you are messing with the URI by changing "/" to "index.jsp" and
other foolish things like that. If you need to make-up a name for the
file, make up something that is used solely for the filename, instead of
re-writing the URI that you use for request dispatching.

Making those changes will surely help.

- -chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAkolXksACgkQ9CaO5/Lv0PBSKgCgimJQlCRi6eab/xsEfVE/3GrC
OQMAn2wBeSJzFWdJEL0nw+oG/IyZsO5J
=M+P4
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: Caching of static content

Posted by jraanamo <ju...@gmail.com>.


Christopher Schultz-2 wrote:
> 
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> 
> 
> Why assume non-ROOT deployment? It's just as easy to use
> ServletContext.getContextPath() than it is to arbitrarily chop
> characters out of a URI.
> 
> 
> 1) This is just a mock Filter to reproduce the behaviour. I guess I should
> have mentioned this but I though I that the code was a clear statement of
> this - at least the createFile -method if nothing else.
> 
> 
> What is this "include" parameter? Is that something else for testing?
> Why not set up better tests from outside (that use includes) rather than
> trying to rig them this way?
> 
> 2) See section 1. above and my initial test uri's, e.g.
> /somenewdirectory/?forward=1 - this was to easily test if forwarding and
> including behaves differently.
> 
> 
> This is going to be a problem. You should store your files somewhere
> other than the webapp directory or things are going to be a real headache.
> 
> 3) Like said - a demo.
> 
> 
> That doesn't seem to capture the server's response.... or are you just
> trying to see if your technique will work before you implement everything?
> 
> 4) Yes! Or else I've written an Filter that really does not do anything
> smart - would not be the first time though. 
> 
> 
> It appears that you are trying to capture content, write a file into the
> webapps directory, and then have the DefaultServlet serve that content
> for you. That's not going to work because of two things:
> 
> 5) Fairly close to my initial problem description: 
> 
> I was trying to create a Filter that generates the some content as files
> (if
> required) into the file system and lets the default servlet handle the
> rest.
> 
> 
> 1. Webapp deployment sometimes doesn't allow you write to the webapps
>    (or other deployment) directory
> 
> 6) Now this is a good point but I don't know how this is restricted else
> than by the file system. I usually only work with Tomcat - maybe there are
> other restrictions with other servlet containers - do you know?
> 
> 
> 2. The DefaultServlet does its own caching of directory information
>    (which I find irritating, honestly) so that newly-created files
>    are not always (or ever?) able to be served by it. You will probably
>    have to do your own interception of the request and serve the bytes
>    yourself. You have already seen that disabling caching makes this
>    work.
> 
> 7) Yes, I sort of figured this out which is why I posted the question in
> the first place - instead of starting to read through the DefaultServlet
> code (which I should have done). And my badly formulated question: 
> 
>  how to force TC to check if file exists in real time?
> 
> should have stated how to disable DefaultServlets internal caching
> 
> And the reason why I did not want to write the content into the response
> stream in the first place was - if you noticed - the content was JSP
> files.  I really wanted the DefaultServlet to handle the file processing
> and keep the Filter non intrusive of what ever else was in the webapp
> processing chain (e.g. other Filters like Sitemesh etc).
> 
> 
> Finally, you are messing with the URI by changing "/" to "index.jsp" and
> other foolish things like that. If you need to make-up a name for the
> file, make up something that is used solely for the filename, instead of
> re-writing the URI that you use for request dispatching.
> 
> 8) I thought we agreed there was no name calling!? Playing around with
> URI's can be a lots of fun - especially if you think of those three small
> letters: S.E.O.
> 
> 9) To sum it up. I only wanted to know how to get around the internal
> caching of dynamic content what comes to DefaultServlet. And as "Lyallex"
> asked me, my work-around was to generated the files outside the servlet
> container and have Tomcat just serve them. Much cleaner solution but also
> not so flexible what comes to more "personalized" content.
> 
> 
> Making those changes will surely help.
> 
> - -chris
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.9 (MingW32)
> Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
> 
> iEYEARECAAYFAkolXksACgkQ9CaO5/Lv0PBSKgCgimJQlCRi6eab/xsEfVE/3GrC
> OQMAn2wBeSJzFWdJEL0nw+oG/IyZsO5J
> =M+P4
> -----END PGP SIGNATURE-----
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
> 
> 
> 

-- 
View this message in context: http://www.nabble.com/Caching-of-static-content-tp23614901p23975925.html
Sent from the Tomcat - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org