목차 >> Spring Mobile  
+- dependency  
+- interceptor  
+- WURFL

18장 Spring Mobile

dependency

Glue에서는 기본적으로 1.1.0.M3버전의 Spring Mobile(예:spring-mobile-device-1.1.0.M3.jar) 를 사용한다(http://www.springsource.org/spring-mobile참조)
1.1.0.M3이전 버전의 라이브러리를 사용할 경우 Glue에서 사용하는 Spring 3.2.0 버전이 아니라 그 이전 버전과 호환되면서 동작하지 않는 기능들이 있으므로 주의해야한다.
그런데 Maven을 사용할경우 Maven에서 제공하는 최신버전((2013년 5월 16일기준))은 1.0.1.RELEASE인데 이 버전은 Spring 3.1.1과 호환되므로 1.1.0.M3 이상 버전의 라이브러리를 프로젝트에서 자체적으로 사용하는 Maven Repository서버에 올려놓거나 공용으로 사용하는 서버가 없다면 로컬의 Maven Repository에 올려놓아야한다.
예를들어 로컬의 Maven Repository가 ‘E:\mvn\MavenRepository’로 정의되어 있다면 spring-mobile-device-1.1.0.M3.jar파일을 직접 ‘E:\mvn\MavenRepository\org\springframework\mobile\spring-mobile-device.1.0.M3’폴더에 배치해 주어야한다.
pom.xml에는아래와같이dependency를추가해주면된다.

<dependency>
    <groupId>org.springframework.mobile</groupId>
    <artifactId>spring-mobile-device</artifactId>
    <version>1.1.0.M3</version>
</dependency>

interceptor

Spring Mobile에서는 DeviceResolverHandlerInterceptor, SiteSwitcherHandlerInterceptor 를 제공한다.
다음은 DeviceResolverHandlerInterceptor와 SiteSwitcherHandlerInterceptor를 xxx-servlet.xml 에 설정한 예이다.

<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="mappings">
        <value>
            /sample1.mvc=controller
        </value>
    </property>
    <property name="interceptors">
        <list>
            <ref bean="deviceResolverHandlerInterceptor"/>
            <ref bean="siteSwitcherHandlerInterceptor"/>
        </list>
    </property>
</bean>
<bean name="deviceResolverHandlerInterceptor" class="org.springframework.mobile.device.DeviceResolverHandlerInterceptor" />
<bean name="siteSwitcherHandlerInterceptor" class="org.springframework.mobile.device.switcher.SiteSwitcherHandlerInterceptor"
    factory-method="mDot" >
    <constructor-arg value="test.com" />
</bean>

DeviceResolverHandlerInterceptor

DeviceResolverHandlerInterceptor 는 Request의 header를 분석하여 어떤 Device인지 관련정보를 Device 객체로 만들어서 Request에 담아 주는 역할을 한다.
DeviceResolverHandlerInterceptor에 의해 Request에 Device 객체가 담기며, Device 객에의 접근을 DeviceUtils의 getCurrentDevice메서드를 사용하면 된다.
JSP, Controller, Interceptor 와 같은 부분에서는 request를 사용할 수 있으므로 다음과 같이 사용한다.

Device device = DeviceUtils.getCurrentDevice(request);

Glue Servce 에서는, 즉 Activity에서는 GlueContext를 통해 다음과 같이 Device객체를 가져온다.

Device device = (Device)ctx.get(DeviceUtils.CURRENT_DEVICE_ATTRIBUTE);

이러한 Device 객체를 이용하면 Client 가 일반 PC의 브라우저인지, 태블릿인지, Mobile기기인지 구분 할 수 있다.

if(device.isMobile()){
    //Mobile 기기인경우
}else if(device.isTablet()){
    //Tablet기기인경우
}else if(device.isNormal()){
    //일반 PC인경우
}

다음은 추가적인 Interceptor를 통해 Device 객체를 사용하여 Mobile 페이지를 별도로 설정하는 예이다. 일반 PC에서 접근할 경우와 Mobile을 통해서 접근할 때 비즈니스 로직은 동일하고 뷰페이지만 다르다면 다음과 같이 Intercetor를 작성하여 Mobile 기기로 접근할 경우 일반 뷰페이지가 아닌 Mobile용 페이지를 보여줄 수 있다.

public class MobileSampleInterceptor extends HandlerInterceptorAdapter
{
    /** logger */
    private GlueLog logger = GlueLogFactory.getLogger(getClass());

    @Override
    public void postHandle(HttpServletRequest req, HttpServletResponse res, Object handler, ModelAndView mv) throws Exception
    {
        Device device = DeviceUtils.getCurrentDevice(req);
        String viewName = mv.getViewName();
        if(device.isMobile()){
            viewName = viewName+"_mobile";
            mv.setViewName(viewName);
        }
        logger.info("viewName==={}",viewName);
    }
}

위와 같은 Intercetor가 설정되었고, PC에서는 sample.jsp를 뷰페이지로 사용한다면, Mobile 기기에서 접근하는 경우에는 sample_mobile.jsp를 뷰페이지로 사용하게 된다.

SiteSwitcherHandlerInterceptor

SiteSwitcherHandlerInterceptor 는 Mobile 기기로 접근하는 Client를 다른 URL로 Redirect 시키는 역할을 한다. SiteSwitcherHandlerInterceptor를 Interceptor로 설정 할 경우에는 반드시 DeviceResolverHandlerInterceptor과 같이 설정하여야 한다.
SiteSwitcherHandlerInterceptor의 factory-method로mDot, dotMobi, urlPath를 설정 할 수 있다.

<bean name="case1" class="org.springframework.mobile.device.switcher.SiteSwitcherHandlerInterceptor"
    factory-method="mDot" >
    <constructor-arg value="test.com" />
</bean>
<bean name="case2"  class="org.springframework.mobile.device.switcher.SiteSwitcherHandlerInterceptor"
    factory-method="dotMobi" >
    <constructor-arg value="test.com" />
</bean>
<bean name="case3"  class="org.springframework.mobile.device.switcher.SiteSwitcherHandlerInterceptor"
    factory-method="urlPath" >
    <constructor-arg value="/m" />
</bean>

접근하고자 하는 url 이 http://www.test.com:8080/GlueSample/sample.mvc 라면 factory-method 별로 constuctor-arg 의 값을 이용해 다음과 같이 redirect 된다.

factory-method Redirect url 설명
mDot http://m.test.com:8080/GlueSample/sample.mvc http://www.test.com:8080 -> http://m.test.com:8080 으로 변경
dotMobi http://www.test.mobi:8080/GlueSample/sample.mvc http://www.test.com:8080 -> http://www.test.mobi:8080 으로 변경
urlPath http://www.test.com:8080/m/GlueSample/sample.mvc http://www.test.com:8080 -> http://www.test.com:8080/m 으로 변경

WURFL

WURFL란

  1. Wireless Universal Resource File의 약자로 오픈 데이터 모바일 장비 데이터베이스와 오픈소스 API를제공한다.
  2. 커뮤니티 주도하에 모바일 장비 정보 데이터베이스를 유지한다.
  3. XML 형식으로 장비 정보 데이터를 위해 대용량 XML 파일을 사용하고 있다.
  4. API는 특성과 그룹명으로 검색 가능하다.
  5. 데이터베이스는 계층 구조를 이루고 있다.
  6. HTTP 요청 또는 User-Agent 헤더 값으로 모바일 장비를 인식할 수 있는 메소드를 제공한다.
  7. 그룹이나, 특성이름으로 장비 정보를 얻는 메소드 제공한다.

기타 자세한 정보는WURFL 사이트(http://wurfl.sourceforge.net)를 참고하세요.

wurfl을 사용하기 위해서는 java 라이브러리와 장비 정보가 담긴 xml파일이 필요하며, 두 파일 모두 WURFL 사이트에서 다운로드 받을 수 있다.
Java 라이브러리는 기본적으로 1.4버전(wurfl-1.4.jar)을 사용하며 Maven을 사용할 경우에는 Maven에서 제공하는 최신버전(2013년 5월 16일기준)은 1.3.1.1 이므로 WURFL 사이트에서 다운받아 Maven Repository에 배치해야 한다.
장비 정보가 담긴 xml파일은 zip으로 제공되며 현재(2013년 5월 16일기준)버전은 2.3.3(wurfl-2.3.3.zip)이다. 장비 정보는 계속 업데이트되므로 가능하면 사이트를 통해서 최신버전을 확인하여 다운받도록 한다.
Glue 기반에서 WURFL Java API를 사용하기 위해서는 applicationContext.xml에 net.sourceforge.wurfl.core.GeneralWURFLEngine클래스를 Bean으로 등록하여 관련 기능들을 사용할 수 있다. constructor-arg에는 장비 정보가 담긴 zip파일의 Path를 설정한다.

<bean id="wurflHolder" class="net.sourceforge.wurfl.core.GeneralWURFLEngine">
    <constructor-arg index="0" value="classpath:/wurfl-2.3.3.zip" />
</bean>

참고로1.0.0.M4버전까지는 Spring Mobile의 DeviceResolverHandlerInterceptor와 연동하여 설정하는 기능을 제공했다.
GeneralWURFLEngine을 통해서 WURFLManager를 얻어올 수 있고 WURFLManager는 Request 정보를 기반으로 XML의 장비 정보를 가진 Device 객체를가져올 수 있다.

GeneralWURFLEngine wurfl
  = (GeneralWURFLEngine)GlueStaticContext.getBeanFactory().getBeanObject("wurflHolder");
WURFLManager manager = wurfl.getWURFLManager();
net.sourceforge.wurfl.core.Device device = manager.getDeviceForRequest(request);

logger.info("WURFL Device : {}",device);
logger.info("getCapabilities : {}",device.getCapabilities());
logger.info("getMatchType : {}",device.getMatchType());
logger.info("getMarkUp : {}",device.getMarkUp());

WURFL의 Device(net.sourceforge.wurfl.core.Device)는 Spring Mobile의 Device (org.springframework.mobile.device.Device) 와는 다르므로 혼동하지 않도록 주의해야 한다.