Serve static files with guice servlet

1,522 views
Skip to first unread message

decitrig

unread,
Nov 17, 2010, 4:46:33 PM11/17/10
to google-guice
I could swear I saw something on serving static files through guice
servlet somewhere, but I can find it now, if it ever existed. Right
now I have guice servlet listening on /app/* urls, so that, for
example, /index.html won't go through the servlet. I would like to be
able to listen on /* and have /index.html served up statically (it's a
GWT host page). Any suggestions?

Kazimierz Pogoda

unread,
Nov 18, 2010, 4:45:36 AM11/18/10
to google...@googlegroups.com
You can pass everything /* through GuiceFilter in web.xml, and then in
your ServletModule:

serveRegex("^((?!^/index\\.html$|^/test\\.html$).)*$").with(MyServlet.class)

It will pass every URI to your servlet, except /index.html and
/test.html which will be served by servlet container's default
servlet. Maybe this useful trick should be documented in ServletModule
documentation? It could help a lot when defining request authorization
with filterRegex, which I consider guice-servlets's unique feature.

> --
> You received this message because you are subscribed to the Google Groups "google-guice" group.
> To post to this group, send email to google...@googlegroups.com.
> To unsubscribe from this group, send email to google-guice...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/google-guice?hl=en.
>
>

--
"Meaning is differential not referential"

kazik 'morisil' pogoda
http://www.xemantic.com/ http://blog.xemantic.com/

decitrig

unread,
Nov 18, 2010, 8:42:18 PM11/18/10
to google-guice
On Nov 18, 4:45 am, Kazimierz Pogoda <hsh...@gmail.com> wrote:
> You can pass everything /* through GuiceFilter in web.xml, and then in
> your ServletModule:
>
> serveRegex("^((?!^/index\\.html$|^/test\\.html$).)*$").with(MyServlet.class )

Aesthetically, I think I prefer having a url prefix for the guice
filter. Neither seem to be ideal; I would love something like

serveStatic("/index.html").with(new File("war/static/index.html"))

I'm no servlet expert, but it seems like this could be implemented in
the guice servlet by having a map of urls to files, and maybe a
another servlet that just spits out the file contents when asked for.

--
rwsims

> It will pass every URI to your servlet, except /index.html and
> /test.html which will be served by servlet container's default
> servlet. Maybe this useful trick should be documented in ServletModule
> documentation? It could help a lot when defining request authorization
> with filterRegex, which I consider guice-servlets's unique feature.
>
> On Wed, Nov 17, 2010 at 10:46 PM, decitrig <rws...@gmail.com> wrote:
> > I could swear I saw something on serving static files through guice
> > servlet somewhere, but I can find it now, if it ever existed. Right
> > now I have guice servlet listening on /app/* urls, so that, for
> > example, /index.html won't go through the servlet. I would like to be
> > able to listen on /* and have /index.html served up statically (it's a
> > GWT host page). Any suggestions?
>
> > --
> > You received this message because you are subscribed to the Google Groups "google-guice" group.
> > To post to this group, send email to google...@googlegroups.com.
> > To unsubscribe from this group, send email to google-guice...@googlegroups.com.
> > For more options, visit this group athttp://groups.google.com/group/google-guice?hl=en.

Moandji Ezana

unread,
Nov 19, 2010, 3:34:56 AM11/19/10
to google...@googlegroups.com

You could do the opposite and first list the urls or folders that are served by a StaticServlet that simply forwards to the resource, and fall back on /* for everything else.

Moandji

--
www.moandjiezana.com

Sent from my Android

Philippe Beaudoin

unread,
Nov 19, 2010, 5:34:51 AM11/19/10
to google...@googlegroups.com
I ran into a similar problem before, which I solved by updating my
deployment descriptor to serve these files as static. In my case I was
using AppEngine and the process is described here:
http://code.google.com/appengine/docs/java/config/appconfig.html#Static_Files_and_Resource_Files

I would be surprised if you couldn't do the same thing with a regular
Jetty or Tomcat server. But maybe there is a reason why you would like
these files to go through a servlet?

Cheers,

Philippe

Eric

unread,
Nov 19, 2010, 9:22:02 AM11/19/10
to google-guice


On Nov 18, 8:42 pm, decitrig <rws...@gmail.com> wrote:
> On Nov 18, 4:45 am, Kazimierz Pogoda <hsh...@gmail.com> wrote:
>
> > You can pass everything /* through GuiceFilter in web.xml, and then in
> > your ServletModule:
>
> > serveRegex("^((?!^/index\\.html$|^/test\\.html$).)*$").with(MyServlet.class )

You might want to use [.] instead of \\. for the literal period, or
even

/(?!index|test)[.]html$

for the whole regex. Character classes do not use the same
metacharacters
as regexes.

I don't understand why you need the last *. In fact, it's a bad idea
because *
matches zero instances of the item it modifies too. You have arranged
for
MyServlet to match everything.

Eric

Ryan Sims

unread,
Nov 19, 2010, 9:35:22 AM11/19/10
to google...@googlegroups.com
On Fri, Nov 19, 2010 at 5:34 AM, Philippe Beaudoin
<philippe...@gmail.com> wrote:
> I ran into a similar problem before, which I solved by updating my
> deployment descriptor to serve these files as static. In my case I was
> using AppEngine and the process is described here:
>  http://code.google.com/appengine/docs/java/config/appconfig.html#Static_Files_and_Resource_Files

In my case, I'm running the GWT Jetty server locally, but it's going
to be deployed to a different container (not sure which one yet). So
putting the configuration in guice-servlet would keep things cleaner.

> I would be surprised if you couldn't do the same thing with a regular
> Jetty or Tomcat server. But maybe there is a reason why you would like
> these files to go through a servlet?

No, not really - quite the opposite; I'd like it to just get served
as-is. If running through a servlet is the best way to do that, fine.
I'd rather configure in guice than in some config file somewhere, and
this seems like something guice could do.

No worries - everything works fine with the url prefix, I'm just
speculating about a possible better way to do it.

Kazimierz Pogoda

unread,
Nov 19, 2010, 11:31:15 AM11/19/10
to google...@googlegroups.com
On Fri, Nov 19, 2010 at 3:22 PM, Eric <erja...@gmail.com> wrote:

> You might want to use [.] instead of \\. for the literal period,

I am not a regex expert - Is there any practical difference, or just a
matter of notation?

> or
> even
>
>    /(?!index|test)[.]html$

There is a reason I put each URI separately, in code it looks like:

serveRegex("^((?!" +
"^/index\\.html$|" +
"^/test\\.html$" +
").)*$") ...

, this way it is easy to add/remove new URIs. It could be convenient
to write some regex string producer which would take varargs of URIs,
escape all special characters, and join them all using guava's Joiner.

More practical example, serve everything with some dispatcher servlet,
except /images/* and /resources/*

serveRegex("^((?!" +
"^/images/.+|" +
"^/resources/.+" +
").)*$") ...

But returning to your proposal, see code below:

Pattern p = Pattern.compile("^((?!^/index\\.html$|^/test\\.html$).)*$");
out.println(p.matcher("/").matches());
out.println(p.matcher("/foo.html").matches());
out.println(p.matcher("/index.html_foo").matches());
out.println(p.matcher("/index").matches());
out.println(p.matcher("/index.html").matches());
out.println(p.matcher("/test.html").matches());

It returns:
true
true
true
true
false
false

However after replacing regex with:

/(?!index|test)[.]html$

It returns 6 x false which is not desired behavior. :(

--
"Meaning is differential not referential"

kazik 'morisil' pogoda
http://www.xemantic.com/ http://blog.xemantic.com/

Kazimierz Pogoda

unread,
Nov 19, 2010, 11:56:02 AM11/19/10
to google...@googlegroups.com
On Fri, Nov 19, 2010 at 2:42 AM, decitrig <rws...@gmail.com> wrote:
>> serveRegex("^((?!^/index\\.html$|^/test\\.html$).)*$").with(MyServlet.class )
>
> Aesthetically, I think I prefer having a url prefix for the guice
> filter. Neither seem to be ideal; I would love something like
>
> serveStatic("/index.html").with(new File("war/static/index.html"))
>
> I'm no servlet expert, but it seems like this could be implemented in
> the guice servlet by having a map of urls to files, and maybe a
> another servlet that just spits out the file contents when asked for.

AFAIR the servlet request handling sequence works the way, that after
all the filters, if no servlet mapping is resolved, the request goes
to so called default servlet (mapped to /*). Every servlet container
has own implementation of this. Here is one for jetty:

http://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java

It would be possibe to do something like:
bind(DefaultServlet.class).in(Singleton.class);
serve("/index.html").with(DefaultServlet.class);

,however AFAIR there are some drawbacks of mapping DefaultServlet to
something other than /*, at least on some servlet containers - the
path before * could be excluded from webapp context relative file
path. In some servlet containers the default servlet is declared with
name 'default' and you can use own mapping to this servlet in web.xml,
however it does not seem to be portable. The solution I proposed looks
ugly - I know it, however it seems to be portable, as long as we can
count on different default servlet implementations. :)

--
"Meaning is differential not referential"

kazik 'morisil' pogoda
http://www.xemantic.com/ http://blog.xemantic.com/

Reply all
Reply to author
Forward
0 new messages