views:

2146

answers:

3

I'm building a Spring MVC web application with Tiles/JSP as the view technology. Previously I stored the paths to common images in class Common:

 public final static String IMG_BREADCRUMBS_NEXT = "/shared/images/famfam/bullet_arrow_right.png";

Then I would use this class in jsp to get the image src like

 <img src="<%= Common.IMG_BREADCRUMBS_NEXT %>"/>

I would like to get rid of scriptlets in my jsp code and use jstl etc. instead. What is the best way to store this kind of information? Is it resource bundles? How have you solved this?

+1  A: 

Use a configuration bean in application scope, so you can write something like

<img src="${configuration.imagePath}/icon.png">

I don't use Spring, but you can probably use dependency injection to do something similar to what we do in JBoss and Seam.

Basically, we have a POJO class called Configuration whose properties are the application's configuration parameters, loaded from an XML configuration (actually a JBoss MBean, but that's off-topic). In this example, our bean would have a getImagePath() method.

Seam will take care of instantiating a single instance of the configuration bean in 'application' scope, so that it is always available to use in expressions, like the one above.

Peter Hilton
Could you elaborate a little on this approach? Thanks.
kosoant
+2  A: 

In the end I used Spring's theme support to achieve what I wanted. In my view code I use the <spring:theme code=""/> tag to get the path to image file:

 <img src="<spring:theme code="theme.images.actions.edit.link"/>" />

This tag behaves like any <fmt:message> or <spring:message> tag, but it has its own "message bundles". The necessary configurations in my applicationContext are:

 <!-- 
 ========================================================= 
 Themes
 =========================================================
  -->
<bean id="themeResolver" class="org.springframework.web.servlet.theme.SessionThemeResolver">
 <property name="defaultThemeName" value="themes.default"/>
</bean>
<bean id="themeSource" class="org.springframework.ui.context.support.ResourceBundleThemeSource" />

All themes of my application are stored under /WEB-INF/classes/themes/. The default theme properties are in /WEB-INF/classes/themes/default.properties It looks like this:

 ...
 theme.images.actions.show.link=/@contextPath@/shared/images/famfam/zoom.png
 theme.images.actions.delete.link=/@contextPath@/shared/images/famfam/cross.png
 ...

To change the theme (and icons) of my app I use a ThemeChangeInterceptor (in applicationContext)

<!--
========================================================= 
Theme resolving
=========================================================
--> 
<bean id="themeChangeInterceptor" class="org.springframework.web.servlet.theme.ThemeChangeInterceptor">
 <property name="paramName" value ="theme" />
</bean>

This enables the user to switch the theme via a "&theme=themes.default" or "&theme=themes.alternative" request parameter.

One key part of my setup is the @contextPath@ in the theme properties file. This is replaced during the Ant build process with the correct context path for development/testing/production environment. The key part of my build.xml is:

 <!-- copy all common themes to classes -->
 <copy todir="${build.war}/WEB-INF/classes/themes" overwrite="true" filtering="true">
  <fileset dir="resources/themes" includes="**/*.properties" />
  <filterchain>
           <replacetokens>
                <token key="contextPath" value="${setup.contextPath}"/>
            </replacetokens>
        </filterchain>
 </copy>

I hope this gives you a "running start" on Spring web app themes. In my opinion this setup makes it quite easy to alter the look and feel of an application.

References:

kosoant
A: 

Wouldn't it be more robust to use a class that determined the theme based on a database. This would allow users to administer themes and even implement themes based on time or the user-agent?

Would it be possible to do this and use spring themes at the same time, to save the theme in the users session?

tariqj