표현 언어 (Expression Language)


JSP에서 사용가능한 새로운 스크립트 언어

EL의 주요 기능

- JSP의 네 가지 기본 객체가 제공하는 영역의 속성 사용

- 집합 객체에 대한 접근 방법 제공

- 수치 연산, 관계 연산, 논리 연산자 제공

- 자바 클래스 메서드(static method) 호출 기능 제공

- 표현언어만의 기본 객체 제공

간단한 구문 때문에 표현식 대신 사용



구문


기본 문법

${expr}, #{expr}

(p252 참조)


사용예

<jsp:include page="/module/${skin.id}/header.jsp" />

<b>${sessionScope.member.id}</b>님 환영합니다.


${expr} : 표현식이 실행되는 시점에 바로 값 계산

#{expr} : 값이 실제로 필요한 시점에 값 계산

JSP 템플릿 텍스트에서는 사용 불가


스크립트 요소(스크립트릿, 표현식, 선언부)를 제외한 나머지 부분에서 사용




EL에서 기본 객체


pageContext : JSP의 page 기본 객체와 동일하다. this와 같음.

pageScope : pageContext 기본 객체에 저장된 속성의 <속성, 값> 매핑을 저장한 Map 객체.

requestScope : request 기본 객체에 저장된 속성의 <속성, 값> 매핑을 저장한 Map 객체.

sessionScope : session 기본 객체에 저장된 속성의 <속성, 값> 매핑을 저장한 Map 객체.

applicationScope : application 기본 객체에 저장된 속성의 <속성, 값> 매핑을 저장한 Map 객체.

param : 요청 파라미터의 <파라미터이름, 값> 매핑을 저장한 Map 객체.

paramValues : 요청 파라미터의 <파라미터이름, 값배열> 매핑을 저장한 Map 객체.

header : 요청 정보의 <헤더이름, 값> 매핑을 저장한 Map 객체.

headerValues : 요청 정보의 <헤더이름, 값 배열> 매핑을 저장한 Map 객체.

cookie : <쿠키 이름, Cookie> 매핑을 저장한 Map 객체.

initParam : 초기화 파라미터의 <이름, 값> 매핑을 저장한 Map 객체.



예제) EL 내장 객체 사용
1) 보내는 FORM이 있는 jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%>
<%
session.setAttribute("test", "Session Test");
%>
<!DOCTYPE html>
<html>
<head>
<style>
table{border:solid 1px #ccc;}
.submit_btn{text-align:right;} 
</style>
<meta charset="UTF-8">
<title>EL 내장 객체 사용 예제</title>
</head>
<body>
<form action="el_ObjectTest02.jsp" method="post">
<filedset>
<legend>EL 내장 객체 사용 예제</legend>
<table>
<tr>
<td>이름</td><td><input type="text" name="name" value="홍길동" /></td>
</tr>
<tr>
<td colspan="2" class="submit_btn"><input type="submit" name="submit" value="확인" /></td>
</tr>
</table>
</filedset>
</form>
</body>
</html>

2) 받는 곳의 jsp
줄 위는 jsp 표현식, 줄 아래는 표현언어(EL)로 같은 내장 객체를 불러온 예이다.
<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%>
<%
request.setCharacterEncoding("UTF-8");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>EL 내장 객체 사용 예제</title>
</head>
<body>
<h2>JSP 표현식의 예</h2>
<%= request.getParameter("name") %>
<%= session.getAttribute("test") %>
<hr>
<h2>표현언어(EL)의 예</h2>
${param.name}
${sessionScope.test}
</body>
</html>

결과는 위와 아래가 동일하게 출력된다.




EL 데이터 타입

불리언(Boolean) 타입 - true 와 false
정수타입 - 0~9로 이루어진 정수 값.
실수타입 - 0~9로 이루어져 있으며, 소수점('.')을 사용할 수 있고, 3.24e3과 같이 지수형으로 표현 가능
문자열 타입 - 따옴표( ' 또는 " )로 둘러싼 문자열.
- 작은 따옴표 사용시, 값에 포함된 작은 따옴표는 \'로 입력
- \ 기호 자체는 \\ 로 표시한다.
널 타입 - null



EL에서 객체에 접근

${<표현1>.<표현2>} 형식 사용


처리 과정

1. <표현1>을 <값1>로 변환한다.

2. <값1>이 null이면 null을 리턴한다.

3. <값1>이 null이 아닐 경우 <표현2>를 <값2>로 변환한다.

<값2>가 null이면 null을 리턴한다.

4. <값1>이 Map, List, 배열인 경우

<값1>이 Map이면

<값1>.containsKey(<값2>)가 false이면 null을 리턴한다.

그렇지 않으면 <값1>.get(<값2>)를 리턴한다.

<값1>이 List나 배열이면

<값2>가 정수 값인지 검사한다. (정수 값이 아닐 경우 에러 발생)

<값1>.get(<값2>) 또는 Array.get(<값1>, <값2>)를 리턴한다.

위 코드가 예외를 발생하면 에러를 발생한다.

5. <값1>이 다른 객체이면

<값2>를 문자열로 변환한다.

<값1>이 이름이 <값2>이고 읽기 가능한 프로퍼티를 포함하고 있다면 프로퍼티의 값을 리턴한다.

그렇지 않을 경우 에러를 발생한다.




연산자

수치 연산자 : +, -, *, / 또는 div, % 또는 mod
비교 연산자 : == 또는 eq, != 또는 ne, 
< 또는 lt, <= 또는 le, > 또는 gt, >= 또는 ge
논리 연산자 : && 또는 and, || 또는 or, ! 또는 not
empty 연산자 : empty <값>
값이 null이면, true
값이 빈 문자열("")이면, true
값의 길이가 0인 배열이나 콜렉션이면 true
이 외의 경우에는 false
비교 선택 연산자 : <수식> ? <값1> : <값2>


예제) EL 연산자를 태그상에서 바로 실현
<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>EL 연산자 사용 예제</title>
</head>
<body>
<h3>\${ 5+7 } = ${ 5+7 }</h3>
<h3>\${ 5-7 } = ${ 5-7 }</h3>
<h3>\${ 5*7 } = ${ 5*7 }</h3>
<h3>\${ 5/7 } = ${ 5/7 }</h3>
<h3>\${ 5%7 } = ${ 5%7 }</h3>
<hr>
<h3>\${ 5==7 } = ${ 5==7 }</h3>
<h3>\${ 5!=7 } = ${ 5!=7 }</h3>
<h3>\${ 5>7 } = ${ 5>7 }</h3>
<h3>\${ 5<7 } = ${ 5<7 }</h3>
<h3>\${"10"+10} = ${"10"+10}</h3>
<hr>
<h3>\${ 5+3==8 ? 8:10 } = ${ 5+3==8 ? 8:10 }</h3>
</body>
</html>

결과)

${ 5+7 } = 12

${ 5-7 } = -2

${ 5*7 } = 35

${ 5/7 } = 0.7142857142857143

${ 5%7 } = 5


${ 5==7 } = false

${ 5!=7 } = true

${ 5>7 } = false

${ 5<7 } = true

${"10"+10} = 20


${ 5+3==8 ? 8:10 } = 8







EL에서 클래스 메서드 호출하기

클래스의 static 메서드를 EL에서 호출 가능

EL에서 호출하려면 다음의 작업 필요하다.
- EL 함수 정의한 TLD 파일 작성
- web.xml 파일에 TLD 파일 지정
- JSP 코드에서 TLD에 정의한 함수 실행

※ TLD : 태그 라이브러리 디스크립터(Tag Library Descriptor). 태그에 대한 메타정보를 담고 있는 XML 파일.


1) EL 함수에서 호출할 클래스 DateUtil.java 

package com.model;
import java.text.SimpleDateFormat;
import java.util.Date;

public class DateUtil {
private static SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
public static String format(Date date) {
return formatter.format(date);  
}
}


2) EL 함수를 정의한 TLD 파일 (WEB-INF 아래에 확장자가 .tld로 된 .xml 포멧으로 생성)
ex) WebContent/WEB-INF/tlds/el-functions.tld

<?xml version="1.0" encoding="UTF-8"?>
<taglib xmlns="http://java.sun.com/xml.ns/javaee" xmlns:xsi="http://www.w3.org/2001XMLSchema-instance" 
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
version="2.1">
    <description>EL에서 함수실행</description>
    <tlib-version>1.0</tlib-version>
    <short-name>ELfunctions</short-name>
    <function>
        <description>Date 객체 포맷팅</description>
        <name>dateFormat</name> <!-- EL에서 실제로 호출할 함수명 -->
        <function-class>com.model.DateUtil</function-class>
        <function-signature>
            java.lang.String format(java.util.Date) <!-- 반환형은 풀패키지명으로 경로까지 표시할 것! -->
        </function-signature>
    </function>  
</taglib>



3) web.xml 파일에 TLD 파일 지정


<web-app ... version=“3.1">

    <jsp-config>

        <taglib>

            <taglib-uri>

                /WEB-INF/tlds/el-functions.tld // JSP에서 사용될 URI

            </taglib-uri>

            <taglib-location>

                /WEB-INF/tlds/el-functions.tld // TLD 파일 경로

            </taglib-location>

        </taglib>

    </jsp-config>

</web-app>




4) JSP에서 EL 함수 호출 (viewToday.jsp)


<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<%@ taglib prefix="elfunc" uri="/WEB-INF/tlds/el-functions.tld" %>


<%

    java.util.Date today = new java.util.Date();

    request.setAttribute("today", today);

%>

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>EL 함수 호출</title>

</head>

<body>

오늘은 <Strong>${elfunc:dateFormat(today) }</Strong> 입니다. 

</body>

</html>

※ prefix:TLD에 정의된 함수명()


오늘은 2016-03-15 입니다.



※ JSP 2.2/EL .2 버전부터는 TLD 파일을 만들지 않고도 다이렉트로 메서드를 호출할 수 있게 되었다.

static이 아니라도 호출 가능하게 됨.


예제) 다이렉트로 메서드를 호출하는 예제


1) 섭씨온도를 화씨온도로 바꿔주는 클래스 Thermometer.java


package com.model;


import java.util.HashMap;

import java.util.Map;


public class Thermometer {

private Map<String, Double> locationCelsiusMap = new HashMap<String, Double>();


public void setCelsius(String location, Double value) {   // 지역과 온도를 해시맵으로 저장

locationCelsiusMap.put(location, value);  

}

public Double getCelsius(String location) {     // 지역으로 온도를 언어옴

return locationCelsiusMap.get(location);

}

public Double getFahrenheit(String location) {     // 섭씨온도를 화씨온도로 바꿈

Double celsius = getCelsius(location);

if(celsius == null) {

return null;

}

return celsius.doubleValue() * 1.8 + 32.0; 

}

public String getInfo() {

return "온도계 변환기 1.1";

}

}


2) 위의 클래스를 불러오는 thermometer.jsp


<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<%@ page import = "com.model.Thermometer" %>

<% 

Thermometer thermometer = new Thermometer();

request.setAttribute("t", thermometer);

%>

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>온도 변환 예제</title>

</head>

<body>

${t.setCelsius('서울', 27.3)}

서울 온도: 섭씨 ${t.getCelsius('서울')}도 / 화씨 ${t.getFahrenheit('서울')}

<br />

정보: ${t.info}

</body>

</html>


서울 온도: 섭씨 27.3도 / 화씨 81.14
정보: 온도계 변환기 1.1


※ getInfo 메서드는 원래 getInfo로 호출해야 하지만 get를 빼고 info란 이름으로도 호출 가능하다.

즉 표현언어는 출력용이므로 getter 메서드에 한해서 get을 빼고 프로퍼티 이름으로 호출 가능.




EL의 용법


request나 session 속성으로 전달한 값을 출력


액션 태그나 커스텀 태그의 속성 값

<jsp:include page="/lo/${layout.module}.jsp" flush="true" />


함수 호출 : 코드의 간결함 및 가독성 향상





EL 비활성화 방법
표현식을 작동시키지 않고 문자열로 인식시키는 방법

1) web.xml 파일에 비활성화 옵션 설정
<jsp-config>
    <jsp-property-group>
        <url-pattern>/oldversion/*</url-pattern> 
        <el-ignored>true</el-ignored>
    </jsp-property-group>
</jsp-config>
 <deferred-syntax-allowed-as-literal>를 이용한 #{expr}을 문자열로 처리
※ oldversion이라는 폴더 아래의 모든(*) 파일을 문자열로 처리한다는 세팅.


2) page 디렉티브에서 설정
- isELIgnored 속성을 true로 하면 EL 무시
- deferredSyntaxAllowedAsLiteral 속성을 true로 하면 #{expr}을 문자열로 처리

<%@ page isELIgnored="true" %>를 맨 위에 넣으면 해당 페이지의 표현식은 모두 문자열로 인식한다.

web.xml 파일 버전에 따라 자동 비활성화
- 서블릿 2.3 버전 : EL 지원하지 않음
- 서블릿 2.4 버전 : ${expr} 형식의 EL 지원

JSP와 서블릿 대응 상관도

JSP 2.3 / 서블릿 3.1

JSP 2.2 / 서블릿 3.0

JSP 2.1 / 서블릿 2.5 : EL 정식 지원 시작

JSP 2.0 / 서블릿 2.4 : EL 제안 시작

이하 버전은 EL 지원 안함.





Posted by netyhobby
,