(4) Sitemesh로 정적인 view의 공통부분 처리하기

윤형선·2021년 9월 13일

웹 페이지들의 구조를 살펴보면 크게 다음과 같습니다.

붉은색으로 표시된 상단 메뉴와 하단 메뉴(header, footer), 그리고 노란색으로 표시된 측면 메뉴(sidebar)는 view 페이지의 본문이 바뀌어도 동일한 내용을 가지고 있습니다.

사용자에게 보여지는 웹 페이지들은 html 코드로 구성되어 있고, 중복되는 코드가 모든 페이지에 삽입된다면 코드의 가독성이나 유지보수 측면에서 비용을 발생시킵니다.

예를들어 동일한 내용이 모든 view 페이지에 중복해서 들어가게 된다면, 상단메뉴 하단메뉴, 그리고 측면메뉴의 수정사항이 생긴다면 개발자는 모든 페이지의 html을 일일히 수정해야 할 것입니다.

따라서 중복을 최소화하는것은 언제나 비용을 감소시킵니다.

Sitemesh란 중복되는 상하단과 측면 메뉴를 각 페이지에 포함시키지 않고 웹 페이지를 구성하는 레이아웃을 효율적으로 만들수 있게 도와주는 spring boot 프레임워크 입니다.

공통처리를 위한 대표적인 프레임워크는 sitemesh, thymeleaf, Tiles등이 있습니다.
오늘은 sitemesh에 대해 알아보겠습니다.

1. dependency 추가 (Maven)

pom.xml에 sitemesh templete 위한 의존성을 추가합니다.

<dependencies>
		<!-- ... 생략 -->
       
		<dependency>
			<groupId>org.sitemesh</groupId>
			<artifactId>sitemesh</artifactId>
			<version>3.0.1</version>
		</dependency>
		
               <!-- ... 생략 -->
</dependencies>

Maven에서는 dependencies태그 안에 의존성을 위치시킵니다.

dependency 추가 후에는 항상 alt+f5를 눌러 maven update를 진행하고,
프로젝트 오른쪽 클릭 Run As -> maven install을 진행해 줍니다.

2. ServletFilterConfig.java 및 SitemeshFilter.java 구성

ServletFilterConfig.java 를 생성하고 Bean을 추가해 줍니다.

// ServletFilterConfig.java 

package demo;

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;

public class ServletFilterConfig {

	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Bean
	public FilterRegistrationBean siteMeshFilter() {
		FilterRegistrationBean filter = new FilterRegistrationBean();
		filter.setFilter(new SitemeshFilter());
		return filter;
	}
}

setFilter()를 통해 view 페이지들이 SitemeshFilter를 거칠 수 있도록 설정해줍니다.

SitemeshFilter.java를 생성하고 적용할 필터에 대해 설정합니다.

//SitemeshFilter.java

public class SitemeshFilter extends ConfigurableSiteMeshFilter {
	@Override
	protected void applyCustomConfiguration(SiteMeshFilterBuilder builder) {
		builder.addDecoratorPath("/*", "/WEB-INF/decorator/default.jsp")
		       .addDecoratorPath("/admin/*", "/WEB-INF/decorator/admin_default.jsp")
		       .addExcludedPath("/sitemap");
	}
}

Sitemesh는 view 페이지가 Decorator를 한번 거치고 사용자에게 반환되도록 합니다.
이곳에서 SitemeshFilter는 사용자로부터 요청된 view 페이지가 어떤 Decorator를 거칠 것인지 지정해줍니다.

addDecoratorPath()를 통해 Decorator에 포함될 url과 Decorator종류를 지정해주고
addExcludedPath()를 통해 Decorator로부터 제외될 url을 설정합니다.

다음은 모든 경로(/*) 에 대하여 default.jsp라는 Decorator를 타게 하였고,
/admin/* 라는 url은 admin_default.jsp이라는 Decorator를 타게 하였습니다.
또한 /sitemap 라는 url은 어떠한 Decorator도 타지 않게 제외해주었습니다.

3. Decorator 구성

//admin_default.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="ko">
   <%@ include file="/WEB-INF/includes/admin/head.jsp" %>
   <body class="nav-md">
	<div class="container body">
		<div class="main_container">
			<!-- header content -->
			<%@ include file="/WEB-INF/includes/admin/header.jsp" %>
			<!-- /header content -->
			
			<!-- page content -->
			<sitemesh:write property='body' />
			<!-- /page content -->

			<!-- footer content -->
			<%@ include file="/WEB-INF/includes/admin/footer.jsp" %>
			<!-- /footer content -->
		</div>
          </div>   
   </body>
</html>

Decorator를 살펴보면 head와 header 그리고 footer를 공통으로 처리하였으며
요청된 url에 따른 해당 페이지가 <sitemesh:write property='body' />라는 태그에 동적으로 삽입됩니다.

참고사항
application.properties에서 view 페이지의 prefix와 suffix를 설정할 수 있습니다.

# JSP Path (ViewResolver)
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp

이상으로 Sitemesh에 대해 알아보았습니다.
감사합니다.

profile
안녕하세요

0개의 댓글