<div dir="ltr" style="text-align: justify;">
<div class="separator" style="clear: both; text-align: center;"><img src="https://dineshonjava.com/wp-content/uploads/2017/01/spring-mobile.jpg" border="0" /></div>
<p>In this Spring Mobile tutorial we will discuss about how to spring work into web environment to detecting device.<br />
<b>Table of Contents</b></p>
<ol style="text-align: left;">
<li><a href="https://dineshonjava.com/2017/01/spring-mobile-tutorial.html#1"><b>Introduction</b></a></li>
<li><a href="https://dineshonjava.com/2017/01/spring-mobile-tutorial.html#2"><b>Maven Dependency</b></a></li>
<li><a href="https://dineshonjava.com/2017/01/spring-mobile-tutorial.html#3"><b>Device Module</b></a></li>
<li><b><a href="https://dineshonjava.com/2017/01/spring-mobile-tutorial.html#4">Device Resolution Classes</a> </b>
<ol>
<li><b>DeviceResolver </b></li>
<li><b>Device</b></li>
<li><b>DeviceResolverHandlerInterceptor</b></li>
<li><b>DeviceResolverRequestFilter</b></li>
<li><b>DeviceHandlerMethodArgumentResolver</b></li>
</ol>
</li>
<li><b><a href="https://dineshonjava.com/2017/01/spring-mobile-tutorial.html#5">Site Preference Management</a> </b>
<ol>
<li><b>SitePreferenceHandler</b></li>
<li><b>SitePreference</b></li>
<li><b>SitePreferenceHandlerInterceptor</b></li>
<li><b>SitePreferenceRepository</b></li>
</ol>
</li>
<li><a href="https://dineshonjava.com/2017/01/spring-mobile-tutorial.html#6"><b>Site Switching</b></a></li>
<li><a href="https://dineshonjava.com/2017/01/spring-mobile-tutorial.html#7"><b>Device Aware View Management</b></a>
<ol>
<li><b>Enabling Device Aware Views</b></li>
<li><b>Fallback View Resolution</b></li>
</ol>
</li>
<li><a href="https://dineshonjava.com/2017/01/spring-mobile-tutorial.html#8"><b>Sample Example for Spring Mobile Overview</b></a></li>
<li><a href="https://dineshonjava.com/2017/01/spring-mobile-tutorial.html#9"><b>Summary</b></a></li>
</ol>
<div style="background-color: #f2f9fc; border: 1px solid #c9e6f2; border-radius: 3px; padding: 16px; line-height: 1.45;"><span style="color: red; font-size: x-large; text-align: center;"><b>Popular Tutorials</b></span></p>
<ul style="text-align: left;">
<li><b><a href="https://dineshonjava.com/spring-tutorial/"><em><strong>Spring Tutorial</strong> </em></a></b></li>
<li><b><a href="https://dineshonjava.com/spring-web-mvc-framework-chapter-38/"><strong><em>Spring MVC Web Tutorial </em></strong></a></b></li>
<li><b><a href="https://dineshonjava.com/introduction-to-spring-boot-a-spring-boot-complete-guide/"><strong>Spring Boot Tutorial</strong> </a></b></li>
<li><b><a href="https://dineshonjava.com/spring-security-take-baby-step-to-secure/"><em>Spring Security Tutorial</em></a></b></li>
<li><b><a href="https://dineshonjava.com/spring-aop-tutorial-with-example-aspect-advice-pointcut-joinpoint/"><em>Spring AOP Tutorial</em></a></b></li>
<li><b><a href="https://dineshonjava.com/using-spring-jdbc-framework-chapter-32/"><em>Spring JDBC Tutorial</em></a></b></li>
<li><b><a href="https://dineshonjava.com/spring-hateoas-hypermedia-driven-restful-web-service/"><em><strong>Spring HATEOAS </strong></em></a></b></li>
<li><b><a href="https://dineshonjava.com/microservices-with-spring-boot/"><em><strong>Microservices with Spring Boot</strong></em></a></b></li>
<li><b><a href="https://dineshonjava.com/jax-rs-web-service-tutorial/"><strong><em>REST Webservice</em> </strong></a></b></li>
<li><b><a href="https://dineshonjava.com/core-java-baby-step-to-be-best-java-ian/"><em><strong>Core Java </strong></em></a></b></li>
<li><b><a href="https://dineshonjava.com/hibernate-3-on-baby-steps/"><em><strong>Hibernate Tutorial</strong></em></a></b></li>
<li><b><a href="https://dineshonjava.com/spring-batch-process-with-example/"><strong><em>Spring Batch</em> </strong></a></b></li>
</ul>
</div>
<p><b>1. Introduction</b><br />
Spring community provide another project Spring Mobile as an extensions to Spring MVC for developing mobile web applications. This module provide the server side device detection and provide site preferences to open website according to device resolution.</p>
<p><b>2. Maven Dependency</b><br />
For getting this project following is maven dependency to be added to pom file.</p>
<pre class="highlight"><;dependency>; 
 <;groupId>;org.springframework.mobile<;/groupId>; 
 <;artifactId>;spring-mobile-device<;/artifactId>; 
 <;version>;${org.springframework.mobile-version}<;/version>; 
<;/dependency>; 
</pre>
<p><b>3. Device Module</b><br />
Spring Mobile provide extension to Spring MVC for device detection. It is useful when any request by mobile deices need to handled differently from requests made by desktop browsers. This supported provided by Spring Module with the help of Device Resolver in the framework. Let see how device resolver works.<br />
<b>4. Device Resolution Framework</b><br />
This device resolution module is a framework which has collection of interfaces, filters, handler classes and enum to working as device resolver. Lets have look following classes in this module.<br />
<b>4.1 DeviceResolver interface</b><br />
In Spring Mobile, the DeviceResolver interface defines the API for device resolution:</p>
<pre class="highlight">public interface DeviceResolver { 
 Device resolveDevice(HttpServletRequest request); 
} 
</pre>
<p>This interface&#8217;s method return the Device interface object as below<br />
<b>4.2 Device interface</b></p>
<pre class="highlight">public interface Device { 
 boolean isNormal(); 
 boolean isMobile(); 
 boolean isTablet(); 
 DevicePlatform getDevicePlatform(); 
} 
</pre>
<p>Device resolution is nothing but it is the simple process of introspecting an HTTP request to determine the device that originated the request by analyzing the User-Agent header and other request headers.</p>
<p>In Spring MVC, web applications perform device resolution at the beginning before any request handler is invoked. Then by the help of Device resolver implementation request handlers can obtain the Device instance and by using of it request served differently as desktop request.</p>
<p>Spring Mobile provides by default implementation of DeviceResolver is LiteDeviceResolver. It is used for device resolution. You may plug-in another DeviceResolver implementation by injecting a constructor argument. For activating device resolver Spring Mobile provides an interceptor so initially we have register this interceptor as below.</p>
<p><b>4.3 DeviceResolverHandlerInterceptor interceptor</b></p>
<p><b>XML Configuration</b></p>
<pre class="highlight"><;interceptors>; 
 <;!-- On pre-handle, resolve the device that originated the web request -->; 
 <;bean class="org.springframework.mobile.device.DeviceResolverHandlerInterceptor" />; 
<;/interceptors>; 
</pre>
<p><b>Java Configuration</b></p>
<pre class="highlight">@Bean 
public DeviceResolverHandlerInterceptor deviceResolverHandlerInterceptor() { 
return new DeviceResolverHandlerInterceptor(); 
} 
 
@Override 
public void addInterceptors(InterceptorRegistry registry) { 
registry.addInterceptor(deviceResolverHandlerInterceptor()); 
} 
</pre>
<p>Alternative to the DeviceResolverHandlerInterceptor, Spring Mobile also provides one servlet filter for support to the device resolver. Configured as below</p>
<p><b>4.4 DeviceResolverRequestFilter filter</b></p>
<p>To enable, add the DeviceResolverRequestFilter to your web.xml:</p>
<pre class="highlight"><;filter>; 
 <;filter-name>;deviceResolverRequestFilter<;/filter-name>; 
 <;filter-class>;org.springframework.mobile.device.DeviceResolverRequestFilter<;/filter-class>; 
<;/filter>; 
</pre>
<p><b>4.5 DeviceHandlerMethodArgumentResolver </b><br />
<b>Find the Current Device</b><br />
There is an Untility class in the Spring Mobile to fetching current device to generate the request.</p>
<pre class="highlight">Device currentDevice = DeviceUtils.getCurrentDevice(servletRequest); 
</pre>
<p>If you&#8217;d like to pass the current Device as an argument to one of your @Controller methods, configure a DeviceWebArgumentResolver:</p>
<pre class="highlight"><;annotation-driven>; 
 <;argument-resolvers>; 
 <;bean class="org.springframework.mobile.device.DeviceWebArgumentResolver" />; 
 <;/argument-resolvers>; 
<;/annotation-driven>; 
</pre>
<p>You can alternatively configure a DeviceHandlerMethodArgumentResolver using Java-based configuration:</p>
<pre class="highlight">@Bean 
public DeviceHandlerMethodArgumentResolver deviceHandlerMethodArgumentResolver() { 
 return new DeviceHandlerMethodArgumentResolver(); 
} 
 
@Override 
public void addArgumentResolvers(List argumentResolvers) { 
 argumentResolvers.add(deviceHandlerMethodArgumentResolver()); 
} 
</pre>
<p>You can then inject the Device into your @Controllers as shown below:</p>
<pre class="highlight">@Controller 
public class HomeController { 
 
 private static final Logger logger = LoggerFactory.getLogger(HomeController.class); 
 
 @RequestMapping("/") 
 public void home(Device device) { 
 if (device.isMobile()) { 
 logger.info("Hello mobile user!"); 
 } else if (device.isTablet()) { 
 logger.info("Hello tablet user!"); 
 } else { 
 logger.info("Hello desktop user!"); 
 } 
 } 
 
} 
</pre>
<p><b>5. Site Preference Management</b><br />
This feature called site preference management allows user to set preference (SitePreference) to view a particular site in either &#8220;normal&#8221;, &#8220;mobile&#8221; or &#8220;tablet&#8221; mode from a particular device. After device resolution we have to decide site preference either open mobile site or desktop or tablet site.</p>
<p><b>5.1 SitePreferenceHandler</b><br />
Following interface provided by the Spring Mobile.</p>
<pre class="highlight">public interface SitePreferenceHandler { 
 
 final String CURRENT_SITE_PREFERENCE_ATTRIBUTE = "currentSitePreference"; 
 
 SitePreference handleSitePreference(HttpServletRequest request, HttpServletResponse response); 
 
} 
</pre>
<p>Above interface has one method handleSitePreference with request and response parameters to decide SitePreference, it is actually an enum.</p>
<p><b>5.2 SitePreference enum</b></p>
<pre class="highlight">public enum SitePreference { 
//... 
} 
</pre>
<p>To selecting site preference as below</p>
<p><b><i>Site: <;a href=&#8221;${currentUrl}?site_preference=normal&#8221;>;Normal<;/a>; | </i></b><br />
<b><i><;a href=&#8221;${currentUrl}?site_preference=mobile&#8221;>;Mobile<;/a>;</i></b></p>
<p>Spring Mobile provides handler for SitePreference is SitePreferenceHandler, it&#8217;s implementation is StandardSitePreferenceHandler.</p>
<p><b>5.3 SitePreferenceHandlerInterceptor</b><br />
To enable SitePreference management before requests are processed, add the SitePreferenceHandlerInterceptor to your DispatcherServlet configuration:</p>
<pre class="highlight"><;interceptors>; 
 <;!-- On pre-handle, manage the user's site preference (declare after DeviceResolverHandlerInterceptor) -->; 
 <;bean class="org.springframework.mobile.device.site.SitePreferenceHandlerInterceptor" />; 
<;/interceptors>; 
</pre>
<p><b>Java-based configuration is also available:</b></p>
<pre class="highlight">@Bean 
public SitePreferenceHandlerInterceptor sitePreferenceHandlerInterceptor() { 
 return new SitePreferenceHandlerInterceptor(); 
} 
 
@Override 
public void addInterceptors(InterceptorRegistry registry) { 
 registry.addInterceptor(sitePreferenceHandlerInterceptor()); 
} 
</pre>
<p><b><br />
</b> <b>5.4 Site Preference Storage</b><br />
&#8216;CookieSitePreferenceRepository&#8217; (default implementation of SitePreferenceRepository) stores the user&#8217;s preference in client side cookie so that it can be used for the future requests made by that user.</p>
<p>For getting current site preference Spring Mobile provides utility class SitePreferenceUtils, it give current site preference instance as below.</p>
<pre class="highlight">SitePreference sitePreference = SitePreferenceUtils.getCurrentSitePreference(servletRequest); 
</pre>
<p>You could pass this site preference as argument with following configuration.</p>
<p><b>To configure a SitePreferenceWebArgumentResolver:</b></p>
<pre class="highlight"><;annotation-driven>; 
 <;argument-resolvers>; 
 <;bean class="org.springframework.mobile.device.site.SitePreferenceWebArgumentResolver" />; 
 <;/argument-resolvers>; 
<;/annotation-driven>; 
</pre>
<p><b>Java-based configuration is also available:</b></p>
<pre class="highlight">@Bean 
public SitePreferenceHandlerMethodArgumentResolver sitePreferenceHandlerMethodArgumentResolver() { 
 return new SitePreferenceHandlerMethodArgumentResolver(); 
} 
 
@Override 
public void addArgumentResolvers(List argumentResolvers) { 
 argumentResolvers.add(sitePreferenceHandlerMethodArgumentResolver()); 
} 
</pre>
<p>You can then inject the indicated SitePreference into your @Controller as shown below:</p>
<pre class="highlight">@Controller 
public class HomeController { 
 
 @RequestMapping("/") 
 public String home(SitePreference sitePreference, Model model) { 
 if (sitePreference == SitePreference.NORMAL) { 
 logger.info("Site preference is normal"); 
 return "home"; 
 } else if (sitePreference == SitePreference.MOBILE) { 
 logger.info("Site preference is mobile"); 
 return "home-mobile"; 
 } else if (sitePreference == SitePreference.TABLET) { 
 logger.info("Site preference is tablet"); 
 return "home-tablet"; 
 } else { 
 logger.info("no site preference"); 
 return "home"; 
 } 
 } 
 
} 
</pre>
<p><b>6. Site Switching</b><br />
Spring mobile also provides different types of site switchers (like mDot, dotMobi and urlPath SiteSwitcher) which automatically redirect users to the device specific site based on the device generating the request and site preference set by the user.</p>
<p>SiteSwitcherHandlerInterceptor redirect users to device specific site. There are different types of site switchers available like mDot, dotMobi and urlPath SiteSwitcher. Bute here we have used urlPath SiteSwitcher which redirects users to different paths within the application based on the device and site preference.</p>
<pre class="highlight"><;interceptors>; 
 <;!-- On pre-handle, resolve the device that originated the web request -->; 
 <;bean class="org.springframework.mobile.device.DeviceResolverHandlerInterceptor" />; 
 <;!-- On pre-handle, redirects mobile users to "m.myapp.com" (declare after DeviceResolverHandlerInterceptor) -->; 
 <;bean class="org.springframework.mobile.device.switcher.SiteSwitcherHandlerInterceptor" 
 factory-method="mDot">; 
 <;constructor-arg index="0" type="java.lang.String" value="myapp.com"/>; 
 <;/bean>; 
<;/interceptors>; 
</pre>
<p><b>Java-based configuration is also available:</b><br />
<b><br />
</b></p>
<pre class="highlight">@Bean 
public DeviceResolverHandlerInterceptor deviceResolverHandlerInterceptor() { 
 return new DeviceResolverHandlerInterceptor(); 
} 
 
@Bean 
public SiteSwitcherHandlerInterceptor siteSwitcherHandlerInterceptor() { 
 return SiteSwitcherHandlerInterceptor.mDot("myapp.com", true); 
} 
 
@Override 
public void addInterceptors(InterceptorRegistry registry) { 
 registry.addInterceptor(deviceResolverHandlerInterceptor()); 
 registry.addInterceptor(siteSwitcherHandlerInterceptor()); 
} 
</pre>
<p><b>7. Device Aware View Management</b><br />
ViewResolver provides a mapping between logical view name and actual view. Here we have used device aware view resolver (&#8216;LiteDeviceDelegatingViewResolver&#8217;) that delegates to InternalResourceViewResolver allowing for resolution of device specific view names by adjusting view name by adding prefix (say &#8216;m/&#8217; and &#8216;t/&#8217; for mobile and tablet) or suffix without the need for defining separate mapping for each device specific view.</p>
<p><b>7.1 Enabling Device Aware Views</b><br />
<b><br />
</b> <b>XML configuration:</b></p>
<pre class="highlight"><;bean class="org.springframework.mobile.device.view.LiteDeviceDelegatingViewResolver">; 
 <;constructor-arg>; 
 <;bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">; 
 <;property name="prefix" value="/WEB-INF/views/" />; 
 <;property name="suffix" value=".jsp" />; 
 <;/bean>; 
 <;/constructor-arg>; 
 <;property name="mobilePrefix" value="mobile/" />; 
 <;property name="tabletPrefix" value="tablet/" />; 
<;/bean>; 
</pre>
<p><b>Java-based configuration:</b></p>
<pre class="highlight">@Bean 
public LiteDeviceDelegatingViewResolver liteDeviceAwareViewResolver() { 
 InternalResourceViewResolver delegate = new InternalResourceViewResolver(); 
 delegate.setPrefix("/WEB-INF/views/"); 
 delegate.setSuffix(".jsp"); 
 LiteDeviceDelegatingViewResolver resolver = new LiteDeviceDelegatingViewResolver(delegate); 
 resolver.setMobilePrefix("mobile/"); 
 resolver.setTabletPrefix("tablet/"); 
 return resolver; 
} 
</pre>
<p><b><br />
</b> <b>7.2 Fallback View Resolution</b><br />
There may be cases where device specific views for a particular page may not be available. There Fallback resolution (&#8216;enableFallback&#8217;) comes into picture. If adjusted view name can not be resolved then original view is used by the ViewResolver.</p>
<p><b>XML configuration:</b></p>
<pre class="highlight"><;bean class="org.springframework.mobile.device.view.LiteDeviceDelegatingViewResolver">; 
 ... 
 <;property name="enableFallback" value="true" />; 
 ... 
<;/bean>; 
</pre>
<p><b>Java-based configuration:</b></p>
<pre class="highlight">@Bean 
public LiteDeviceDelegatingViewResolver liteDeviceAwareViewResolver() { 
 ... 
 resolver.setEnableFallback(true); 
 ... 
 return resolver; 
} 
</pre>
<p><b>8. Sample Example for Spring Mobile Overview</b><br />
In this section we discuss a sample web application with using Spring Mobile to detect device and accordingly rendering the views.</p>
<p><b>Source Code of Sample Application</b><br />
<b>You could find source code this application from <a href="https://github.com/DOJ-SoftwareConsultant/Spring-Mobile" target="_blank" rel="noopener">GitHub</a>.</b></p>
<div class="separator" style="clear: both; text-align: center;"><img src="https://dineshonjava.com/wp-content/uploads/2017/01/sample-application-spring-mobile.jpg" border="0" /></div>
<p><b>9. Summary</b><br />
In this article we have seen two different module to detecting compatible site to the device one is Device Resolution and another is SitePreference by these we could resolve device aware views. And also add one sample application for Spring Mobile.</p>
<div style="background-color: #f2f9fc; border: 1px solid #c9e6f2; border-radius: 3px; padding: 16px; line-height: 1.45;"><span style="color: red; font-size: x-large; text-align: center;"><b>Spring MVC Related Posts</b></span></p>
<ul>
<li><b><a href="https://dineshonjava.com/spring-web-mvc-framework-chapter-38/"><span style="color: red;">Spring MVC Web Tutorial</span></a></b></li>
<li><b><a href="https://dineshonjava.com/spring-mvc-interview-questions-and-answers/"><span style="color: red;">Spring MVC Interview Questions</span></a></b></li>
<li><b><a href="https://dineshonjava.com/introduction-to-mvc/"><span style="color: red;">MVC Design Pattern</span></a></b></li>
<li><b><a href="https://dineshonjava.com/what-is-dispatcherservlet-in-spring-and-its-uses/"><span style="color: red;">Spring MVC DispatcherServlet </span></a></b></li>
<li><b><a href="https://dineshonjava.com/difference-between-applicationcontext-webapplicationcontext-in-spring-mvc/"><span style="color: red;">Spring MVC WebApplicationContext and Root Application Context</span></a></b></li>
<li><b><a href="https://dineshonjava.com/stereotype-annotations-in-spring/"><span style="color: red;">Spring MVC @Controller Annotation</span></a></b></li>
<li><b><a href="https://dineshonjava.com/requestmapping-annotation-in-spring-mvc/"><span style="color: red;">Spring MVC @RequestMapping Annotation</span></a></b></li>
<li><b><a href="https://dineshonjava.com/requestparam-annotation-in-spring-mvc-with-example/"><span style="color: red;">Spring MVC @RequestParam Annotation</span></a></b></li>
<li><b><a href="https://dineshonjava.com/difference-between-applicationcontext-webapplicationcontext-in-spring-mvc/"><span style="color: red;">Spring MVC ContextLoaderListener</span></a></b></li>
<li><b><a href="https://dineshonjava.com/requestparam-vs-pathvariable-annotations-in-spring-mvc/"><span style="color: red;">Spring MVC @RequestParam and @PathVariable annotations</span></a></b></li>
<li><b><a href="https://dineshonjava.com/spring-30-mvc-hello-world-example/"><span style="color: red;">Spring MVC Hello World Example</span></a></b></li>
<li><b><a href="https://dineshonjava.com/spring-exception-handling-example/"><span style="color: red;">Spring MVC Exception Handling Example</span></a></b></li>
<li><b><a href="https://dineshonjava.com/spring-mvc-with-hibernate-crud-example/"><span style="color: red;">Spring MVC with Hibernate CRUD Example</span></a></b></li>
<li><b><a href="https://dineshonjava.com/spring-3-mvc-tiles-plugin-with-example/"><span style="color: red;">Spring MVC Tiles Plugin with Example</span></a></b></li>
<li><b><a href="https://dineshonjava.com/spring-3-mvc-and-interceptor-with/"><span style="color: red;">Spring MVC Interceptor with example</span></a></b></li>
<li><b><a href="https://dineshonjava.com/integration-spring-mvc3-and-mongodb/"><span style="color: red;">Spring MVC with MongoDB CRUD Example</span></a></b></li>
<li><b><a href="https://dineshonjava.com/spring-3-mvc-internationalization/"><span style="color: red;">Spring MVC Internationalization &; Localization with Example</span></a></b></li>
</ul>
<p> ;</p>
</div>
</div>
<div class="wp-post-navigation"> 
									 <div class="wp-post-navigation-pre"> 
									 <a href="https://dineshonjava.com/method-injection-with-spring-using-lookup-method-property/">Previous</a> 
									 </div> 
									 <div class="wp-post-navigation-next"> 
									 <a href="https://dineshonjava.com/what-is-dispatcherservlet-in-spring-and-its-uses/">Next</a> 
									 </div> 
									</div>
<script type="text/javascript">
jQuery(document).ready(function($) {
 $.post('https://dineshonjava.com/wp-admin/admin-ajax.php', {action: 'mts_view_count', id: '91'});
});
</script>
Strategy Design Patterns We can easily create a strategy design pattern using lambda. To implement…
Decorator Pattern A decorator pattern allows a user to add new functionality to an existing…
Delegating pattern In software engineering, the delegation pattern is an object-oriented design pattern that allows…
Technology has emerged a lot in the last decade, and now we have artificial intelligence;…
Managing a database is becoming increasingly complex now due to the vast amount of data…
Overview In this article, we will explore Spring Scheduler how we could use it by…