JSTL과 EL - BE

JSP는 백엔드 개발자가 다 다룰 영역도 아니고 프론트 개발자나 디자이너가 많이 다뤄야할 부분도 아니고 섞여있다. 어떻게 하면 프론트 개발자나 디자이너가 봤을 때도 괜찮은 게 없을까? 라는 고민에서 EL, JSTL 같은 표현식이 나오고 MVC패턴이 등장하게 된 것이다.

EL(Expression Language)

  • EL은 우리나라 말로 말하면 표현언어이다.
  • EL은 값을 표현하는 데 사용되는 스크립트 언어로서 JSP의 기본 문법을 보완하는 역할을 한다.

표현 언어(EL)가 제공하는 기능

  • JSP의 스코프(scope)에 맞는 속성 사용
  • 집합 객체에 대한 접근 방법 제공
    • 집합 객체 : 컬렉션, 프레임워크에서 제공하는 객체
  • 수치 연산, 관계 연산, 논리 연산자 제공
  • 자바 클래스 메소드 호출 기능 제공
  • 표현언어만의 기본 객체 제공

표현 언어(EL)의 표현방법

표현 언어(EL)의 기본 객체

표현 언어(EL)의 기본 객체 사용 예제

표현 언어(EL)의 데이터 타입

  • 불리언 타입 - true와 false
  • 정수타입 - 0~9로 이루어진 정수 값 음수의 경우 ‘-‘가 붙음
  • 실수타입 - 0~9로 이루어져 있으며, 소수점(‘.’)을 사용할 수 있고, 3.24e3과 같이 지수형으로 표현 가능하다.
  • 문자열 타입 - 따옴표( ‘ 또는” )로 둘러싼 문자열. 만약 작은 따옴표(‘)를 사용해서 표현할 경우 값에 포함된 작은 따옴표는 ' 와 같이 \ 기호와 함께 사용해야 한다.
  • \ 기호 자체는 \ 로 표시한다.
  • 널 타입 - null

객체 접근 규칙

${<표현1>.<표현2>}
  • 표현 1이나 표현 2가 null이면 null을 반환한다.
  • 표현1이 Map일 경우 표현2를 key로한 값을 반환한다.
  • 표현1이 List나 배열이면 표현2가 정수일 경우 해당 정수 번째 index에 해당하는 값을 반환한다.
  • 만약 정수가 아닐 경우에는 오류가 발생한다.
  • 표현1이 객체일 경우는 표현2에 해당하는 getter메소드에 해당하는 메소드를 호출한 결과를 반환한다.

표현 언어(EL)의 연산자

수치 연산자, 비교 연산자, 논리 연산자, empty 연산자, 비교선택 연산자를 사용할 수 있다.

수치 연산자

  • 숫자가 아닌 객체와 수치 연산자를 사용할 경우 객체를 숫자 값으로 변환 후 연산자를 수행 : ${“10”+1} → ${10+1}
  • 숫자로 변환할 수 없는 객체와 수치 연산자를 함께 사용하면 에러를 발생 : ${“열”+1} → 에러
  • 수치 연산자에서 사용되는 객체가 null이면 0으로 처리 : ${null + 1} → ${0+1}

비교 연산자

  • == 또는 eq
  • != 또는 ne
  • < 또는 lt
  • > 또는 gt
  • <= 또는 le
  • >= 또는 ge
  • 문자열 비교: ${str == ‘값’} str.compareTo(“값”) == 0 과 동일
  • 주의사항 : 태그랑 같기 때문에 <,>는 영어로 바꾸어서 사용해야하는 경우도 있음

empty 연산자

1
empty <값>
  • <값>이 null이면 true를 리턴
  • <값>이 빈 문자열("")이면 true를 리턴
  • <값>이 길이가 0인 배열이면 true를 리턴
  • <값>이 빈 Map이면 true를 리턴
  • <값>이 빈 Collection이면 true를 리턴
  • 이 외의 경우에는 false를 리턴

비교선택 연산자

1
<수식> ? <값1> : <값2>

표현 언어 비활성화

  • JSP에 명시
  • <%@ page isELIgnored = "true" %>
    • default값은 false이다.

실습예제

scope별 표현 언어의 사용

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
    pageContext.setAttribute("p1", "page scope value");
    request.setAttribute("r1", "request scope value");
    session.setAttribute("s1", "session scope value");
    application.setAttribute("a1", "application scope value");
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
pageContext.getAttribute("p1") : ${pageScope.p1 }<br>
request.getAttribute("r1") : ${requestScope.r1 }<br>
session.getAttribute("s1") : ${sessionScope.s1 }<br>
application.getAttribute("a1") : ${applicationScope.a1 }<br>
<br><br>
pageContext.getAttribute("p1") : ${p1 }<br>
request.getAttribute("r1") : ${r1 }<br>
session.getAttribute("s1") : ${s1 }<br>
application.getAttribute("a1") : ${a1 }<br>

</body>
</html>
  • 명시적으로 작성해주는 것이 좋음
    • session.getAttribute("s1") : ${s1 }보단 session.getAttribute("s1") : ${sessionScope.s1 } 이렇게 작성해주기


JSTL(JSP Standard Tag Library)

  • JSTL(JSP Standard Tag Library)은 JSP 페이지에서 조건문 처리, 반복문 처리 등을 html tag형태로 작성할 수 있게 도와준다.
  • 초창기에는 JSP가 스크립트릿의 자바코드와 HTML태그가 섞여있는 형태, 개발의 편의성은 높았지만 HTML태그와 자바코드가 섞여있어서 프론트 개발자가 해당 코드를 수정하기가 어렵고 유지 보수가 어렵다. 그래서 JSTL이 등장했다.
    • 프론트 개발자들은 태그가 조금 더 친숙하기 때문에 JSTL은 태그 형식으로 로직을 수행할 수 있도록 도와준다.

JSTL 사용방법

JSTL이 제공하는 태그의 종류

  • 코어가 가장 중요함
    • 코어 기능에 조건문, 반복문 등을 처리할 때 사용된다.

코어태그

코어태그 : 변수 지원 태그 - set, remove

지시자

  • 태그를 누가 가진 것인지 확인하기 위해 prefix를 지정해가지고 사용할 때 쓸 수 있게 도와준다.
1
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

변수 설정 : 지정한 영역에 변수를 생성한다.

1
2
3
4
<c:set var="varName" scope="session" value="someValue"/>
<c:set var="varName" scope="request">
some Value
</c:set>
  • var : EL에서 사용될 변수명
  • scope : 변수값이 저장될 영역(page, request, session, application)
  • value : 변수값

변수 제거

1
<c:remove var="varName" scope="request">

코어태그 : 변수 지원 태그 - 프로퍼티, 맵의 처리

프로퍼티 : 객체의 값을 변경하거나 값을 읽어들이기 위한 getter, setter 메서드를 생각해주기

1
<c:set target="${some}" property="propertyName" value="anyValue" />
  • some 객체가 자바빈일 경우 : some.setPropertyName(anyvalue)
  • some 객체가 맵(map)일 경우 : some.put(propertyName, anyValue)
  • target : <c:set>으로 지정한 변수 객체
  • property : 프로퍼티 이름
  • value : 새로 지정할 프로퍼티 값

코어태그 : 흐름제어 태그 - if

1
2
3
<c:if test="조건">
//test의 조건이 true이면 몸체 내용을 처리한다.
</c:if>
  • else에 대한 처리는 없음

코어태그 : 흐름제어 태그 - choose

1
2
3
4
5
6
7
8
9
10
11
<c:choose>
  <c:when test="조건1">
    // 조건 1이 true일 때 실행
  </c:when>
  <c:when test="조건1">
    // 조건 2가 true일 때 실행
  </c:when>
  <c:otherwise>
    // 앞의 <c:when>의 조건들이 모두 만족하지 않을 때에 실행
  </c:otherwise>
</c:choose>

코어태그 : 흐름제어 태그 - forEach

1
2
3
4
5
<c:forEach var="변수" items="아이템" [begin="시작번호"] [end="끝번호"]>

${변수}

</c:forEach>
  • var : EL에서 사용될 변수명
  • items : 배열, List, Iterator, Enumeration, Map 등의 Collection
  • begin : items에 지정한 목록에서 값을 읽어올 인덱스의 시작값 (선택)
  • end : items에 지정한 목록에서 값을 읽어올 인덱스의 끝값 (선택) * item이 Map인 경우 변수에 저장되는 객체는 Map.Entry이다. 따라서, 변수값을 사용할 때는 ${변수.key}와 ${변수.value}를 사용해서 맵에 저장된 항목의 <키, 값> 매핑에 접근할 수 있다.

코어태그 : 흐름제어 태그 - import

1
2
3
<c:import url="URL" charEncoding="캐릭터인코딩" var="변수명" scope="범위">
    <c:param name="파라미터이름" value="파라미터값"/>
</c:import>
  • url : 결과를 읽어올 URL
  • charEncoding : 읽어온 결과를 저장할 때 사용할 캐릭터 인코딩
  • var : 읽어온 결과를 저장할 변수명
  • scope : 변수를 저장할 영역
  • <c:param>태그는 url속성에 지정한 사이트에 연결할 때 전송할 파라미터를 입력 (선택)

코어태그 : 흐름제어 태그 - redirect

지정한 페이지로 리다이렉트한다. response.sendRedirect()와 비슷

1
2
3
<c:redirect url="리다이렉트할 URL">
    <c:param name="파라미터이름" value="파라미터값" />
</c:redirect>
  • url : 리다이렉트 URL
  • <c:param>은 리다이렉트할 페이지에 전달할 파라미터 지정
  • 페이지가 이동하기 때문에 다른 소스코드들은 별로 필요가 없고 쓰이지 않는다.

코어태그 : 기타태그 - out

JSPWriter에 데이터를 출력한다.

1
<c:out value="value" escapeXml="{true|false}" defalut="defaultValue" />
  • value : JspWriter에 출력할 값을 나타낸다. 일반적으로 value 속성의 값은 String과 같은 문자열이다. 만약 value의 값이 java.io.Reader의 한 종류라면 out태그는 Reader로부터 데이터를 읽어와 JspWriter에 값을 출력한다.
  • escapeXml : 이 속성의 값이 true일 경우 아래 표와 같이 문자를 변경한다. 생략할 수 있으며, 생략할 경우 기본값은 true이다.
  • default : value속성에서 지정한 값이 존재하지 않을 때 사용될 값을 지정한다.
  • 1
    2
    3
    <c:set var="t" value="<script type='text/javascript'>alert(1);</script>"/>
    <c:out value="value" escapeXml="true"> // 문자로 출력
    <c:out value="value" escapeXml="false"> // 팝업창으로 실행됨
    


참고