ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Camel][JSP] 표현 언어 ( Expression Language)
    JSP 2020. 3. 20. 22:47

    1. 표현언어(Expression Language)란?

     표현언어는 값을 표현하는데 사용되는 새로운 스크립트 언어니다. 표현언어는 JSP의 기본문법을 보완하는 역할을 하게됩니다. 표현언어의 기능은 아래와 같습니다. 

     

    • JSP 기본객체가 제공하는 영역의 속성을 사용한다.
    • 집합 객체에 대한 접근 방법을 제공한다.
    • 수치 연산, 관계 연산, 논리 연산자를 제공한다.
    • Java 클래스 메소드 호출 기능을 제공한다.
    • 표현언어만의 기본 객체를 제공한다.

     

     

    2. 표현언어의 형식, 구문

    2-1. ${expression} 형식

    표현언어는 아래와 같이 '$'와 표현식 그리고 중괄호를 사용해서 값을 표현합니다. 

    ${expression}
    
    <jsp:include page"/camel/${member.id}/pig.jsp"/>
    
    <b>${sessionScope.member.id}</b> Welcome!

     expression에는 표현 언어가 정의한 문법에 따라 값을 표현하는 식이 오게됩니다. 표현언어는 액션태그나 커스텀 태그의 속성 값으로 사용할 수 있습니다. 또한, 태그의 값으로 사용하는 것뿐만 아니라 비스크립트 요소 부분에서도 표현식으로 값을 출력하기 위해 사용할 수 있씁니다.

     

     표현언어는 JSP 스트립트 요소를 제외한 나머지에서 사용가능하며, 표현언어를 사용하면 보다 간편하게 값을 출력할 수 있습니다.

     

    2-2. #{expression} 형식

     표현언어의 형식에는 '$' 대신 '#'을 사용한 표현언어의 형식도 존재합니다. ${expression}과 #{expression}의 차이점은 표현언어의 값의 생성시기입니다. ${expression} 형식은 ${expression}구문을 분석할 때 바로 값을 계산하는 반면, #{expression} 형식은 실제로 값이 사용될 때 값을 계산합니다. 

     

     이처럼 실제 값이 사용될 때 값을 계산하기 때문에 Deferred Expression 이라고도 합니다. 하지만 이러한 특징으로 인해 아래처럼 JSP 템플릿 텍스트에서의 사용은 불가능합니다. 

    <%-- 사용 불가능 --%>
    #{sessionScope.member.id}> Welcome!

     

     

    3. 표현언어의 기본 객체

     JSP에서 필요한 정보에 쉽게 접근할 수 있도록 기본객체를 제공하듯이, 표현언어도 역시 기본객체를 제공합니다. 표현언어의 기본객체를 사용해 요청 파라미터나 세션의 속성 값과 같은 것들을 표현식에서 쉽게 사용할 수 있습니다. 표현언어에서 제공하는 기본객체는 아래와 같습니다. 

    기본 객체 설명
    pageContext JSP의 page 기본객체와 동일
    pageScope pageContext 기본객체에 저장된 속성의 <속성, 값> 매핑을 저장한 Map 객체
    requestScope request기본객체에 저장된 속성의 <속성, 값> 매핑을 저장한 Map 객체
    sessionScope session기본객체에 저장된 속성의 <속성, 값> 매핑을 저장한 Map 객체
    applicationScope application 기본객체에 저장된 속성의 <속성, 값> 매핑을 저장한 Map 객체
    param 요청 파라미터의 <속성, 값> 매핑을 저장한 Map 객체. 파라미터 값의 타입은 String으로써 request.getParameter(파라미터이름)의 결과와 동일
    paramValues 요청 파라미터의 <속성, 값배열> 매핑을 저장한 Map 객체. 파라미터 값의 타입은 String[]으로써 request.getParameterValues(파라미터이름)의 결과와 동일
    header 요청 정보의 <header이름, 값> 매핑을 저장한 Map 객체. request.getHeader(header이름)의 결과와 동일.
    headerValues 요청 정보의 <header이름, 값배열> 매핑을 저장한 Map 객체. request.getHeaders(header이름)의 결과와 동일.
    cookie <cookie이름, cookie> 매핑을 저장한 Map 객체. request.getCookies()로 구한 Cookie배열로부터 매핑을 생성
    intParam 초기화 파라미터의 <이름, 값> 매핑을 저장한 Map 객체. application.getIntParameter(이름)의 결과와 동일

     

     한가지 알아두어야 할 표현언어의 특징 중 하나는 값이 존재하지 않을 경우 null을 출력하는 것이 아니라 아무것도 출력하지 않는다는 것입니다. 추가적으로, 표현언어는 객체의 값에 접근할 때 JavaBean 객체의 프로퍼티를 사용합니다. 

     

     

    4. 표현언어의 사용

    표현언어는 일종의 스크립트 언어로서 다양한 연산자와 자료타입을 제공합니다. 표현언어는 정수, 실수, Boolean, 문자열, 널 타입을 제공하며 표현 방식은 아래에 설명하겠습니다. 

    • 정수 - 0~9로 이루어진 정수 값. 음수의 경우 '-'가 붙는다.
    • 실수 - 0~9로 이루어지며, '.'을 사용할 수 있고 지수형으로도 표현가능하다.
    • Boolean - true, false
    • 문자열 - 따옴표로 둘러싸서 표현한다. 작은 따옴표를 사용할 경우 \'과 같은 방식으로 사용해야하며, \ 기호는 \\로 표현한다.
    • 널 - null

     

    4-1. 표현언어의 객체 접근과 탐색

    표현언어는 객체에 저장된 값에 접근할 때 '.'이나 '[ ]'를 사용합니다. 이 둘을 동일한 역할을 수행하기 때문에 cookie.name과 cookie[name]은 동일한 결과를 나타냅니다. 

     

    표현언어에서 Page, Reauest, Session, Application 영역에 저장된 속성에 접근하기 위해서는 pageScope, requestScope, sessionScope, applicationScope 기본객체를 사용합니다. 예를 들어, Page영역에 저장되어 있는 속성의 값을 참고하는 코드는 아래와 같습니다. 

    ${pageScope.NAME}

    하지만 위의 코드의 pageScope와 같은 표현언어 기본객체를 사용하지 않고 이름만 지정할 경우 표현언어는 네 개의 영역을 차례로 검색해 속성이 존재하는지를 확인합니다. 만약 속성이 존재할 경우 그 속성의 값을 사용하게됩니다. 

     

     

    4-2. 표현언어의 연산자 우선순위

    표현언어에서 사용되는 연산자들은 우선 순위를 가지고 있으며, 그 우선순위는 아래와 같습니다.(위쪽에 위치할수록 높은 우선순위입니다.)

    • []
    • ()
    • -(단일), not, !, empty
    • *, /, div, %, mod
    • +, -
    • <>, <=, >=, ltgt, le, ge
    • ==, !=, eq, ne
    • &&, and
    • ||, or
    • ?, :

    같은 줄에 있는 연산자의 우선순위는 같으며 우선 순위가 같은 연산자끼리의 연산 순서는 왼쪽에서 오른쪽입니다. 

     

     

     

    4-3. 표현언어의 클래스 정적(static) 메소드 호출

     표현식을 사용하면 Java의 클래스를 마음대로 사용할 수 있었습니다. 그러나 표현언어에서는 직접적으로 Java의 클래스를 사용할 수 없습니다.

     

     그렇다면 표현언어로는 Java의 클래스를 절대 사용할수 없을까? 정답는 '아니오'입니다. 

     표현언어에서 클래스의 메소드를 사용하기 위해서는 클래스의 메소드를 static으로 정의해 주어야합니다. 그렇기 때문에 static으로 정의되어있지 않은 메소드는 사용할 수 없습니다. 

     그러나 static으로 정의만하면 되는것이 아니라 클래스 파일을 작성한 후 다음으로 TLD 파일을 작성해주어야 합니다.

    TLD는 Tag Library Decriptor의 약자입니다. TDL 파일은 태그 라이브러리에 대한 설정 정보를 가지고 있으며 일반적으로 WEB-INF/tlds 디렉터리나 WEB-INF/jsp 디렉터리와 같은 곳에 위치시킵니다. tld 파일의 구성은 아래와 같습니다. 

     

    WEB-INF/tlds/el.tld

    <?xml version="1.0" encoding="utf-8" ?>
    
    <taglib xmlns="http://java.sun.com/xml/ns/javaee" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-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>표현언어에서의 메소드 호출</description>
        <tlib-version>1.0</tlib-version>
        <short-name>ELfunctions</short-name>
    
        <function>
            <description>Date 객체 Formatting</description>
            <name>dateFormat</name>
            <function-class>mvjsp.chap15.DateUtil</function-class>
            <function-signature>
                java.lang.String format(java.util.Date)
            </function-signature>
        </function>
    
    </taglib>
    

     <function> 태그는 표현언어에서 사용할 함수를 정의할 때 사용하는 태그입니다. 하나의 함수 당 하나의 <function> 태그를 사용합니다.

     <name> 태그는 표현언어에서 사용할 함수의 이름을 정의하는 태그이며,

     <function-class> 태그는 표현언어가 사용할 함수 기능을 제공할 클래스의 완전한 이름을 지정하는 태그입니다. 

     <function-signature> 태그는 함수 기능을 실행할 메소드를 가리킵니다. 이때 반환형과 파라미터의 타입은 완전한 클래스의 이름을 사용합니다. 파라미터의 경우 이름을 제외한 타입만 지정해줍니다.

     

     tld 파일을 작성했다면 이제는 web.xml 파일에 tld 파일에 대한 내용을 추가해 주면됩니다. 그 예는 아래와 같습니다. 

     

    web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns="http://java.sun.com/xml/ns/javaee"
    	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    		http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    	version="3.0">
    	
    	<jsp-config>
    		<taglib>
    			<taglib-uri>
    				/WEB-INF/tlds/el.tld
    	        </taglib-uri>
    			<taglib-location>
    				/WEB-INF/tlds/el.tld
    	        </taglib-location>
    		</taglib>
    		
    		<jsp-property-group>
    			<url-pattern>/oldversion/*</url-pattern>
    			<el-ignored>true</el-ignored>
    		</jsp-property-group>
    		
    	</jsp-config>
    
    </web-app>

    이 모든 과정을 수행했다면 이제는 표현언어에서 메소드를 사용할 수 있습니다. 표현언어에서 메소드를 사용하기 위해서는 JSP 페이지에서 taglib 디렉티브를 작성해 줘야하며 그 작성법과 표현언어의 메소드 사용법은 아래와 같습니다. 

    <%@ page contentType = "text/html; charset=utf-8" %>
    <%@ page session="false" %>
    <%@ taglib prefix="elfunc" uri="/WEB-INF/tlds/el.tld" %>
    <%
    	java.util.Date today = new java.util.Date();
    	request.setAttribute("today", today);
    %>
    <html>
    <head><title>EL Method</title></head>
    <body>
    
    Today is <b>${elfunc:dateFormat(today) }</b>.
    
    </body>
    </html>

    한 가지 주의해야할 점은 표현언어에서 taglib로 지정한 메소드를 호출할 때에는 실제 사용할 클래스의 메소드의 이름이 아닌 TLD 파일의 <name> 태그에 지정한 이름을 사용해야 한다는 점입니다. 

     

     

     

    4-4. 표현언어의 활용

    표현언어를 활용할수 있는 대표적인 예시로는 <jsp:forward> 태그와 <jsp:include> 태그에 속성으로 전달한 값을 활용할 때입니다. 

     <jsp:forward> 태그를 사용해 웹 처리 흐름의 이동이 있을 때, request.setAttribute 메소드를 사용해서 값을 전달합니다. 그리고 포함되는 페이지에서 request 기본객체의 속성으로 전달받은 값을 사용할 경우 표현언어를 사용하면 코드의 간결함을 확인할 수 있습니다. 

     <jsp:include> 태그의 경우 page 속성을 통해 포함할 JSP 페이지의 uri를 입력받는데, 이때 표현언어를 사용하면 page 속성의 값은 간결하게 표현될 수 있습니다. 

     

     

    4.5 표현언어의 비활성화

     기존에 표현언어를 지원하지 않는 JSP 엔진에서 작성한 JSP 페이지의 코드는 그대로 사용하고 JSP 엔진만 바꾸는 경우 기존 코드에 있던 ${expression}과 같은 코드는 에러를 발생시킬 수있습니다. 그렇기 때문에 표현언어는 비활성화가 가능합니다. 이러한 비활성화를 위한 방법은 총 3가지가 있습니다. 

     

    4.5.1 web.xml 파일에 표현언어 비활성화 옵션 추가

    <jsp-property-group> 태그 내부의 <el-ignored> 태그를 true로 설정하면 <url-pattern> 태그로 명시한 URL 패턴에 매칭되는 JSP는 표현언어의 형식을 모두 일반 문자열로 처리하게됩니다. 

     그리고 만약 ${expression}은 표현언어로 처리하고 싶고 #{expression}은 일반 문자열로 처리하고 싶다면, <el-ignored> 태그대신 <deferred-syntax-allowed-as-literal> 태그를 사용하고 태그의 값으로 true를 지정해주면 됩니다. 

    4.5.2 JSP 페이지에서 표현언어 비활성화 시키기

    jsp 페이지의 page 디렉티브를 사용하면 표현언어를 비활성화 시킬 수 있습니다. 표현언어 비활성화와 관련된 page 디렉티브의 속성은 아래와 같습니다. 

    •  isELIgnored - true일 경우 표현언어를 일반 문자열로 처리.
    • deferredSyntaxAllowedAsLiteral - true일 경우 표현언어 형식 #{expression} 만 일반 문자열로 처리.

    4.5.3 web.xml 파일의 버전에 따른 표현언어 비활성화 처리

     web.xml 파일이 따르는 서블릿 버전에 따라서 표현언어의 지원 여부를 정할 수 있습니다. 

    • 서블릿 2.3 web.xml - 표현언어를 지원하지 않음
    • 서블릿 2.4 web.xml - #{expression} 을 지원하지 않음
    • 서블릿 2.5/3.0 web.xml - 표현언어를 지원.

    댓글

Camel`s Tistory.