Creating a mobile version of your website with Spring Mobile and Sitemesh
About a year ago I developed an Android app for my website, but as not everybody has an Android device I wanted to create a mobile version of my website. In the mobile version I want to present slightly different data to make it look more like the app. In this post I will show you how I have used Spring mobile to determine which version of the site the user wants to visit and how I used Sitemesh to select the correct decorator.
Spring mobile
Spring mobile provides you some nice features to either detect mobile devices or to give the user a choose between the “mobile” or “normal” site. In my case I want redirect the user to the mobile website based on the device and make the site available on a different URL (http://m.yourcoolsite.com).
If you happen to use maven (like me) you need to add the Spring Milestone Repository and the dependency:
<repository> <id>org.springframework.maven.milestone</id> <name>Spring Maven Milestone Repository</name> <url>http://maven.springframework.org/milestone</url> </repository> <dependency> <groupId>org.springframework.mobile</groupId> <artifactId>spring-mobile-device</artifactId> <version>1.0.0.RC1</version> </dependency>
The configuration for resolving the device and switching the site is pretty simple. I configured two interceptors and the SiteSwitcherHandlerInterceptor allows you to configure the “mDot” factory method to redirect your users to the mobile url.
<mvc:interceptors> <!-- On pre-handle, resolve the device that originated the web request --> <beans:bean class="org.springframework.mobile.device.DeviceResolverHandlerInterceptor" /> <!-- On pre-handle, redirects mobile users to "m.yourcoolsite.com" (declare after DeviceResolverHandlerInterceptor) --> <beans:bean class="org.springframework.mobile.device.switcher.SiteSwitcherHandlerInterceptor" factory-method="mDot"> <beans:constructor-arg value="yourcoolsite.com" /> </beans:bean> </mvc:interceptors>
That is all there is for the Spring configuration, so next up is the Sitemesh configuration.
Sitemesh
In my normal website I use Sitemesh (version 2.3) as my layout templating framework. Now with the mobile version I want a complete different layout (no header or navigation). Of course you can have this all done by great CSS, but I also want sometimes to display different information. So I want to use a different decorator for the mobile website. The first page of my website is a login screen. On this page I want to have a link to the normal website, so that the user can decide which site he wants to use, even after I redirected the user to a mobile site. Here is a screenshot of my mobile login page:
The first thing we need to do is to configure an extra decorator for the mobile website. So in my decorators.xml I have added the following decorator with the name mobile:
<decorator name="main" page="main.jsp"> <pattern>**</pattern> </decorator> <decorator name="mobile" page="mobile-main.jsp"/>
Here you can see that I have created a separate .jsp file for the mobile website. The next thing we need to do is to let Sitemesh decide which decorator it needs to use when a mobile user is visiting the site. In sitemesh.xml I configured the decorator-mapper with my custom created mapper:
<property name="decorators-file" value="/WEB-INF/decorators.xml"/> <decorator-mappers> <mapper class="nl.orange11.web.SpringMobileParameterDecoratorMapper"> <param name="config" value="${decorators-file}"/> </mapper> </decorator-mappers>
SpringMobileParameterDecoratorMapper.java:
public class SpringMobileParameterDecoratorMapper extends ConfigDecoratorMapper { private String decoratorName = null; public void init(Config config, Properties properties, DecoratorMapper parent) throws InstantiationException { super.init(config, properties, parent); decoratorName = properties.getProperty("decorator.name", "mobile"); } public Decorator getDecorator(final HttpServletRequest request, final Page page) { SitePreference sitePreference = SitePreferenceUtils.getCurrentSitePreference(request); if(sitePreference != null && sitePreference.isMobile()){ return getNamedDecorator(request, decoratorName); } return super.getDecorator(request, page); } }
In the mapper I check if the user has specified a site preference. The util method that I use checks if the URL parameter that specifies a site preference is present. If this is not the case, then the util method will use your device type as a preference. Based on the outcome I decide which decorator I want to use.
Controller
Because I have different jsp files for the mobile site, but still using the same controller I need to change the view that is passed into the ModelAndView object based on the site preferences.
SitePreference sitePreference = SitePreferenceUtils.getCurrentSitePreference(request); if (sitePreference == SitePreference.MOBILE) { view = "mobile/" + view; }
As you can see it does not require a lot of code to configure your mobile website. You will spend most of the time designing a good mobile layout. I have used JQueryMobile, as I think it is a great framework that allows you to quickly create a good looking interface for your mobile website. It is also cross-platform, so you don’t need to create different views for smartphone, tablet or desktop platforms.
Well that’s it! I hope that my post helped some of you in your journey of creating great mobile websites 🙂