EL 및 JSTL
- -
📌EL
- 라이브러리로 자바 구문을 만들어 놓고 필요할 때마다 꺼내 쓰면 되기 때문에 유지보수에 편하다.
- JSP 페이지 내에서 자바 코드와 HTML 코드(태그 형태)가 섞여 있으면 가독성이 떨어진다.
- EL문과 JSTL문을 사용하면 HTML과 태그 형태로만 구성된 일관된 소스코드를 볼 수 있다.
1. EL문
- Expression Language
- 값을 간결하고 간편하게 출력(표현)할 수 있도록 해주는 언어
- EL 문은 ${} 안에 있는 변수는 필드를 찾아오는 게 아니라 getter를 찾아가는 것이다.
- 그래서 우리가 만드는 객체를 사용하고 싶으면 setter, getter로 해야 한다.
JSP(자바) | EL |
<%=name%> | ${name} |
* setAttribute를 할 수 있는 4가지
① pageContext : 현재 페이지
② request : 요청
③ session : 세션
④ application : 전체
- 연산자
- EL문에서 연산자를 문자열로 나타낼 수 있다.
- ${empty data} : data의 값이 없으면 ture
연산자 문자열 연산자 문자열 / div < lt % mod >= ge && and <= le || or == eq ! not != ne > gt empty 뒤에 오는 값이 비어있으면 true / 아니라면 false

- 자바 변수를 사용하기 위해서는 <%= %> 문을 사용할 수밖에 없다.
- EL문은 변수를 찾는 것이 아니라 setAttribute로 한 키값을 찾으러 가는 것이다.
- 그래서 EL문을 사용하기 위해서는 setAttribute("키","값")을 사용해야 한다.
- 만약 키의 값이 중복 되어 들어간다면 찾는 attribute 순서는 다음과 같다. pageContext > request > session > application
- 우리가 원하는 곳에서 찾기 위해서는 ${~~~~~Scope. 키값}으로 하면 된다.

- 위에서 보았듯이 attribute로 넘어왔으면 ${} 안에다가 키 값을 그냥 적으면 된다.
- parameter로 넘어온다면 EL문에서는 ${param.name}으로 하면 된다.
- checkbox처럼 배열로 값이 넘어오는 parameter는 ${paramValues.name[n]}으로 사용하면 된다.
- 쿠키를 사용하기 위해서는 배열을 선언해서 사용했지만 EL문을 사용하면 ${cookie.키값.value}로 하면 값을 쉽게 얻을 수 있다.
📌JSTL
태그 라이브러리 선언
자바에서 import문을 선언하듯 JSP에서도 JSTL 확장 태그를 사용하려면 taglib 지시자로 라이브러리 선언해야 한다.
JSP 지시자 태그 <%@ taglib %>를 사용해서 다음과 같이 선언한다.
<%@ taglib prefix="접두사" uri="URI" %>
uri : 태그 라이브러리의 네임 스페이스 URI 식별자
prefix : JSTL 태그를 사용할때 태그 이름 앞에 붙일 접두사
다음은 태그 라이브러리 별 표준 선언문이다.
태그 라이브러리 | 선언문 |
Core | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> |
XML | <%@ taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml" %> |
I18N | <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> |
Database | <%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %> |
Functions | <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> |
prefix를 꼭 저렇게 지정해야하는건 아니지만 JSTL에서 제안하는 표준 접두사이므로 똑같이 사용하는 게 좋다.
태그 라이브러리 별 태그 정리
태그 라이브러리 | 기능 | 태그 - 부모태그(자식태그) |
Core(기본) | 변수 | remove, set |
흐름 제어 | choose(when, otherwise) forEach forTokens if |
|
URL 관리 | import(param) redirect(param) url(param) |
|
기타 | catch, out | |
XML | 기본 | out, parse, set |
흐름 제어 | choose(when, otherwise) forEach if |
|
변환 | transform(param) | |
I18N(국제화) | 로케일 | setLocale, requestEncoding |
메시지 포맷 | bundle message(param) setBundle |
|
Database | 데이터 소스 설정 | setDataSource |
SQL | query(dateParam, param) transaction update(dateParam, param) |
|
Functions(기타 함수) | 집합의 원소 개수 | length |
문자열 처리 | toUpperCase toLowerCase substring substringAfter substringBefore trim replace indexOf startsWith endsWith contains containsIgnoreCase split join escapeXml |
<c:out> 태그
출력문을 만드는 태그이다.
<c:out value="출력값" default="기본값" />
<c:out value="출력값">기본값</c:out>
value에 EL 표현식을 쓸 수 있다.
value 값이 null이면 기본값이 출력되고 기본값이 없으면 빈 문자열이 출력된다.
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<c:out value="Hello World" /><br>
<c:out value="${null}">JSTL</c:out><br>
<c:out value="Hello">World</c:out><br>
<c:out value="${null}" />
</body>
</html>

<c:set> 태그
변수를 다룰 때 사용한다.
이 태그로 생성한 변수는 JSP의 로컬 변수가 아니라 서블릿 보관소(JspContext, ServletRequest, HttpSession, ServletContext)에 저장된다.
<c:set var="변수명" value="값" scope="page(기본값)|request|session|application" />
<c:set var="변수명" scope="page(기본값)|request|session|application">값</c:set>
scope의 기본값은 page이다. 따라서 scope를 생략하면 JspContext에 저장된다.
<%--<c:set> 기본 사용 방법--%>
<c:set var="username1" value="김연아" />
<c:set var="username2">박지성</c:set>
${username1}<br>
${username2}<br>
${pageScope.username1}<br>
${pageScope.username2}<br>
<p></p>
<%--보관소 지정(ServletRequest)--%>
<c:set var="username3" scope="request">마일리 사이러스</c:set>
${pageScope.username3}<br>
${requestScope.username3}<br>
<p></p>
<%--기존 값 덮어씀--%>
<% pageContext.setAttribute("username4", "마고 로비"); %>
기존 username4 : ${username4}<br>
<c:set var="username4" value="레오나르도 디카프리오" />
변경 username4 : ${username4}<br>

scope를 생략하면 기본적으로 JspContext(page)에 저장됨을 알 수 있다.
scope="request"와 같이 scope를 명시적으로 지정할 수도 있다.
<c:set>으로 이미 존재하는 변수에 값을 할당할 경우 기존 값을 덮어쓴다.
<c:set>을 이용한 객체의 프로퍼티 값 설정
<c:set target="대상 객체" property="설정할 프로퍼티" value="프로퍼티 값" />
<%!
public static class MyMember {
int no;
String name;
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
%>
<%
MyMember member = new MyMember();
member.setNo(100);
member.setName("김연아");
pageContext.setAttribute("member", member);
%>
${member.name}<br>
<c:set target="${member}" property="name" value="박지성" />
${member.name}<br>

Innter class MyMember의 인스턴스 member를 생성하고 member의 name을 <c:set> 태그를 사용해서 변경하는 코드이다.
<c:set>으로 객체의 프로퍼티 값을 설정할 때는 setter()의 리턴 타입이 반드시 void여야 한다.
그렇지 않으면 다음과 같은 예외가 발생한다.

<c:remove> 태그
보관소에 저장된 값을 제거한다.
<c:remove var="변수명" scope="page(기본값) | request | session | application" />
<c:set>과 마찬가지로 scope 속성으로 보관소를 명시할 수 있고 보관소의 기본값은 page이다.
<% pageContext.setAttribute("username1", "봉준호"); %>
${username1}<br>
<c:remove var="username1" />
${username1}<br>

<c:remove> 사용 후 JspContext에서 username1의 값을 삭제해서 값이 출력되지 않는다.
<c:if> 태그
<c:if test="조건식" var="변수명" scope="page(기본값) | request | session | application">내용</c:if>
test의 조건식이 true이면 '내용'이 실행된다.
var, scope 속성은 test 결과를 저장할 때 사용한다.
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}

${10 > 20}은 false이므로 '10은 20보다 크다'는 출력되지 않는다.
${10 < 20}은 true이므로 '20은 10보다 크다'가 출력되었다.
<c:if> - List가 empty(비어있는지) 체크
<c:if test="${empty myList}">
<div>
<!-- myList가 비어있으면 -->
</div>
</c:if>
<c:if test="${not empty myList}">
<div>
<!-- myList가 비어있지 않으면 -->
</div>
</c:if>
List의 empty 여부는 empty operator를 사용하여 test 할 수 있다.
<c:choose> 태그
자바의 switch-case와 같은 기능을 수행한다.
여러 조건에 따라 다른 작업을 할 필요가 있을 때 사용한다.
<c:choose>
<c:when test="조건식"></c:when>
<c:when test="조건식"></c:when>
...
<c:otherwise></c:when>
</c:choose>
<c:when> 태그는 한 개 이상 존재해야 하며 <c:otherwise> 태그는 0개 혹은 1개가 올 수 있다.
<c:when>의 조건에 일치하지 않으면 <c:otherwise>가 실행된다.
c:set var="userid" value="hello123" />
<c:choose>
<c:when test="${userid == 'admin'}">
관리자 페이지
</c:when>
<c:otherwise>
${userid}님 반갑습니다.
</c:otherwise>
</c:choose>

<c:forEach> 태그
반복 작업에 사용한다. 특히 목록에서 값을 꺼내서 처리할 때 사용한다.
<c:forEach var="변수명" items="목록 데이터" begin="시작 인덱스" end="종료 인덱스">콘텐츠</c:forEach>
items에는 다음을 지정할 수 있다.
- 배열
- java.util.Collection 구현체(ArrayList, LinkedList, EnumSet, ...)
- java.util.Iterator 구현체
- java.util.Enumeration 구현체
- java.util.Map 구현체
- 콤마(,) 구분자로 나열된 문자열
var는 반복문을 돌면서 items에서 꺼낸 항목 값을 가리키는 참조 변수이다.
<c:forEach> - 배열
다음은 items에 배열을 지정한 forEach 예이다.
<% pageContext.setAttribute("numList", new String[]{"1", "2", "3", "4", "5"}); %>
<ul>
<c:forEach var="num" items="${numList}">
<li>${num}</li>
</c:forEach>
</ul>

다음과 같이 시작 인덱스와 종료 인덱스를 지정할 수 있다.
<% pageContext.setAttribute("numList", new String[]{"1", "2", "3", "4", "5"}); %>
<ul>
<c:forEach var="num" items="${numList}" begin="1" end="3">
<li>${num}</li>
</c:forEach>
</ul>

<c:forEach> - ArrayList
다음은 items에 ArrayList를 지정한 forEach 예이다.
<%
List<String> fruits = new ArrayList<>();
fruits.add("apple");
fruits.add("banana");
fruits.add("pineapple");
fruits.add("kiwi");
fruits.add("melon");
pageContext.setAttribute("fruits", fruits);
%>
<ul>
<c:forEach var="fruit" items="${fruits}">
<li>${fruit}</li>
</c:forEach>
</ul>

실행 결과
<c:forEach> - 문자열
다음은 콤마(,)로 연결된 문자열에 대한 forEach 예제이다.
<% pageContext.setAttribute("maleActors", "리버 피닉스, 장동윤, 차인표, 남궁민, 공유"); %>
<ul>
<c:forEach var="name" items="${maleActors}">
<li>${name}</li>
</c:forEach>
</ul>

<c:forEach> - 횟수 반복
items 지정 없이 begin과 end 속성을 사용해서 일정 횟수 반복할 수 있다.
<ul>
<c:forEach var="no" begin="1" end="10">
<li>forEach 예제 ${no}</li>
</c:forEach>
</ul>

<c:forTokens> 태그
문자열을 delimiter(구분자)로 분리해서 반복문을 돌리는 데 사용한다.
<c:forTokens var="변수명" items="문자열" delims="구분자">콘텐츠</c:forTokens>
<% pageContext.setAttribute("tokens", "v1=20&v2=20&op=+"); %>
<ul>
<c:forTokens var="item" items="${tokens}" delims="&">
<li>${item}</li>
</c:forTokens>
</ul>

<c:url> 태그
URL을 만들 때 사용한다.
이 태그를 사용하면 매개변수를 포함한 URL을 쉽게 만들 수 있다.
<c:url var="변수명" value="url">
<c:param name="파라미터명" value="값" />
<c:param name="파라미터명" value="값" />
<c:param name="파라미터명" value="값" />
</c:url>
<c:url var="calcUrl" value="http://localhost:8080/calc">
<c:param name="v1" value="10" />
<c:param name="v2" value="20" />
<c:param name="op" value="+" />
</c:url>
${calcUrl}

<c:import> 태그
url 속성에 콘텐츠가 있는 주소를 지정하면 해당 주소로 요청하고 응답 결과를 받아서 반환한다.
<c:import url="url" var="변수명" scope="page(기본값) | request | session | application" />
다음은 url에 로또 800회 차 당첨 결과를 JSON으로 반환받은 결과를 출력하는 예제이다.
<textarea rows="10" cols="80">
<c:import url="https://www.nlotto.co.kr/common.do?method=getLottoNumber&drwNo=800" />
</textarea>

var, scope 속성을 사용해서 보관소에 저장했다가 출력할 수 있다.
<c:import var="lottoResult" url="https://www.nlotto.co.kr/common.do?method=getLottoNumber&drwNo=800" />
<textarea rows="10" cols="80">
${lottoResult}
</textarea>
실행 결과는 위와 동일하다.
이렇게 보관소에 저장해두면 필요할 때마다 가져와서 쓰거나 결과 데이터를 변환하는 등의 작업을 할 수 있다.
<c:redirect> 태그
리다이렉트 처리를 할때 사용한다. 내부적으로 HttpServletResponse의 sendRedirect()를 호출한다.
<c:redirect url="url" />
<fmt:parseDate> 태그
날짜 형식으로 작성된 문자열로 java.util.Date 객체를 생성한다.
그리고 지정된 보관소에 저장한다.
<fmt:parseDate var="변수명" value="날짜 형식 문자열" pattern="패턴" scope="page(기본값) | request | session | application" />
<fmt:parseDate var="date1" value="2020-02-15" pattern="yyyy-MM-dd" />
'개인공부 > JSP' 카테고리의 다른 글
아파치(Apache)/톰캣(Tomcat)이란? (0) | 2023.11.13 |
---|---|
서블릿에서 request으로 요청 URL 확인하기 (0) | 2022.10.13 |
[JSP] PreparedStatement 와 Statement 차이점 (0) | 2022.10.07 |
[JSP] 커넥션 풀 (0) | 2022.10.07 |
[JSP] JavaBean (1) | 2022.09.21 |
소중한 공감 감사합니다