JSTL 써머리
1. JSTL이란?
일반적으로 알고있는 JSTL이란 JSTL + EL의 조합을 말한다.
HTML 코드 내에 java 코드인 스크립틀릿 <%= student %>를 ${student}로, <%=if %>문을 <c:if>, <%=for%>문을 <c:forEach>로 대체하여 사용한다.
예전에는 스크립틀릿을 많이 사용했지만 가독성이 떨어지고, 뷰와 비즈니스로직의 분리로 인해 현재는 JSTL을 많이 사용하는 추세다. JSTL과 EL은 보통 함께 사용하는데 그 이유와 각각의 개념, 각각의 차이와 문법을 정리해보도록 하자.
2. JSTL
JSTL의 정식 명칭은 자바서버 페이지 표준 태그 라이브러리(JavaServer Pages Standard Tag Library)이고 줄여서 JSTL이라 부른다.
위키피디아를 참조하자면, JSTL은 Java EE 기반의 웹 애플리케이션 개발 플랫폼을 위한 컴포넌트 모음이다. JSTL은 XML 데이터 처리와 조건문, 반복문, 국제화와 지역화와 같은 일을 처리하기 위한 JSP 태그 라이브러리를 추가하여 JSP 사양을 확장했다.
JSTL은 JSP 페이지 내에서 자바 코드를 바로 사용하지 않고 로직을 내장하는 효율적인 방법을 제공한다. 표준화된 태그 셋을 사용하여 자바 코드가 들락거리는 것보다 더 코드의 유지보수와 응용 소프트웨어 코드와 사용자 인터페이스 간의 관심사의 분리로 이어지게 한다.
JSTL의 사용법JSTL은 라이브러리이기 때문에 사용하기전에 core를 header에 추가해주어야 한다.
<% @taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
사용방법은 다음과 같다.
<c:if test=""></c:if>
<c:forEach items=""></c:forEach>
<c:set> | 변수명에 값을 할당 |
<c:out> | 값을 출력 |
<c:if> | 조건식에 해당하는 블럭과 사용될 scope설정 |
<c:choose> | 다른 언어의 switch와 비슷 |
<c:when> | switch문의 case에 해당 |
<c:otherwise> | switch문의 default에 해당 |
<c:forEach> | 다른언어의 loop문 items 속성에 배열을 할당할 수 있음 |
3. EL
EL의 정식 명칭은 표현 언어(Expression Language)라고 하며 줄여서 EL이라고 부른다.
JSP 2.0 스펙에 새로 추가된 스크립트 언어로서 초기의 EL은 JSTL의 액션 태그에서만 작동하는 문제가 있었는데, JSP 2.0 부터는 JSP 컨테이너가 EL표현식을 해석할 수 있게 도어 표준 액션 태그, 커스텀 태그, 템플릿 데이터와 같이 자바코드를 사용해야 했던 모든 곳에 EL을 사용할 수 있다.
EL은 자바스크립트에서 확장된 Xpath에서 힌트를 얻어 만들어진 언어로 값이 없는 변수(null)에 대해 좀 더 관대하고 데이터 형 변환을 자동으로 해주는 특징이 있다. EL을 사용하면 값이 없거나 형 변환 등에 전혀 신경 쓸 필요 없이 서버로 전송해서 형변환 없이 사용할 수 있다.
EL의 사용법<%= name %>
${name}
${pageScope} | page Scope에 접근하기 위한 객체 |
${reqeustScope} | request Scope에 접근하기 위한 객체 |
${sessionScope} | session Scope에 접근하기 위한 객체 |
${applicationScope} | application Scope에 접근하기 위한 객체 |
${param} | 파라미터 값을 가져오기 위한 객체 |
${header} | 헤더 값을 가져오기 위한 객체 |
${cookie} | 쿠키 값을 가져오기 위한 객체 |
${initParam} | JSP 초기 파라미터를 가져오기 위한 객체 |
${pageContext} | pageContext 객체에 접근하기 위한 객체 |
+ | + |
* | * |
/ | div |
\&\& | and |
|| | or |
== | eq |
!= | ne |
< | ge |
> | lt |
<= | ge |
>= | le |
4. 스크립틀릿 vs JSTL
JSTL + EL의 조합으로 우리는 스크립틀릿을 사용할 때보다 훨씬 간결하고 가독성 좋은 HTML코드를 완성할 수 있다. 비교를 위해 jsp에서 1부터 10까지 출력하는 예제와 parameter를 표시하는 방법을 작성해보자.
스크립틀릿을 사용한 방법<html>
<body>
<%
for (int i = 1; i <= 10; i ++) {
%>
<%= i %><br/>
<%
}
%>
<%= request.getAttribute("person").getAddress().getCity() %>
</body>
</html>
스크립틀릿과 HTML태그들을 함께 사용하지 않아야하는 주된 이유는 가독성 문제다. JSTL을 사용하면 개발자는 HTML과 태그로만 구성된 일관된 소스를 볼 수 있다.
퍼블리셔, 프론트 개발자, 서버 개발자가 공동으로 작업을 한다고 생각해보자. 스크립틀릿 코드는 퍼블리셔나 디자이너가 알아보기 힘들수 있다. 스크립틀릿을 이해하려면 java를 알아야 하기 때문이다.
그럼 이제 이 지저분한 코드를 JSTL + EL로 어떻게 바꿀 수 있는지 작성해보자.
JSTL + EL을 사용한 방법<% @taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
<html>
<body>
<c:forEach var="i" begin="1" end="10" step="1">
<c:out value="${i}"/>
<br/>
</c:forEach>
${person.address.city}
</body>
</html>
스크립틀릿 코드와 비교해보면 java코드 없이, <% 기호 없이 오로지 태그로만 구성되어 있는 걸 알 수 있다. 이런 코드들은 가독성이 좋고 이해하기도 쉽다. 또한 협업하기에도 더없이 군더더기없는 코드이다.
서버에서 넘어온 parameter를 꺼내는 방법에서도 차이를 알 수 있는데, 이것 또한 스크립틀릿보다 간결하게 사용할 수 있다.
5. 알아두면 좋은 JSTL 표현들
javascript에서 model parameter를 가져오는 방법
var key = '<c:out value='${key}' />';
javascript에서 context path를 가져오는 방법
var G_CONTEXT_PATH = "${pageContext.request.contextPath}";
jsp에서 url의 get parameter 가져오는 방법
<c:if test="${param.loginFail eq 'true'}">
<div class="login-fail">아이디 혹은 비밀번호가 일치하지 않습니다.</div>
</c:if>
jsp에서 현재 년도 구하기
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<jsp:useBean id="now" class="java.util.Date" />
<fmt:formatDate var="year" value="${now}" pattern="yyyy" />
<p>Current year: ${year}</p>
<p>Previous year: ${year - 1}</p>
- JSP는 HTML문서 사이에 JSP문법코드가 삽입된 형태로 작성된다.
<% %> - 스크립트릿, 이 안에 자바 코드 쓸수 있다.
<%= %> - 익스프레션, 자바식 출력 - <%@ %> - 지시자, 웹컨테이너가 jsp 페이지를 처리할 때 필요한 정보를 기술
- <%! %> - 선언부, 변수선언이나 메서드를 선언
- &{ } - 익스프레션 언어(EL)
- <jsp:
/>, <c:/> - 액션 태그
JSTL
태그 라이브러리 선언
자바에서 import문을 선언하듯 JSP에서도 JSTL 확장 태그를 사용하려면 taglib 지시자로 라이버리를 선언해야 한다.
JSP 지시자 태그 <%@ taglib %>를 사용해서 다음과 같이 선언한다.
<%@ taglib prefix="접두사" uri="URI" %>
uri : 태그 라이브러리의 네임 스페이스 URI 식별자
prefix : JSTL 태그를 사용할때 태그 이름 앞에 붙일 접두사

<c:if> 태그
ex)
<c:if test="조건식" var="변수명" scope="page(기본값) | request | session | application">내용</c:if>
-> test의 조건식이 true이면 '내용'이 실행된다. var, scope 속성은 test 결과를 저장할때 사용한다.
ne : !=
eq : ==
<c:if test="${10 > 20}" var="result1">
10은 20보다 크다.<br>
</c:if>
result1 : ${result1}<br>
<c:if test="${10 < 20}" var="result2">
20은 10보다 크다.<br>
</c:if>
result2 : ${result2}

<c:forEach> 태그
반복 작업에 사용한다. 특히 목록에서 값을 꺼내서 처리할때 사용한다.
ex) <c:forEach var="변수명" items="목록 데이터" begin="시작 인덱스" end="종료 인덱스">콘텐츠</c:forEach>
<% pageContext.setAttribute("numList", new String[]{"1", "2", "3", "4", "5"}); %>
<ul>
<c:forEach var="num" items="${numList}">
<li>${num}</li>
</c:forEach>
</ul>
