3

I had a working implementation of the SiteMeshFilter in my project, but since moving to extending AbstractAnnotationConfigDispatcherServletInitializer instead of WebApplicationInitializer my sitemesh filter isn't being used.

I've been trying to understand the following tutorials on Spring security http://blog.springsource.org/2013/07/03/spring-security-java-config-preview-web-security/ and http://tux2323.blogspot.co.uk/

Not sure if Security is getting in the way or I've mis-configured the Initializer/Dispatcher somehow....

The old config (extending WebApplicationInitializer):

@Override
public void onStartup(ServletContext servletContext) throws ServletException {
    AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
    ServletRegistration.Dynamic dispatcher = servletContext.addServlet("yhj dispatcher", new DispatcherServlet(applicationContext));
    dispatcher.addMapping("/");
    dispatcher.setLoadOnStartup(1);
    servletContext.addFilter("sitemeshFilter", new     SitemeshFilter()).addMappingForUrlPatterns(null, false, "/*");
applicationContext.register(MvcConfiguration.class);
}

New config (extending AbstractAnnotationConfigDispatcherServletInitializer):

    @Override
public void onStartup(ServletContext servletContext) throws ServletException {
    super.onStartup(servletContext);
    }
    @Override
protected String[] getServletMappings() {
    return new String[] {"/"};
}

@Override
protected Class<?>[] getRootConfigClasses() {
    return new Class<?>[] {SecurityConfig.class};
}

@Override
protected Filter[] getServletFilters() {
    return new Filter[]{new SitemeshFilter(), new DelegatingFilterProxy("springSecurityFilterChain") };
}

@Override
protected Class<?>[] getServletConfigClasses() {
    return new Class<?>[] {MvcConfiguration.class, PersistanceConfig.class};
}

The other config classes/SitemeshFilter haven't changed so I'm reasonably happy they are ok. Indeed I get a page complete with data from database when I hit the site, but it simply hasn't been styled up by Sitemesh. Possible the sitemesh filter isn't being hit?

SitemeshFilter.java:

public class SitemeshFilter extends ConfigurableSiteMeshFilter {
@Override
protected void applyCustomConfiguration(SiteMeshFilterBuilder builder) {
    builder.setMimeTypes("text/html", "application/xhtml+xml");
    builder.addDecoratorPath("/*", "/WEB-INF/templates/page.jsp");
  }
}
DaFoot
  • 1,475
  • 8
  • 29
  • 58

1 Answers1

0

I see three things that should be addressed:

  • The first is that in the new configuration the SitemeshFilter is being registered to only be applied for requests processed by the DispatcherServlet as apposed to every URL. To match the original configuration I'd update your SitemeshFilter to process every URL.

  • The second is that your original configuration does not mention Spring Security. If my feedback does not help, perhaps you can elaborate how you were doing this before (and provide the relevant configuration...ie web.xml).

  • I'd recommend ensuring that you apply springSecurityFilterChain to every URL rather than only URLs handled by the DispatcherServlet.

Making the following changes should address all the points above:

First remove getServletFilters()

Next create a class that looks like the following code:

public class SecurityWebApplicationInitializer 
     extends AbstractSecurityWebApplicationInitializer {

    protected void afterSpringSecurityFilterChain(ServletContext servletContext) {
        insertFilters(servletContext, new SitmeshFilter());
    }
}
Rob Winch
  • 21,440
  • 2
  • 59
  • 76
  • Thankyou for taking the time to respond. I've implemented the changes suggested, but Sitemesh is still not adding its decoration. I've added my SitemeshFilter code to th e question for reference. – DaFoot Aug 11 '13 at 22:55
  • How did you apply Spring Security before it broke? Can you include this setup? Does it work if you are not using Spring Security? – Rob Winch Aug 12 '13 at 13:24
  • I didn't, I'm trying to add security now. Which seems to be working in that I get denied access to some URLs as defined, but nothing styled up by Freemarker templates. – DaFoot Aug 13 '13 at 07:12
  • So if you use your new configuration, but do not use Security does it work? – Rob Winch Aug 13 '13 at 13:46
  • I tried removing SecurityConfig.class from the array returned by getRootConfigClasses() in my AbstractAnnotationConfigDispatcherServletInitializer extending class but get the following: SEVERE: Exception starting filter springSecurityFilterChain org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'springSecurityFilterChain' is defined So I guess that's not the correct way to remove the security layer...left Java classes in place, assuming as other config files don't ref those they don't get called. – DaFoot Aug 15 '13 at 18:43
  • Is it not problematic to have classes that extend AbstractSecurityWebApplicationInitializer and another that extends AbstractAnnotationConfigDispatcherServletInitializer? Don't they both extend/implement same Java that initialises the app - wouldn't that potentially cause duplicate init/errors? – DaFoot Aug 15 '13 at 18:47
  • 1
    If you try to initialize the Root ApplicationContext in both yes ti could cause errors, but since your subclass of AbstractSecurityWebApplicationInitializer does not pass in any configuration all it is doing is wiring up the springSecurityFilterChain as you normally would in web.xml. See here for the documentation that supports it (NOTE I am the one that wrote the documentation though ;) ) http://static.springsource.org/spring-security/site/docs/3.2.x-SNAPSHOT/guides/hellomvc.html#registering-spring-security-with-the-war – Rob Winch Aug 15 '13 at 20:59