스프링 JSP
프로젝트를 진행했을 때 tiles
라는 프레임워크를 사용해본 적이 있다.
레이아웃 구성이 간편해서 새 프로젝트를 구성할 때 쓰고 싶었지만 이제는 deprecated
되었다고 한다.
그래서 비슷한 구조를 만들기로 결심하고 include
를 이용해서 살펴보던 중
JSP
에도 Custom Tag
라는 게 있다는 걸 발견했다.
Custom tag란?
커스텀 태그는 말 그대로 JSP에서 사용자 지정 태그를 만들고 재사용할 수 있는 일종의 컴포넌트 같은 기능이다.
JSP 2.0
이후에 등장하였으며, 이전 방식인 태그 라이브러리 태그보다 더 유연하고 간소화된 사용 방법을 제공한다고 한다.
JSTL
(태그 라이브러리)는 JSP
에서 자주 사용하는 forEach
, include
등의 태그 문법을 포함하고 있으며
이와 비슷하게 자주 쓰이는 기능들을 사용자가 커스터마이징하여 할 수 있게 만든 것이 바로 커스텀 태그다.
데이터 등을 전달하는 기능도 있다고 하니 배워두면 여러모로 쓸만할 것 같다.
간단한 사용 방법
1. 태그 정의
<!-- WEB-INF/tags/header.tag -->
<%@ tag description="custom header" pageEncoding="UTF-8"%>
<header>
<h2>Title</h2>
</header>
2. 태그 선언
<%@ taglib prefix="custom" tagdir="/WEB-INF/tags" %>
3. 태그 사용
<custom:header />
Custom Tag를 이용하여 Template 구성하기 (1) 정적 템플릿
main.jsp
<%@ page pageEncoding="UTF-8" %>
<%@ taglib prefix="t" tagdir="/WEB-INF/tags" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="path" value="${pageContext.request.contextPath}"/>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Website</title>
<link rel="stylesheet" href="${path}/static/css/_global.css" />
</head>
<body>
<t:header/>
<main>
<t:snb/>
<article id="container">
<jsp:include page="pages/dashboard" />
</article>
</main>
<t:footer/>
</body>
</html>
header.jsp
<%@ tag description="custom header" pageEncoding="UTF-8"%>
<header>
<h2>Title</h2>
</header>
footer.tag
<%@ tag description="custom footer" pageEncoding="UTF-8"%>
<footer>
<p>Footer</p>
</footer>
snb.tag
<%@ tag description="custom snb" pageEncoding="UTF-8"%>
<nav id="snb">
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">Learn HTML</a></li>
<li><a href="#">About Us</a></li>
</ul>
</nav>
pages/dashboard.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<section>
<h1>dashboard</h1>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed efficitur a ipsum a fermentum.<br>Donec tristique id magna a dapibus. Interdum et malesuada fames ac ante ipsum primis in faucibus. Sed at fermentum sapien. Mauris volutpat, ex sit amet fermentum iaculis, sapien arcu aliquet neque, condimentum dignissim tellus velit et purus. Sed ut eros quis libero dignissim faucibus ut bibendum nunc. Nam malesuada dolor et nisl lacinia, ornare blandit odio efficitur. Maecenas vel mi nisl. Vestibulum molestie sagittis metus, at posuere libero viverra sed.
Donec convallis maximus lacus. Aliquam magna lorem, hendrerit a massa et, malesuada vehicula lectus. Fusce turpis tellus, porttitor id scelerisque sit amet, mollis vel risus. Nullam feugiat ullamcorper auctor.<br>Nulla at nibh magna. Sed rutrum viverra nisl ac pharetra. Fusce tincidunt elementum ipsum eu viverra. Nulla vitae tempor est. Phasellus bibendum, erat id auctor consectetur, nunc risus pulvinar est, ut aliquet diam risus non mi. Morbi hendrerit orci eget viverra ullamcorper. Praesent dictum, ante id feugiat mattis, magna leo vulputate nisl, quis consequat lorem felis ac felis. In lectus libero, porta a lorem ac, euismod viverra metus. Fusce auctor leo quis laoreet porta.
Mauris porttitor dignissim facilisis.<br><br>Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nullam consectetur, quam eget laoreet eleifend, quam nunc aliquam mauris, quis suscipit augue est id nunc. Aliquam finibus porta magna, sed feugiat nibh tincidunt pulvinar. Praesent sit amet molestie felis. Pellentesque euismod, massa eget posuere imperdiet, lectus urna laoreet tortor, elementum finibus nunc libero ut odio. Aliquam scelerisque vestibulum ipsum, non faucibus ante dignissim ut.
Integer in vestibulum ipsum. Proin pulvinar condimentum nisi, et finibus sem porta nec. Vivamus interdum posuere metus, ac condimentum elit venenatis feugiat. Praesent malesuada ex nec nulla viverra dictum. Duis vel tempus est. Proin sagittis tempor feugiat. Donec hendrerit mi nisl, non gravida dui scelerisque nec. In nec ullamcorper eros. Nulla facilisi. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nulla consequat luctus mi, sit amet iaculis ante condimentum vitae. Curabitur non magna lacinia, congue nunc et, faucibus metus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.
Nunc et ex at dui pulvinar lacinia. Aenean et mauris magna. Integer tincidunt aliquam turpis non egestas. Phasellus bibendum a nulla a bibendum.<br>Integer eget sodales leo. Aliquam viverra, ex tempor tempus porta, lorem magna malesuada leo, vitae pellentesque mi dui vitae nisl. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Aliquam erat volutpat. Ut non imperdiet libero. Mauris ut accumsan lorem. Integer convallis bibendum enim. Ut a sagittis sem. In varius, ante vitae vestibulum mattis, neque risus posuere eros, eu lobortis sem justo at arcu.
Pellentesque ultrices justo libero, in egestas risus elementum quis. Maecenas tempor mauris vel arcu imperdiet, eu efficitur dui dictum. Nam rhoncus viverra pharetra. Cras tempus dignissim bibendum.<br><br>Nunc facilisis vitae odio a tempor. Vestibulum tempor urna ac dui euismod fermentum.<br>Nullam sodales tempor lacus. Fusce non nisl ipsum. Ut tortor massa, tincidunt vel viverra id, ultricies vitae erat. Aliquam pharetra ullamcorper varius. Vivamus venenatis vehicula nunc a mattis. Duis ut nibh at odio posuere ullamcorper condimentum eget lectus.
Pellentesque ut sem sit amet arcu venenatis placerat non quis sapien. In tellus neque, suscipit in finibus auctor, venenatis quis justo. Donec sagittis tincidunt sapien, sed imperdiet libero tempus ac. In hac habitasse platea dictumst. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras arcu massa, interdum id quam quis, interdum molestie enim. Suspendisse potenti.<br>Donec eros ipsum, efficitur vel mi quis, porta viverra nisi. Vivamus nibh nibh, efficitur id condimentum in, efficitur non lacus. Nulla quis orci facilisis, pharetra quam vitae, faucibus risus.
Vestibulum mollis purus nec ultricies auctor.<br>Suspendisse dictum, ante sit amet euismod malesuada, orci eros blandit diam, in tristique arcu mauris at velit. Aliquam ut vestibulum nulla. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur vitae arcu vel diam cursus bibendum.<br>Nulla scelerisque gravida mattis. Cras aliquam augue posuere augue interdum tempus. Pellentesque non pulvinar ante, at volutpat sapien. In elit est, condimentum non mi a, varius accumsan leo. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Praesent ullamcorper eleifend fermentum.<br>Fusce vitae ligula et lectus maximus semper vitae nec enim. Quisque arcu enim, laoreet eget lorem euismod, consequat eleifend nulla.
Aliquam ac turpis sed orci maximus euismod. Integer vel risus elit. Suspendisse potenti.<br>Praesent viverra turpis nunc, a gravida libero venenatis eget. Aenean consequat ante ligula, eget mattis quam hendrerit in. Sed consectetur nisi eget turpis mattis, id sodales nisi posuere. Nam nec mollis dui. Cras ac enim sed nunc congue congue. Pellentesque condimentum pharetra faucibus. Nullam cursus ac ligula sit amet faucibus. Sed diam metus, vehicula non massa at, dapibus volutpat quam. Cras vulputate elementum elit, non accumsan tortor rhoncus eget. Nam nisi lorem, sodales aliquam pulvinar nec, pulvinar id ligula. Integer tempor lacinia nisl ac ultricies.
Phasellus eu laoreet velit, ac dapibus purus. Sed suscipit dui quis metus rutrum, ac vehicula urna posuere. Vestibulum fermentum ut ipsum suscipit vulputate. Ut sodales tempus nulla, non luctus ante placerat sit amet. Donec scelerisque ante ex, sed tempus dolor semper vel. Aenean elementum ultrices dapibus. Nullam varius mattis ex. Nam euismod, justo vel blandit aliquet, turpis massa blandit urna, nec vehicula nisi nisl id eros. Phasellus erat est, interdum vitae orci eleifend, efficitur lobortis tortor. Donec et elementum nibh. Maecenas orci elit, sagittis at suscipit sit amet, tempor et ipsum.
</p>
</section>
간단하게 커스텀 태그를 이용해서 정적 템플릿을 작성해보았다.
하지만 이 방식은 tiles
레이아웃에서 제공하는 동적 페이지와는 차이가 있으므로 JspController
에서 페이지를 동적으로 전달 받은 후 템플릿을 다시 구성해보도록 하겠다.
Custom Tag를 이용하여 Template 구성하기 (2) 동적 템플릿
동적 템플릿 구성을 적용하여 다양한 URL
에 대응하는 페이지들을 메인 article
태그 내에서 자유롭게 스위치할 수 있다.
main.jsp
<%@ page pageEncoding="UTF-8" %>
<%@ taglib prefix="t" tagdir="/WEB-INF/tags" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Website</title>
<link rel="stylesheet" href="${path}/static/css/global.css" />
</head>
<body>
<t:header/>
<main>
<t:snb/>
<article id="container">
<!-- 동적 페이지 넘겨주기 -->
<jsp:include page="${dynamicPage}" />
</article>
</main>
<t:footer/>
</body>
</html>
JspController.java
@GetMapping("/main")
public String main(Model model) {
model.addAttribute("dynamicPage", "pages/login.jsp");
return "main";
}
@GetMapping("/login")
public String login(Model model) {
model.addAttribute("dynamicPage", "pages/login.jsp");
return "main";
}
// dashboard
@GetMapping("/dashboard")
public String dashboard(Model model) {
model.addAttribute("dynamicPage", "pages/dashboard.jsp");
return "main";
}
login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<section>
<h1>login</h1>
</section>
이제 호출하는 페이지에 따라 동적으로 화면이 잘 변경된다.
JSP
의 경우 full page
로 작성해야하기 때문에 코드의 중복이 자주 발생하는데
커스텀 태그를 이용하여 간단하게나마 템플릿을 구성하고 컴포넌트화하여 가독성을 한층 더 높일 수 있는 것 같다.