JSP에서 커스텀태그를 이용한 가장 쉬운 레이아웃 템플릿 사용 예
JSP 2.0 Tag Files 활용 레이아웃 템플릿 사용하기
JSP의 커스텀태그를 이용하면 아주 쉽게 레이아웃 템플릿을 작성할 수 있다. JSP 2.0부터 지원되는 Tag Files을 이용하면 되며, Tomcat 5.5 부터 이후의 버전에 사용할 수 있다
레이아웃 템플릿을 사용면 페이지 전체의 틀은 유지되면서 레이아웃의 특정 부분의 내용을 달리하여 화면에 출력하고자 할 때 제작시간을 대폭 절감할 수 있고 또, 레이아웃 파일을 변경하면 그 레이아웃을 이용하는 수많은 페이지가 동시 변경된다는 점에서 유지보수 면에서도 효과를 볼 수 있다
JSP 커스텀태그를 이용하여 레이아웃 템플릿을 구현하는 것이므로 다른 외부의 툴을 설치할 필요도 없고 새로 알아야 하는 것도 거의 없다. 한개의 커스텀태그 선언파일( /WEB-INF/tags/*.tag )과 그 커스텀태그를 사용하는 JSP 만 작성하면 되므로 해야할 작업량이 늘어나는 것도 없다
커스텀 태그 선언으로 레이아웃 템플릿을 작성하고 /WEB-INF/tags/sampleLayout.tag 에 저장한다
<!DOCTYPE html>
<%@tag description="Simple Template" pageEncoding="UTF-8"%>
<%@attribute name="title"%> <%--외부에서 문자열을 받을 수 있다--%>
<%@attribute name="head_area" fragment="true" %> <%--외부에서 HTML 요소를 받을 수 있다--%>
<%@attribute name="body_area" fragment="true" %>
<html>
<head>
<title>${title}</title> <%--EL 표현식을 사용하여 외부에서 전달된 문자열을 사용한다--%>
<jsp:invoke fragment="head_area"/> <%--invoke 사용하여 외부에서 전달된 HTML요소를 사용한다--%>
</head>
<body>
<jsp:invoke fragment="body_area"/>
</body>
</html>
위의 레이아웃 템플릿에 내용을 채우는 JSP의 예 (위에서 정의한 태그파일의 경로와 파일명을 사용한다)
<%@taglib prefix="t" tagdir="/WEB-INF/tags" %>
<t:sampleLayout title="My page"> <%--태그파일에 선언된 문자열 속성에 값을 전달하는 방법--%>
<jsp:attribute name="head_area"> <%--태그파일에 선언된 HTML 요소 속성에 값을 전달하는 방법--%>
<script>
function hello() {
alert("Hello World");
}
</script>
</jsp:attribute>
<jsp:attribute name="body_area">
<div>
<button onclick="hello();">Hello There</button>
</div>
</jsp:attribute>
</t:sampleLayout>
위의 JSP 파일을 웹브라우저가 요청하면 다음과 같이 레이아웃에 데이터가 결합되어 화면에 출력된다
<!DOCTYPE html>
<html>
<head>
<title>My page</title>
<script>
function hello() {
alert("Hello World");
}
</script>
</head>
<body>
<div>
<button onclick="hello();">Hello There</button>
</div>
</body>
</html>
JSP에서 레이아웃에 데이터를 설정할 때 반드시 모든 태그 속성을 설정해야 하는 것은 아니다.
속성을 설정할 때 required="true/false" 를 사용하면 필수 설정 속성임을 선언할 수 있고, required="false"으로 설정하면 해당 레이아웃 파일을 사용하는 모든 JSP에서 반드시 그 속성 값을 설정할 필요는 없다
만약, 태그파일에서 속성을 선언할 때 아래와 같이 지정했다면 required="true" 라는 표현이 없기 때문에 required="false" 가 디폴트로 적용된다
<%@attribute name="head_area" fragment="true" %>
그러므로 위의 선언은 아래의 선언과 동일한 의미이다
<%@attribute name="head_area" fragment="true" required="false" %>
위와 같이 선언된 경우 JSP에서는 필수속성만 설정하면 되므로 아래와 같이 body_area 만 설정하면 된다
<%@taglib prefix="t" tagdir="/WEB-INF/tags" %>
<t:sampleLayout title="My page">
<jsp:attribute name="body_area">
<div>Hello World!</div>
</jsp:attribute>
</t:sampleLayout>
또 다른 예제, 태그파일이 다른 태그파일을 참조하는 내용
태그파일 선언 ( WEB-INF/tags/wrapper.tag )
커스텀 태그를 선언할 때는 아래처럼 WEB-INF/tags/xxx.tag 에 저장해야 한다
<%@tag description="Simple Wrapper Tag" pageEncoding="UTF-8"%>
<html><body>
<jsp:doBody/> <%--doBody 태그를 사용하면 태그파일 내에 attribute로 선언하지 않아도 된다--%>
</body></html>
태그파일에서 <jsp:doBody/>를 선언하여 바디를 지정하면 태그 파일에서 attribute 를 선언하지 않아도 되며, 레이아웃을 이용하는 jsp 에서는 간단히 <jsp:body>를 이용하여 html 요소를 전달할 수 있으므로 좀더 간편한 장점이 있다
태그파일 사용 ( tag_use.jsp ) 위에 선언된 태그파일의 바디에 Welcome 문자열을 전달한다
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib prefix="t" tagdir="/WEB-INF/tags" %>
<t:wrapper> <%--태그파일에 doBody 태그외에는 아무것도 없으므로 아래처럼 설정할 수도 있다--%>
<h1>Welcome</h1> <%--만약 태그파일에 doBody 외에 다른 속성도 선언되어 있다면 왼쪽과 같이 하면 오류발생--%>
</t:wrapper>
위의 경우보다 더 확장된 사용 예
/WEB-INF/tags/genericLayout.tag ( 레이아웃만 선언하고 내용은 다른 JSP 에서 동적으로 설정한다 )
<%@tag description="Overall Page template" pageEncoding="UTF-8"%>
<%@attribute name="header" fragment="true" %>
<%@attribute name="footer" fragment="true" %>
<html>
<body>
<div id="pageheader">
<jsp:invoke fragment="header"/>
</div>
<div id="body">
<jsp:doBody/>
</div>
<div id="pagefooter">
<jsp:invoke fragment="footer"/>
</div>
</body>
</html>
위에 선언된 레이아웃 템플릿에 실제 출력할 내용을 설정하는 JSP 파일
- 이 파일이 실행되면 위의 템플릿에 실제 출력할 데이터가 전달되고 템플릿이 화면에 출력된다
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib prefix="t" tagdir="/WEB-INF/tags" %>
<t:genericLayout>
<jsp:attribute name="header">
<h1>Welcome</h1> <%--정적인 문자열을 템플릿에 전달 --%>
</jsp:attribute>
<jsp:attribute name="footer">
<p id="copyright">Copyright 1927, Future Bits When There Be Bits Inc.</p> <%--정적인 문자열을 템플릿에 전달 --%>
</jsp:attribute>
<jsp:body>
<p>Hi I'm the heart of the message</p>
</jsp:body>
</t:genericLayout>
WEB-INF/tags/userpage.tag (태그 파일에서 다른 태그 파일에 값을 설정하는 예 )
<%@tag description="User Page template" pageEncoding="UTF-8"%>
<%@taglib prefix="t" tagdir="/WEB-INF/tags" %>
<%@attribute name="userName" required="true"%> <%-- 태그 속성 선언 --%>
<t:genericLayout>
<jsp:attribute name="header">
<h1>Welcome ${userName}</h1> <%-- 태그 속성 값을 템플릿에 전달 --%>
</jsp:attribute>
<jsp:attribute name="footer">
<p id="copyright">Copyright 1927, My Company Inc.</p>
</jsp:attribute>
<jsp:body>
<jsp:doBody/>
</jsp:body>
</t:genericLayout>
위의 템플릿을 사용하는 예
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib prefix="t" tagdir="/WEB-INF/tags" %>
<t:userpage userName="${user.fullName}"> <%--태그속성에 값을 설정하는 방법, EL 을 사용하여 영역객체에 접근할 수 있다 --%>
<p>
First Name: ${user.firstName} <br/> <%--태그에 선언된 <jsp:doBody/> 에 값을 설정한다--%>
Last Name: ${user.lastName} <br/>
Phone: ${user.phone}<br/>
</p>
</t:userpage>
WEB-INF/tags/userdetail.tag
<%@tag description="User Page template" pageEncoding="UTF-8"%>
<%@tag import="com.example.User" %>
<%@attribute name="user" required="true" type="com.example.User"%> <%-- 참조형 속성 선언 --%>
First Name: ${user.firstName} <br/>
Last Name: ${user.lastName} <br/>
Phone: ${user.phone}<br/>
2개의 태그파일에 선언된 태그속성에 값을 설정하는 예
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib prefix="t" tagdir="/WEB-INF/tags" %>
<t:userpage userName="${user.fullName}"> <%--태그파일에 선언된 속성에 값을 전달--%>
<p>
<t:userdetail user="${user}"/> <%--또 다른 태그파일에 선언된 속성에 값을 전달--%>
</p>
</t:userpage>
레이아웃의 변경되는 부분에 css, js 포함하는 예
레이아웃의 특정 부분에 외부의 HTML을 포함할 때 그 부분에 적용할 CSS, JS 파일이 있다면 아래와 같은 방법으로 어렵지 않게 해결할 수 있다
WEB-INF/tags/template.tag
<%@tag description="Main template of the page" pageEncoding="UTF-8" trimDirectiveWhitespaces="true" %>
<%@attribute name="header" fragment="true" required="false" %>
<html>
<head>
...some css and javasctipt used on all the pages...
<!-- Custom css and javascript for one page -->
<jsp:invoke fragment="header"/> <%--외부에서 이 부분의 내용을 변경할 수 있다--%>
</head>
<body>
<jsp:doBody />
</body>
</html>
위의 태그파일(레이아웃)에 *.css, *.js 파일을 전달(연결)하는 jsp 파일의 예
<%@page contentType="text/html" pageEncoding="UTF-8" %>
<%@taglib prefix="custom" tagdir="/WEB-INF/tags" %>
<custom:template>
<jsp:attribute name="header"> <%--레이아웃 파일에 선언된 속성에 <rel='stylesheet....>이나 <script....> 등을 전달한다--%>
...Here you can include your custom css and javascript for this page...
</jsp:attribute>
<jsp:body>
...here comes the info of the page...
</jsp:body>
</custom:template>