스프링부트 + jsp 환경에서 tiles 사용하기 (desktop, mobile 접근 구분하여 페이지 분기)
09 Feb 2019 | Spring Java tiles 타일즈 mobile 모바일스프링부트 + jsp + tiles 설정이 이미 되어 있다고 가정한다.
[스프링부트 + jsp + tiles 설정 참고 : http://jmlim.github.io/spring/2019/02/08/spring-boot-tiles/]
테스트한 버전은 2.x 버전이며 스프링 부트 버전에 따라 버전을 조금 다르게 가야할 수도 있을 것 같다.
1. pom.xml 에 spring mobile 추가.
스프링 모바일 2.x 버전은 아직 정식버전이 나오지 않았으므로 마일스톤에서 내려받는다. (스프링 마일스톤 레포지토리를 추가하여 내려받음.)
....
<!-- 스프링 마일스톤 repo -->
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</repository>
</repositories>
....
<!-- 스프링 모바일 -->
<dependency>
<groupId>org.springframework.mobile</groupId>
<artifactId>spring-mobile-starter</artifactId>
<version>2.0.0.M2</version>
</dependency>
2. yml or properties 설정 추가.
yml 사용 시
spring:
mobile:
devicedelegatingviewresolver:
enabled: true
properties 사용 시
spring.mobile.devicedelegatingviewresolver.enabled: true
이렇게만 추가해도 컨트롤러의 요청 메소드에 Device 정보를 argument 로 받을 수 있다.
@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!");
}
}
3. TilesConfig 에 모바일 분기 관련 설정 추가.
- tiles Configurer 에 tiles-mobile.xml 설정 추가.
- LiteDeviceDelegatingViewResolver 설정 추가.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.mobile.device.view.LiteDeviceDelegatingViewResolver;
import org.springframework.web.servlet.view.tiles3.TilesConfigurer;
import org.springframework.web.servlet.view.tiles3.TilesView;
import org.springframework.web.servlet.view.tiles3.TilesViewResolver;
@Configuration
public class TilesConfig {
@Bean
public TilesConfigurer tilesConfigurer() {
final TilesConfigurer configurer = new TilesConfigurer();
configurer.setDefinitions(new String[]{"/WEB-INF/tiles/tiles.xml",
// 모바일 분기 관련 설정 추가부분..
"WEB-INF/tiles/tiles-mobile.xml"});
configurer.setCheckRefresh(true);
return configurer;
}
@Bean
public TilesViewResolver tilesViewResolver() {
final TilesViewResolver tilesViewResolver = new TilesViewResolver();
tilesViewResolver.setViewClass(TilesView.class);
return tilesViewResolver;
}
/**
* 모바일 분기 관련 설정 추가부분..
*/
@Bean
public LiteDeviceDelegatingViewResolver liteDeviceDelegatingViewResolver() {
LiteDeviceDelegatingViewResolver resolver = new LiteDeviceDelegatingViewResolver(this.tilesViewResolver());
/**
tilesViewResolver의 Order 값을 최상위로 높여 주지 않으면 앞서 프로퍼티에서 생성한
LiteDeviceDelegatingViewResolver에의해 ContentNegotiatingViewResolver 에서 org.springframework.web.servlet.view.JstlView 이 실행되어 Tiles가 동작하지 않게 된다.
*/
resolver.setOrder(0);
resolver.setMobilePrefix("mobile/");
resolver.setEnableFallback(true);
return resolver;
}
}
4. tiles-mobile.xml 설정 추가. (기존 tiles.xml 에서 mobile 키워드 추가.)
ex1) name = main-layout -> mobile-main-layout
ex2) value = /WEB-INF/views/main/body/{1}.jsp -> /WEB-INF/views/mobile/main/body/{1}.jsp
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE tiles-definitions PUBLIC
"-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"
"http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
<tiles-definitions>
<!-- main -->
<definition name="mobile-main-layout" template="/WEB-INF/views/mobile/main/layout/base-main.jsp">
<put-attribute name="header" value="/WEB-INF/views/mobile/common/layout/header.jsp" />
<put-attribute name="body" value="" />
<put-attribute name="footer" value="/WEB-INF/views/mobile/common/layout/footer.jsp" />
</definition>
<definition name="mobile/main/*" extends="mobile-main-layout">
<put-attribute name="body" value="/WEB-INF/views/mobile/main/body/{1}.jsp" />
</definition>
<definition name="mobile/main/*/*" extends="mobile-main-layout">
<put-attribute name="body" value="/WEB-INF/views/mobile/main/body/{1}/{2}.jsp" />
</definition>
<definition name="mobile/main/*/*/*" extends="mobile-main-layout">
<put-attribute name="body" value="/WEB-INF/views/mobile/main/body/{1}/{2}/{3}.jsp" />
</definition>
</tiles-definitions>
경로 참고 이미지
5. Controller 에서 페이지 호출
위 설정대로 모바일로 접근 시 경로 리턴값에 자동으로 mobile/ 이 붙게 된다.
아래 LiteDeviceDelegatingViewResolver 소스 부분 참고
ex) mv.setViewName(“main/index”);
로 리턴시 mv.setViewName(“mobile/main/index”); 로 설정값이 바뀜
@Controller
@RequestMapping("/")
public class MainController {
@GetMapping(value = {"", "index"})
public ModelAndView index() {
ModelAndView mv = new ModelAndView();
.....
로직로직
....
mv.setViewName("main/index");
return mv;
}
}
LiteDeviceDelegatingViewResolver.java
public class LiteDeviceDelegatingViewResolver extends AbstractDeviceDelegatingViewResolver {
private String normalPrefix = "";
private String mobilePrefix = "";
private String tabletPrefix = "";
private String normalSuffix = "";
private String mobileSuffix = "";
private String tabletSuffix = "";
.....
// 1. 앞에 키워드를 붙이는 부분이며 아까 설정에서 mobilePrefix 를 mobile/ 로 설정하였다.
protected String getDeviceViewNameInternal(String viewName) {
RequestAttributes attrs = RequestContextHolder.getRequestAttributes();
Assert.isInstanceOf(ServletRequestAttributes.class, attrs);
HttpServletRequest request = ((ServletRequestAttributes)attrs).getRequest();
Device device = DeviceUtils.getCurrentDevice(request);
SitePreference sitePreference = SitePreferenceUtils.getCurrentSitePreference(request);
String resolvedViewName = viewName;
if (ResolverUtils.isNormal(device, sitePreference)) {
resolvedViewName = this.getNormalPrefix() + viewName + this.getNormalSuffix();
}
// 2. 모바일 디바이스일 경우 이부분이 조건으로 타게되며 그 경우에 모바일 prefix 인 mobile/ 이 붙에 됨.
else if (ResolverUtils.isMobile(device, sitePreference)) {
resolvedViewName = this.getMobilePrefix() + viewName + this.getMobileSuffix();
} else if (ResolverUtils.isTablet(device, sitePreference)) {
resolvedViewName = this.getTabletPrefix() + viewName + this.getTabletSuffix();
}
return this.stripTrailingSlash(resolvedViewName);
}
private String stripTrailingSlash(String viewName) {
return viewName.endsWith("//") ? viewName.substring(0, viewName.length() - 1) : viewName;
}
}
참고:
- https://mycup.tistory.com/208
- http://projects.spring.io/spring-mobile/
Comments