[JSP/Servlet] 익스프레션 언어(EL식)
■ 들어가기
- 뇌를 자극하는 JSP&Servlet (김윤명/한빛미디어). 을 공부하며 정리하는 블로그
■ 목차
1. 익스프레션 언어의 기초 문법
2. 익스프레션 언어의 연산자
3. 익스프레션 언어로 자바의 정적 메서드 호출하기
1. 익스프레션 언어의 기초 문법 (EL식)
- EL 식의 문법 : ${ 식 }
- EL 식 예제
데이터 이름 하나로 구성된 EL 식 : ${ REQUEST }
연산자를 포함하는 EL 식 : ${ RESULT + 101 }
자바의 정적 메서드를 호출하는 EL 식: ${ m:sqrt(100) }
1-1. 데이터 이름 하나로만 구성된 EL 식
- 표기법: ${ RESULT }
- EL 식 안에 기술되는 데이터 이름은 "애트리뷰트 이름" 으로 해석됨
- JSP/Servlet 기술에서 사용되는 네 종류의 애트리뷰트
애트리뷰트 종류 | 호출할 때 사용하는 내장변수 | 메서드의 소속 | 데이터 전송 범위 | 용도 |
page 애트리뷰트 |
pageContext | javax.servlet.jsp.JspContext 클래스 |
현재 JSP 페이지 내 | 같은 JSP 페이지 안에 있는 스크립팅 요소와 익스프레션 언어 간의 데이터 교환 |
request 애트리뷰트 |
request | javax.servlet.ServletRequest 인터페이스 |
현재 웹 컴포넌트 및 forward, include 메서드를 통해 호출되는 또다른 웹 컴포넌트 | forward, include 메서드를 통해 호출되는 웹 컴포넌트로의 데이터 전달 |
session 애트리뷰트 |
session | javax.servlet.http.HttpSession 인터페이스 |
같은 세션에 속하는 모든 웹 컴포넌트 | 여러 화면으로 구성되는 애플리케이션에서 웹 컴포넌트 간의 데이터 전달 |
application 애트리뷰트 |
application | javax.servlet.ServletContext 인터페이스 |
같은 웹 애플리케이션에 속하는 모든 웹 컴포넌트 | 같은 웹 애플리케이션 디렉터리에 속하는 웹 컴포넌트들 간의 데이터 공유 |
- EL 식 안의 데이터 이름 해석되는 순서
page 애트리뷰트 -> request 애트리뷰트 -> session 애트리뷰트 -> application 애트리뷰트
1-2. 익스프레션 언어의 내장 객체
내장 객체 이름 | 표현하는 데이터 | 사용 예시 | 객체의 타입 |
param | 웹 브라우저에서 <form> 엘리먼트를 통해 입력된 데이터를 가져올 때 사용하는 내장 객체 | ${param.데이터이름} ex. ${param.NUM} |
Map |
paramValues | <checkbox>, <select> 서브 엘리먼트를 통해 똑같은 이름의 데이터가 여러 개 입력될 경우에 사용 | ${paramValues.데이터이름[인덱스]} ex. ${paramValues.ANIMAL[1]} |
Map |
header | HTTP 요청 메시지에 포함된 HTTP 헤더 값을 가져올 때 사용하는 내장 객체 | ${header["HTTP헤더이름"]} ex. ${header["User-Agent"]} |
Map |
headerValues | HTTP 요청 메시지 안에 똑같은 이름의 HTTP 헤더가 둘 이상 있을 때 header 내장 객체 대신에 사용 | ${headerValues["HTTP헤더이름][인덱스]} ex. ${headerValues["User-Agent"][1]} |
Map |
cookie | 웹 브라우저로부터 전송된 쿠키를 가져올 때 사용하는 내장 객체 (cookie.쿠키이름: 쿠키 객체를 의미) |
${cookie.쿠키이름.value} ${cookie["쿠키이름"]["value"]} ex. ${cookie.CART.value} ex. ${cookie["CART"]["value"]} |
Map |
initParam | 웹 애플리케이션의 초기화 파라미터 값을 가져다가 출력할 때 사용하는 내장 객체 - web.xml 파일 내 context-param 엘리먼트에 등록된 정보를 사용 |
${initParam.초기화 파라미터 이름} ${initParam.["초기화 파라미터 이름"]} ex. ${initParam.DB_NAME} ex. ${initParam.["DB_NAME"]} |
Map |
pageContext | JSP 페이지의 환경 정보를 제공하는 객체 | ${pageContext.get메서드.메서드} ex. ${pageContext.request.requestURI} |
PageContext |
- pageContext의 경우, java.servlet.jsp.PageContext 클래스에 속하는 get으로 시작하는 이름의 메소드 호출 가능
- 총 8개 메서드 : getError(), getException(), getPage(), getRequest(), getResponse(), getServletConfig(), getServletContext(), getSession()
- 사용법 : get이란 단어 떼고 카멜표기법으로 된 다음 대문자 단어를 소문자로 고친 후 사용
(단, 리턴값은 내장변수 requset와 동일한 객체로써 내부 메서드를 호출)
ex) getRequest -> pageContext.request.requestURI
2. 익스프레션 언어의 연산자
- 대부분 java의 연산자와 같은 기능 수행
- 산술 연산자, 비교 연산자, 논리 연산자, 조건 연산자는 java 연산자와 동일
구분 | 연산자 | 설명 |
산술 연산자 | + - * / % div mod |
덧셈, 뺄셈, 곱셉, 나눗셈, 나머지 |
비교 연산자 | < > <= >= == != lt gt le ge eq ne |
크기와 동등 여부 비교 ( 수치 데이터 비교 외에 문자 데이터 비교에도 사용 ) |
논리 연산자 | && || ! and or not |
논리적인 AND와 OR |
조건 연산자 | ? : | 조건에 따라 두 값 중 하나를 선택 |
엠프티 연산자 | empty | 데이터의 존재 유무 여부 확인 ex. ${empty NAME} |
대괄호와 마침표 연산자 |
[ ] . | 집합 데이터에 있는 한 항목 선택 - 배열 항목 - java.util.List 객체 데이터 항목 - java.util.Map 객체 데이터 항목 - 자바빈(JavaBean) 프로퍼티 |
괄호 | ( ) | 연산자의 우선 순위 지정 |
2-1. 대괄호와 마침표 연산자
A. 배열 항목
- java와 마찬가지로 배열 이름 다음에 대괄호로 묶은 인덱스 표시 : ${배열이름[인덱스]}
ex. ${ARR[0]}
B. java.util.List 객체 항목
- java.util.List는 java 표준 라이브러리에 있는 인터페이스이며,
이 인터페이스에는 여러 개의 데이터 항목을 저장하고 관리할 수 있는 메서드 존재
- java에서는 java.util.List의 구현 클래스인 java.util.ArrayList, java.util.LinkedList의 객체를 만들어 사용
- 배열과 마찬가지로 대괄호 연산자를 이용하여 사용 : ${List객체이름[인덱스]}
ex. ${list[2]}
C. java.util.Map 객체 항목
- java 표준 라이브러리에 있는 인터페이스이며,
이 인터페이스에는 데이터 항목을 <이름, 값> 쌍으로 만들어 저장하고 관리할 수 있는 메서드 존재
- java에서는 java.util.Map의 구현 클래스인 java.util.HashMap의 객체를 만들어 사용
- Map 객체에 저장한 데이터 값을 EL 식에서 사용하기 위해서는 대괄호 연산자나 마침표 연산자를 이용
${Map객체["데이터 이름"]} or ${Map객체.데이터 이름}
ex. ${map["John"]}, ${map.John}
D. 자바빈(JavaBean) 프로퍼티
- 자바빈 : JavaBean 규격서에 따라 작성된 자바 클래스 의미
- 규격서에 따르면,
1) 파라미터가 없는 생성자가 반드시 존재
2) 클래스 외부에서 필드(클래스의 멤버 변수)를 필요로 할 때는 직접 접근 불가, 반드시 메서드를 통해 접근 가능!
- 필드의 값을 읽는 메서드 이름은 get으로 시작해야 하고
- 필드에 값을 저장하는 메서드 이름은 set으로 시작해야 함
- 메서드를 통해 관리되는 데이터를 "프로퍼트(property)"라 지칭하며,
java 클래스 파일을 jsp 파일에 import하여 jsp 파일에서 EL 식으로 사용
3. 익스프레션 언어로 자바의 정적 메서드 호출하기
- 익스프레션 언어의 목적 : 데이터를 처리하는 로직 구사가 아니라 데이터 처리 결과를 출력하는 것
- 정적 메서드(static method) : java 클래스 안에 static 키워드를 붙여서 선언한 메서드를 의미
- EL 식에서 메서드 호출하기 위해서는 호출할 정적 메서드를 웹 컨테이너에 함수로 등록해야 함 => EL 함수로 지칭
3-1. 자바의 정적 메서드를 EL 함수로 등록하는 방법
- 서블릿 클래스를 웹 컨테이너에 등록하기 위해서 web.xml 파일에 등록을 했었는데
- EL 함수를 웹 컨테이너에 등록하기 위해서는, .tld라는 확장자를 갖는 TLD 파일에 등록 필요!
- TLD 파일은 web.xml 파일과 달리 하나의 웹 애플리케이션 디렉터리 내에 여러 개 존재 가능하고, 작성 방법도 상이함
[잠깐] TLD?
- 태그 라이브러리 디스크립터(Tag Library Descriptor)의 약자이며, 태그는 "액션 태그"를 의미
A. 작성 방법
- TLD 파일의 루트 엘리먼트는 <taglib>가 되어야 함 (web.xml 파일의 루트 엘리먼트는 <web-app>)
- <taglib> 안에는 <tlib-version>, <short-name> 이라는 두 개의 서브 엘리먼트를 반드시 써야 함
(<short-name>에는 태그 라이브러리의 이름 표시)
- <taglib> 엘리먼트 아래에 <function> 이라는 서브 엘리먼트 추가하고,
그 안에 <name>, <function-class>, <function-signature> 라는 3개의 서브 엘리먼트를 추가
- <taglib> 에는 TLD 문법의 식별자와 버전을 기재
<!-- 태그 라이브러리 골격 -->
<tag-lib xmlns="http://java.sun.com/xml/ns/javaee" version="2.1">
<tlib-version>1.0</tlib-version>
<short-name>태그 라이브러리 이름</short-name>
<function>
<name>EL 함수의 이름</name>
<function-class>정적 메서드가 속하는 자바 클래스의 풀네임</function-class>
<function-signature>정적 메서드의 시그니처(메서드 이름, 리턴 타입, 파라미터 타입)</function-signature>
</function>
</tag-lib>
- 예시 : java.lang.Math 클래스의 sqrt 메서드를 squareroot 라는 이름의 EL 함수로 등록
<taglib xmlns="http://java.sun.com/xml/ns/javaee" version="2.1">
<tlib-version>1.0</tlib-version>
<short-name>math</short-name>
<function>
<name>squareroot</name>
<function-class>java.lang.Math</function-class>
<function-signature>double sqrt</function-signature>
</function>
</taglib>
B. TLD 파일 설치
- 웹 애플리케이션 디렉터리의 WEB-INF 서브 디렉터리 아래 어느 곳이던 상관 없음
- 일반적으로 관리 편리성을 위해 WEB-INF 하위에 tlds 라는 서브 디렉터에 *.tld 파일을 저장하여 관리
- 생성한 TLD 파일을 web.xml 파일에 등록하여 웹 컨테이너에 TLD 파일 존재 알려야 함!
- web.xml 파일 작성 방법..
1) <web-app> 안에 <taglib> 라는 서브 엘리먼트 생성
2) <taglib> 안에 <taglib-uri>, <taglib-location> 의 두 개의 서브 엘리먼트 생성
(각각 TLD 파일의 식별자로 사용할 URI와 TLD 파일의 경로명 기재)
→ 2020.11.04 현재 위와 같이 작성하면 에러가 발생함!
→ 에러코드 : taglib definition not consistent with specification version
→ 에러원인 : web.xml 파일 내 taglib 엘리먼트를 <jsp-config> </jsp-config> 엘리먼트로 감싸 줘야 함!
참고: http://asq.kr/ll5RKV6pJA3PM
<web-app>
<jsp-config>
<taglib>
...
</taglib>
</jsp-config>
</web-app>
C. TLD 파일 호출
- jsp 페이지 내에서 EL 함수 사용하기 위해서는 taglib 지시자 사용
- taglib 지시자에는 uri, prefix 애트리뷰트 작성
(url: web.xml 파일에 기재했던 TLD 파일의 URI 지정, prefix: jsp 페이지 내에서 사용할 alias 지정(접두어))
- 사용 예시:
<%@taglib uri="/math-functions.tld" prefix="m" %>
..
${m:squareroot(4)}