어느덧 신규 프로젝트에 투입된지 2달여가 지나가고 있다.

현재 프로젝트는 17년 기준으로 개발 된 프로젝트에 대해 마이그레이션 작업을 하는 프로젝트여서 과거 소스 및 라이브러리를 유지해야하는 부분이 있었다.

 

오늘은 sitemesh를 통해 같은 url로 접근시 pc, mobile에 대한 레이아웃을 분기하는 작업에 대해 정리하려한다.

 

보통 sitemesh를 통해 pc, mobile의 레이아웃 분기는 url에 /mobile 과 같이 특정한 값을 추가하여 분기하는데, 필자의 경우는 같은 url을 유지하고 싶어하는 요구조건이 있어 sitemesh의 내부 작업이 불가피했다.

 

sitemesh 기본 설정은 검색을 통해 금방 알 수 있으니 생략하고, 이번 프로젝트에서 위의 경우를 해결하기 위한 내용을 중점적으로 다루겠다.

 

우선 /WEB-INF/sitemesh.xml 파일에 접근하여 아래와 같이 작성한다.

<sitemesh>
	<property name="decorators-file" value="/WEB-INF/decorators.xml"/>
	<property name="decorators-file-mobile" value="/WEB-INF/mobile-decorators.xml"/>
    
	...
    
	<decorator-mappers>
		<mapper class="com.example.home.common.sitemesh.CustomConfigDecoratorMapper">
			<param name="config" value="${decorators-file}" />
			<param name="mConfig" value="${decorators-file-mobile}" />
		</mapper>
	</decorator-mappers>
</sitemesh>

위 소스에서의 중점은 기존 sitemesh.jar의 ConfigDecoratorMapper를 CustomConfigDecoratorMapper로 생성하여 변경한다.

com.opensymphony.module.sitemesh.mapper.ConfigDecoratorMapper -> com.example.home.common.sitemesh.CustomConfigDecoratorMapper

 

이렇게 하는 이유는 내부에서 요청 접속 기기의 유형을 판별하여 decorators.xml을 유동적으로 적용하기 위함이다.

 

추가로, pc, mobile을 구분하고자 하는 경우 spring-mobile-device dependecy를 추가하면 손쉽게 적용 할 수 있다.

public class CustomConfigDecoratorMapper extends AbstractDecoratorMapper {

	private ConfigLoader configLoader = null;
	private ConfigLoader mConfigLoader = null;
    
	/** Create new ConfigLoader using '/WEB-INF/decorators.xml' file. */
	public void init(Config config, Properties properties, DecoratorMapper parent) throws InstantiationException {
		super.init(config, properties, parent);
		try {
			String fileName = properties.getProperty("config", "/WEB-INF/decorators.xml");
			String mFileName = properties.getProperty("mConfig", "/WEB-INF/mobile-decorators.xml");
			configLoader = new ConfigLoader(fileName, config);
			mConfigLoader = new ConfigLoader(mFileName, config);
		} catch (Exception e) {
			throw new InstantiationException(e.toString());
		}
	}

	public Decorator getDecorator(HttpServletRequest request, Page page) {
		...
        
		Device device = DeviceUtils.getCurrentDevice(request);
		
		...

		try {
			if(device != null && device.isMobile()) {
				name = mConfigLoader.getMappedName(thisPath);
			} else {
				name = configLoader.getMappedName(thisPath);
			}
			
		} catch (ServletException e) {
			e.printStackTrace();
		}
        
		...
	}
    
	public Decorator getNamedDecorator(HttpServletRequest request, String name) {
		...
		Device device = DeviceUtils.getCurrentDevice(request);
		try {
			if(device != null && device.isMobile()) {
				result = mConfigLoader.getDecoratorByName(name);
			} else {
				result = configLoader.getDecoratorByName(name);
			}
		} catch (ServletException e) {
			e.printStackTrace();
		}
		...
	}
}

위의 소스를 보면 device로 접속기기의 유형을 판별하고 이를 통해 pc, mobile에 맞는 decorators.xml을 분기처리 하였다.

이렇게 하면 화면에서 각 기기 유형별로 sitemesh가 적용됨을 확인 할 수 있다.

+ Recent posts