• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Tomcat servlet-mapping bypass if real file requested

 
Ranch Hand
Posts: 114
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Is this possible at all? I know I can use a prefix or a suffix to be specific about the URI, but say I wanted to pass *all* requests via one particular servlet (front controller), except those which are directed a real file, can I do that?



It's even crossed my mind to have the servlet look if the file exists and then stream it back if it does, but dealing with mime types doesn't stike me as a fun task, and the overhead of doing this seems a bit silly really.

Even this would be a suitable solution for me if it were possible:



Where "void" means "don't use a servlet".

I'm basically looking to produce a clean URL mapper where the URL is parsed at runtime to determine what request parameters are in it (without the ?foo=bar mess).

Like this: http://www.symfony-project.com/book/trunk/09-Links-and-the-Routing-System

I guess if I were to check the URL at the first instance in the front controller I could minimize the overhead, and I can steal apache's mime-type list.
 
Sheriff
Posts: 13411
Firefox Browser VI Editor Redhat
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It's usually easier to do things the other way around and set up specific mappings when you DO want to go to a servlet.

This usually done with a prefix that looks like a directory
/command/* or with a specific file extension like *.do.

Then you don't need specific mappings for css, js, jpg, gif, pdf, and whatever else you might need to access from the client.
 
Chris Corbyn
Ranch Hand
Posts: 114
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yep, I do acknowledge that I'm experimenting as much as anything else really.

I got this to work pretty quickly. The first thing that happens in my front controller is the URI gets examined to see which action controller to dispatch. It's here that I do a simple check for a resource and stream it back as early as possible if something really does exist.



The CloseServletException is a bit of a hack really, but it gets my front controller to jump to the end of processing and just return.

Tested downloading a 684MB file (adobe photoshop dmg image), displaying images and using CSS. All works nice and fast

My inexperience probably shows in my coding though.

This probably all looks a bit pointless to you right now but there is method in my logic for doing this... somewhere
 
Ranch Hand
Posts: 489
Eclipse IDE Tomcat Server Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You could also fo it this way

Map all requests to your front controller servlet.
Place a Filter before your Servlet.

In the filter's doFilter() method, examine the request (the same logic as in your Front Controller from your last post). If the request is for a file, have the Filter serve the response back and don't pass on the request to the Servlet. Else do nothing, just pass it straight through.



You achieve 2 things this way.

1. The Servlet is still mapped to all requests.
2. The logic check is refactored away from the Servlet.

Just a suggestion.

cheers,
ram.
 
Chris Corbyn
Ranch Hand
Posts: 114
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks for the tip. I didn't know you could do that. Refactoring now

I'm hoping this will fix a big i've found in using my code with safari. Image/CSS etc are not understood in safri, unless you go directly to them in the browser. I can only conclude that Safari sends some other requests that aren't for files bceause:

This fails (unless you point your browser directly to the image, and dont <img src /> to it):



But this works (which I though would have the same effect):



The second one still pushes everything I *thought* was in the request through the servlet, but clearly I was wrong because Safari gives a broken image if you link to it via <img>, yet it works if you copy the <img src=??? > into the address bar. Confusing.

I'll lt you know if your method solves that I'll add some ETag and Last-Modified checks too which would speed things up further.
 
Chris Corbyn
Ranch Hand
Posts: 114
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
FYI, your suggestion worked a peach It fixed my wierd bug and it feels like it's being done in the proper place now. I've also moved my request routing/mapping logic into a filter.

The file check:


The request mapping is this:


Which builds a request router using a series of strategies checking how well they can interpret the URI and offering a "score". Config looks like this (suffixes and prefixes non-important).



The idea is that you can comletely configure the URL schema based on this XML file and you'll never need to use ?foo=bar style queries in the URL (like the symfony link I posted earlier).
 
Ben Souther
Sheriff
Posts: 13411
Firefox Browser VI Editor Redhat
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Safari (or any other browser for that matter) has no way of knowing what content on the server is static and what is dynamic. It just makes an HTTP request and receives an HTTP response.
[ August 19, 2007: Message edited by: Ben Souther ]
 
Chris Corbyn
Ranch Hand
Posts: 114
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Understood I'm not 100% what the problem was really with my first version, I just know that moving the code back a layer has helped, unless I inadvertently changed some logic along the way. I studied the headers that were being sent for a real file, and those for my streamed files and the only difference was ETag and Last-Modified.
 
I wasn't selected to go to mars. This tiny ad got in ahead of me:
a bit of art, as a gift, the permaculture playing cards
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic