본문 바로가기

Servlet, JSP

JSP EL(Expression Language)에 대해

 

JSP에서 EL(Expression Language)은 데이터를 출력하는 강력하고 간결한 도구입니다. 복잡한 자바 코드를 JSP 페이지에 직접 작성하는 대신, 간단한 문법으로 Scope(영역)에 저장된 데이터를 쉽게 가져와서 사용할 수 있습니다.

이번 글에서는 EL의 기본적인 개념부터 시작해, JSP의 다양한 내장 객체와 함께 데이터를 다루는 방법을 예제를 통해 자세히 살펴보겠습니다.


1. EL(Expression Language)이란?

EL은 JSP 페이지에서 데이터를 표현하는 데 특화된 언어입니다. HTML 코드 안에 스크립틀릿(`<% ... %>`)을 사용해 데이터를 출력하면 코드가 복잡해지고 가독성이 떨어지지만, EL을 사용하면 훨씬 깔끔하게 데이터를 표시할 수 있습니다.

  • 기본 형식: ${ 표현식 }
  • 특징:
    • Scope(영역)에 저장된 데이터에만 접근할 수 있습니다.
    • 문자, 숫자, Boolean(true, false), null 등을 직접 표현할 수 있습니다.
    • \${ ... }와 같이 역슬래시(\)를 사용하면 EL 문법이 아닌 일반 텍스트로 인식됩니다.
    • EL 문법 오류가 발생하면 HTTP 500 – 내부 서버 오류가 발생합니다.

2. EL 연산자

EL은 다양한 연산자를 지원하며, JSP 스크립틀릿(`<% ... %>`)보다 간결하게 연산을 수행할 수 있습니다. 다음 예제를 통해 EL의 연산자들을 확인해 보세요.

EL 연산자 예제


<body>
    <hr>
        <h4>EL 연산자(산술)</h4>
    <hr>
    \${ 3+1 } => ${ 3+1 } <br>
    \${ 3-1 } => ${ 3-1 } <br> <!-- 사용자 입력에 3+1로 되어있어 3-1로 수정함 -->
    \${ 3*2 } => ${ 3*2 } <br>
    \${ 10/3 } => ${ 10/3 } or \${ 10 div 3 } => ${ 10 div 3 } <br>
    <%-- ${ 10 div 3 }은 eclipse가 div를 html태그의 div와 혼동하여 에러라고 인식함--%>
    \${ 3%2 } or \${ 3 mod 2 } => ${ 3%2 } <br>
    <hr>
        <h4>EL 연산자(관계)</h4>
    <hr>
    <!-- gt : Greater than -->
    \${ 3>1 } or \${ 3 gt 1 } => ${ 3>1 } <br>
    <!-- ge : Greater Equal -->
    \${ 3>=1 } or \${ 3 ge 1 } => ${ 3>=1 } <br>
    <!-- lt : Less than -->
    \${ 3<1 } or \${ 3 lt 1 } => ${ 3<1 } <br>
    <!-- le : Less Equal -->
    \${ 3<=1 } or \${ 3 le 1 } => ${ 3<=1 } <br>

    <!-- eq : Equal -->
    \${ 3==1 } or \${ 3 eq 1 } => ${ 3==1 } <br>
    <!-- ne : Not Equal -->
    \${ 3!=1 } or \${ 3 ne 1 } => ${ 3!=1 } <br>
   
    <hr>
        <h4>EL 연산자(삼항연산자 및 empty)</h4>  
    <hr>
    \${ 3>=0 ? '양수' : '음수' } => ${ 3>=0 ? '양수' : '음수' } <br>
   
<!--     http://localhost:8080/2025_0820_EL_JSTL/el/_01_ex_el1.jsp?msg=%EC%95%88%EB%85%95 -->
    전달받은 메시지 : ${ empty param.msg ? "없음" : param.msg }
   
</body>
    

3. JSP와 EL의 Scope(영역) 객체

JSP는 데이터를 저장하고 공유하는 4가지 Scope(영역)를 가지고 있습니다. JSP 스크립틀릿(`<% ... %>`)과 EL은 이 영역을 다루는 방식에 차이가 있습니다.

용도 JSP(저장) EL(조회) 설명
페이지 pageContext pageScope 현재 페이지 내에서만 유효합니다.
요청 request requestScope 하나의 HTTP 요청이 끝날 때까지 유효합니다.
세션 session sessionScope 웹 브라우저가 닫히거나 세션이 만료될 때까지 유효합니다.
애플리케이션 application applicationScope 서버가 종료될 때까지 유효하며, 모든 사용자가 공유합니다.

JSP와 EL Scope 활용 예제


<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
    /* 
        EL : 조회용 표현언어
        JSP 내장객체 : pageContext, request, session, application
    */
    //                  bindingAPI(data 연결)
   pageContext.setAttribute("msg", "pageScope 영역"); /* 나만 살아있음 */
    request.setAttribute("msg", "requestScope 영역"); /* 요청을 받을 때만 살아있음 */
    session.setAttribute("msg", "sessionScope 영역"); /* 브라우저를 닫기 전까지는 살아있음 */
    application.setAttribute("msg", "applicationScope 영역"); /* 서버를 닫기 전까지는 살아있음 */
   
    String name = "홍길동"; 
    /*request.setAttribute("name", name); 4개의 영역 중 어디에 넣어도 name 스트링은 인식됨. 
    ! 브라우저를 닫기 전까지 session에 저장이 된다고 데이터값을 너무 session에 넣으면 서버 메모리가 부족해지고 다운되기 쉬워짐.*/
   
%>    

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

이름 : ${ name } <br>       <!-- Scope영역 내의 value만 사용할 수 있어서 String name만 정의했을 경우 page에서 공란으로 출력됨 -->
                       <!--${ 영역명.변수명 }  -->
pageContext 영역 내의 Data : ${ pageScope.msg } <br>
requestContext 영역 내의 Data : ${ requestScope.msg } <br>
sessionContext 영역 내의 Data : ${ sessionScope.msg } <br>
applicationContext 영역 내의 Data : ${ applicationScope.msg } <br>
 
<!-- EL에서 영역명을 생략하면 어떤 영역의 데이터가 사용될까? 
    참조 순서 : pageScope → requestScope → sessionScope → applicationScope  
    -->

???Scope ${ msg } <br>
 
</body>
</html>
    

예제 코드 분석

  • String name = "홍길동";: 이 변수는 Scope에 저장되지 않았기 때문에, ${ name }으로 출력하려고 하면 아무것도 표시되지 않습니다. EL은 반드시 Scope에 저장된 값만 접근할 수 있습니다.
  • ${ msg }: EL에서 Scope를 생략하면 pageScoperequestScopesessionScopeapplicationScope 순서로 변수를 찾습니다. 따라서 이 예제에서는 pageScope에 저장된 "pageScope 영역"이 출력됩니다.

4. EL을 이용한 Map 데이터 출력

EL은 Map이나 VO(Value Object)와 같은 객체의 데이터도 쉽게 가져올 수 있습니다. 특히 Map에 저장된 데이터를 출력할 때 EL은 스크립틀릿보다 훨씬 간결하고 직관적인 문법을 제공합니다.

Map 출력 예제

<%@page import="java.util.HashMap"%>
<%@page import="java.util.Map"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
<%
                /* Object는 어떤 type의 value도 저장 가능함 */
    Map<String,Object> map = new HashMap<String,Object>();
   
    map.put("name","홍길동");
    map.put("age",30);
    map.put("gender","남성");
    map.put("eye_left", 1.0);
    map.put("eye_right", 0.8);
    map.put("married", true);
   
    //EL 사용을 위한 mapping
    pageContext.setAttribute("map", map);
   
%>    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
이름 : <%= map.get("name") %> <br>
이름 : ${ map.name } <br><!-- EL이 더 간결함  -->
이름 : ${ pageScope.map.name } <br>
<!-- dot 표기법 -->
나이 : ${ map.age } <br>
<!-- square bracket 표기법 -->
성별 : ${ map['gender'] } <br>
<!-- ""도 가능 -->
결혼 유무 : ${ map["married"] } <br>
시력(좌/우) : ${ map.eye_left }/${ map.eye_right } <br>
map : ${ map } <br>
</body>
</html>
    

예제 코드 분석

  • 스크립틀릿 vs EL: Map의 값을 출력할 때 스크립틀릿은 map.get("key") 형태를 사용해야 하지만, EL은 . (점) 표기법(map.name)이나 대괄호([]) 표기법(map['gender'])을 사용해 간결하게 접근할 수 있습니다.

5. EL을 이용한 VO(Value Object) 데이터 출력

EL은 VO 클래스의 Getter 메서드를 자동으로 호출하여 멤버 변수에 접근합니다. 이 방식은 JSP 페이지와 자바 클래스 간의 데이터 연동을 매우 효율적으로 만듭니다.

VO(PersonVo.java) 예제

package vo;

//ValueObject(값을 관리하는 객체);
public class PersonVo {
    String  name;
    int     age;
    String  addr;
   
    public PersonVo() {
        // TODO Auto-generated constructor stub
    }

    public PersonVo(String name, int age, String addr) {
        super();
        this.name = name;
        this.age = age;
        this.addr = addr;
    }
   
    //getter, setter가 없는 경우 el단에서 출력을 못함.
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getAddr() {
        return addr;
    }

    public void setAddr(String addr) {
        this.addr = addr;
    }
   
}
    

EL을 이용한 VO 데이터 출력 예제


<%@page import="vo.PersonVo"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
<%
    PersonVo p = new PersonVo("홍길동",30,"서울시 관악구");

    pageContext.setAttribute("p", p);
   

%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
이름 : ${ p.name } <!-- p.getName() call --> <br>
<!-- getter를 주석처리하는 경우 생기는 오류(console단에서 확인할 것!) :  
Stacktrace:]을(를) 발생시켰습니다.
jakarta.el.PropertyNotFoundException: [vo.PersonVo] 유형에서 [name] 특성을 읽을 수 없습니다. -->
나이 : ${ p.age } <br>
주소 : ${ p.addr } <br>
</body>
</html>
    

예제 코드 분석

  • ${ p.name }: 이 코드는 내부적으로 p.getName() 메서드를 호출합니다. EL은 Vo 객체의 속성명(name)을 찾아 해당하는 get 메서드를 자동으로 실행합니다.
  • 주의: 만약 Vo 클래스에 Getter 메서드가 없다면 PropertyNotFoundException 오류가 발생합니다. EL은 Getter를 통해 데이터에 접근하기 때문에 반드시 필요합니다.