삽질했던 기억

 

최근에 구글 검색으로 스프링에서 모바일 페이지 지원이 가능한 라이브러리를 알게 되었다.

 

spring-mobile-device 라이브러리다. 사실 사용법도 구글링하면 잘 나와있다.

 

Maven repository에 검색하면 다음과 같이 나와있다.

 

maven 검색에서 나온 결과

1.1.5.RELEASE 버전이 뭔가 최신버전(?) 인 것 같다. 근데? 업데이트 날짜가 2015년이다.

 

내 프로젝트는 springframework-5.0.7 이다. 처음엔 1.1.5.RELEASE 버전으로 pom.xml 파일에 라이브러리를 추가하였다.

 

근데 뭐 아무리 해도 실행이 안된다.  필터 때문에 오류가 나는 것 같고 내부적으로도 뭔가 꼬이는 것 같아 보였다.

 

이럴 때는 프로젝트 내 target폴더를 지우고 .m2 폴더를 지우고 메이븐 reload를 진행해보고 라이브러리에 뭔가 문제가 있음을 확인했다.

 

github 검색으로도 뒤져보면 거의 대부분 springframework 3점대 버전으로만 적용된 프로젝트만 있었다.

 

이게 호환이 안되나 싶었다.

 

그러고나서 곰곰히 생각해보고 다시 메이븐으로 돌아와서 아래와 같이 컴파일 버전을 확인하였다. 3. 2.13 버전으로 컴파일 되었다는 것은 당연히 5점대에서는 돌아가지 않는다는 것이다. 어!? 그럼 어떡하지? 하던 중

버전이 안맞음..

잘 보니까 옆에 Spring Plugins 탭에 2.0.0.M3 버전이 하나 더 있었다. 뭔가 공식적인 버전 보다는 따로 github Repository에서 배포하는 듯했다.

찾았다. 이거다.!

 

컴파일 버전을 보니까 스프링 5점대에서 빌드가 된다.

자 그럼 내 프로젝트에 적용해보자

pom.xml에 의존성 추가

다음 dependency 태그를 pom.xml에 넣는다.

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

pom.xml

하지만 이것만 넣어서는 maven이 다운받지 못한다. 이 파일은 repo에서 다운받는 것이므로 repo 주소까지 추가로 기입해야 한다. <repositories> 태그도 함께 넣어주자.

 

<repositories>
   <repository>
      <id>spring-milestones</id>
      <name>Spring Milestones</name>
      <url>https://repo.spring.io/libs-milestone</url>
      <snapshots>
         <enabled>false</enabled>
      </snapshots>
   </repository>
</repositories>

나는 pom.xml 파일 끝에 쪽에 넣어줬다.

 

web.xml에 필터 등록

해당 라이브러리는 필터기반의 방식으로 동작된다. 즉 해당 url에 들어오기전에 앞단 부분에서 처리된다고 보면 되는데

 

필터 등록은 보통 web.xml에서 한다. 아래와 같이 필터 등록을 해준다.

 

<filter>
   <filter-name>deviceResolverRequestFilter</filter-name>
   <filter-class>org.springframework.mobile.device.DeviceResolverRequestFilter</filter-class>
</filter>
<filter-mapping>
   <filter-name>deviceResolverRequestFilter</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>

빈 등록

이제 servlet-context.xml 부분에 빈을 등록해주면 된다. "이건 인터셉터와 관련된 빈이야~" 라고 하는 태그를 같이 달아주는 것이다. 그냥 아래 부분을 중간쯤에 넣어주면 된다. 

<interceptors>
   <beans:bean class="org.springframework.mobile.device.DeviceResolverHandlerInterceptor"></beans:bean>
</interceptors>

테스트

이제 테스트를 하는 코드를 작성해보자. 간단하게 기본코드 HomeController를 이용하였다. HttpServletRequest 객체를 받아서 DeviceUtils.getCurrentDevice() 메서드의 인자로 넣어주면 디바이스 정보가 객체에 기록된다. Device객체의 isMobile(), isTablet() 등으로 현재 사용하는 디바이스가 뭔지 알려준다. 

테스트

PC로 접속하면 다음과 같다. "Hello desktop user"를 출력하는 것을 확인할 수 있다. ( 이건 내 프로젝트 기본 셋팅 페이지이다. 이것저것 세팅 해논거... )

pc로 접속시

모바일로 접속하는 것을 테스트 하려면 아래의 크롬 확장 프로그램을 설치해주자 "User-Agent Switcher for Chrome"

https://chrome.google.com/webstore/detail/user-agent-switcher-for-c/djflhoibgkdhkhhcedjiklpkjnoahfmg

이거 깔아야함

설치한 확장 프로그램을 크롬 주소창 옆에 고정한 후 안드로이드 화면으로 체크하고 열린 URL로 들어가보자

안드로이드로 체크

모바일로 접속했다는 것을 확인할 수 있다. 아직 모바일 페이지는 따로 제작하지 않았다. 검색한 결과 모바일인 경우 controller로 처리한 뷰 페이지를 따로 지정한 폴더쪽으로 매핑시킬 수 있다고 한다. 현재 진행하는 프로젝트에 이것을 적용할 예정이다.

모바일 이란 것을 인식해버림

내가 제작한 모바일 페이지를 보여주기

모바일 전용 페이지 제작

mobile 폴더에 모바일 전용 페이지인 home.jsp 파일을 만든다. 

모바일 전용 페이지

내용은 다음과 같다.

모바일 전용 페이지

servlet-context.xml 수정

InternalResourceViewResolver는 컨트롤러가 반환해주는 뷰 페이지에 대해서 prefix와 suffix를 붙여주는 역할을 한다. 이것을 spring-mobile-device의 LiteDeviceDelegatingViewResolver가 위임받아서 뷰페이지 앞에 prefix와 suffix를 붙여주는 일을 하는데 모바일 디바이스인 경우 views 폴더 아래 지정한 폴더이름을 붙여서 그 아래 있는 jsp페이지를 찾아 주게 된다. 기존에 세팅되었던 InternalResourceViewResolver에 대한 빈 등록 부분은 주석처리를 하고 아래 코드로 대체한다.

아래 예제는 "mobile/"이라고 붙였으니 views/mobile/home.jsp 경로로 매핑되는 뷰를 볼 수 있다.

servlet-context.xml 설정

User-Agent Switcher for Chrome 안드로이드 환경으로 접속한 상태

안드로이드로 들어간 상태

 

 

사실 여기서 다루지 않은 spring-mobile-device의 SitePreferenceWebArgumentResolver는 아래 링크에서 참고하길 바란다. 이 객체로 사용자는 모바일 유저인데도 본인이 선호하는 PC 전용 사이트로 이동하는 것을 지시할 수 있다. 또한 m.google.com  형식과 같이 다른 도메인으로 보내는 방식도 이와 관련되어 있다. 

 

관련 출처 

http://arahansa.github.io/docs_spring/device.html

http://web.archive.org/web/20150525062736/http://projects.spring.io/spring-mobile/

https://docs.spring.io/spring-mobile/docs/current/reference/html/device.html

 

결론 > 스프링 5점대 버전은 spring-mobile-device 2.0.0.M3을 써야 한다.

Maven repository에서 스프링 컴파일 버전을 확인하는 습관을 갖자. 

 

 

'스프링(부트아님ㅋ)' 카테고리의 다른 글

DispatcherServlet 정리  (0) 2023.07.16
Spring 애너테이션 몇 가지 정리  (0) 2023.05.14
스프링 IoC + DI  (0) 2023.05.05

+ Recent posts