2

I have implemented the OpenSessionInViewFilter for my MVC webapp and it works almost perfect. Only problem is that it also creates a session for every image, js, css etc that are requested from the webserver. This i dont want.

Im using struts2, spring and hibernate and this is my web.xml

<filter>
    <filter-name>lazyLoadingFilter</filter-name>
    <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>lazyLoadingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

So because i am mapping url-pattern /* it also takes all the images etc.. I tried setting it to *.jsp, and *.action, but then i get the lazyloading-exceptions again... How should i do this? I've been looking for answers for 5 hours now and im getting a litle bit crazy in my head.

All i need to do is to make this filter IGNORE all the static resources. Thats it! And for everything else it can run. It sounds so simple, but its really really annoying me that i cant figure out how.

Any help would be greatly appriciated.

Do i need to extend the filter to write my own filter and exclude within it? And if so. How?

EDIT: It seems like i could set up filter-mappings for my static files at the top of the filter-chain. And then send those to a "ByPassFilter", thus bypassing the filterchain for these static resources. Is this the way to go??

Thanks guys!

user829237
  • 1,719
  • 8
  • 37
  • 61

5 Answers5

1

The general practice in such a scenario is to use the combination of Apache Web server with an application server (Tomcat/JBoss) with mod_jk module.

Here is link describing how to use this combination. (Another link)

The chief advantage of using this configuration is

  1. Static content can be served by Apache web server.
  2. The dynamic content requests (like *.jsp, *.action etc) are delegated to tomcat.
  3. There are may other useful modules like content compression for static contents hence improving the response time.
  4. Its more secure than the scenario wherein the app server is serving everything.

I understand this may not be precisely the solution you looking for, I suggested this as this is a general practice.

Santosh
  • 17,667
  • 4
  • 54
  • 79
0

As far as your implementation of having a Bypassfilter is considered , if you have such a filter in front then once you skip the next filter in filter chain then basically the rest of filters in the chain will also get skipped (which doesn't seem to be a desirable thing to do in most situations ) . Also as the filter invocations for a request behave like

Filter1 -> Filter2 -->Struts Action/BL --> Filter 2 -->Filter 1

Hence the OpenSessionInViewFilter will kick in after the request is processed in your struts action ( which can be avoided by placing another bypass filter after open session in view filter in web.xml ) . However overall it has always appeared undesirable to me to skip the entire filter chain for skipping a single filter .

I haven't ever faced a need to skip OpenSessionInViewFilter ever , however if i had to do it then instead of having a Bypassfilter i would have a filter extending the OpenSessionInViewFilter filter which would be skipping my static resources from processing .

jay
  • 791
  • 8
  • 20
  • Yes. I just did your last comment here. I did extend the filter to exclud the static content. So now it works perfect. However, im a bit confused as to why I'm seemingly the only one doing this. Why would anyone want to open a session for static content? – user829237 Apr 26 '12 at 11:24
  • "Necessity is the mother of invention" might be the reason for you doing it :) , people might not be facing issues that you are facing or they simply get around those issues by someway or other :) . Meanwhile if you had separate/distinct url's for your actions and different url's for your static content then your filter mapping would have been sufficient enough to tackle the situation . – jay Apr 26 '12 at 11:45
  • @user829237, I had to do that additional filtering too. I set the url-pattern to "*.do" for my struts application, but didn't want to create a session for *all* of the struts actions, so I added some code to my custom filter. Let me know if you want to see it? – Randy Stegbauer Apr 27 '12 at 19:45
0

Include only those elements of the pattern that you need.

Something like this:

<filter-mapping>
    <filter-name>lazyLoadingFilter</filter-name>
    <url-pattern>*.html</url-pattern>
    <url-pattern>/profile/edit</url-pattern>
    <url-pattern>/cars/*</url-pattern>
</filter-mapping>
0

Just in case someone needs a solution with extending OpenSessionInViewFilter. It prevents Hibernate session creation for pre-defined static resources.

/**
 * Skips OpenSessionInViewFilter logic for static resources
 */
public class NonStaticOpenSessionInViewFilter extends OpenSessionInViewFilter {

    static final Pattern STATIC_RESOURCES = Pattern.compile("(^/js/.*)|(^/css/.*)|(^/img/.*)|(^/fonts/.*)|(/favicon.ico)");

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String path = request.getServletPath();
        if (STATIC_RESOURCES.matcher(path).matches()) {
            filterChain.doFilter(request, response);
        } else {
            super.doFilterInternal(request, response, filterChain);
        }
    }

}

Basically Spring should have provided some property like excludePatterns for OpenSessionInViewFilter.

vladimir83
  • 509
  • 3
  • 10
-1

I totally agree with the answer from @Santosh.

the OpenSessionInViewFilter creates a resource and adds it the the ThreadLocal object, if the session is never used then the session is never actually created, this also means that a db connection is not used for that request. ( this is probably the answer to your question ).

If you still require to control things you can always create another filter extending the OpenSessionInViewFilter and execute the getSession method based on which resource is being called.

Anantha Sharma
  • 9,920
  • 4
  • 33
  • 35
  • 1
    Well, actually i get some quite different results than your first statement. "If the session is never used then the session is never actually created" - If I clear my cache and reload my main-page, then i do get max_open_connections error from the db. (It is set to 20), and the stacktrace will tell me that the error was caused while trying to get a session while getting a static file. – user829237 Apr 26 '12 at 11:06
  • do you have a connection pool to to get the connections? if hibernate is managing the connections (without a pool) then this is an expected behaviour – Anantha Sharma Apr 26 '12 at 11:57