프로퍼티의 프로퍼티를 스크립틀릿이나 표준액션으로만 표현하기가 어렵거나 아예 불가능한 경우가 있다.
즉 다음과 같은 서블릿 코드를 스크립틀릿이나 표준액션으로 표현하려고 하면 다음과 같이 표현할 수 밖에 없을 것이다.

    public void doPost(HttpServletRequest request, HttpServletResponse response)
                throws IOException, ServletException {
        foo.Person p = new foo.Person();
        p.setName("Evan");
       
        foo.Dog dog = new foo.Dog();
        dog.setName("spike");
        p.setDog(dog);
       
        request.setAttribute("person", p);
       
        RequestDispatcher view = request.getRequestDispatcher("result.jsp");
        view.forward(request, response);
    }

<%= ((foo.Person) request.getAttribute("person")).getDog().getName() %>

<jsp:useBean id="person" class="foo.Person" scope="request" />
<jsp:getProperty name="person" property="dog"/>

스크립틀릿으로 쓰면 결과물은 제대로 나오지만 많이 지져분한 모습이다.
표준액션을 사용하게 되면 dog라는 프로퍼티가 있는 것이 아니라 dog라는 객체안에 있는 name이라는 프로퍼티를 출력해야 하므로 결과가 잘못 나오게 된다.

이런 경우를 위해서 사용하는 것이 EL(Expression Language) 이다.
위 내용을 EL로 표현하게 되면 ${person.dog.name} 이라고 간단하게 표현할 수 있는 것이다.
EL에서 도트연산자(.) 앞에 있는 것(person)은 반드시 맵이거나 빈이여야 한다. 도트 연산자 우측에 있는 것은 맵의 키이거나 빈 프로퍼티여야 한다.
${person.dog.name}을 php로 표현하자면 $person[$dog['name']] 정도로 표현할 수 있을지도 모르겠다. ^^
오른쪽에 오는 값은 일반적인 자바 명명규칙을 따라야 한다.

도트 연산자 대신에 [] 연산자를 사용할 수도 있다.
즉 ${person.name}은 ${pserson["name"]}처럼 쓸 수 있다.

도트 연산자의 왼쪽에는 맵, 빈만 올 수 있었지만, [] 연산자의 경우에는 왼쪽에 맵, 빈 외에도 배열, 리스트가 올 수 있다.
또한 [] 안에 따옴표로 감싸져 있으므로 [] 안의 내용은 맵 키, 빈 프로퍼티, 리스트나 배열의 인덱스가 될 수 있다.
다음은 []의 예제이다.

서블릿 코드

String[] favoriteMusic = {"Zero 7", "Tahiti 80", "BT", "Frou Frou"};
request.setAttribute("musicList", favoriteMusic);

JSP 코드

${musicList}
${musicList[0]}
${musicList["1"]}

${musicList}은 배열을 toString()으로 변환해서 보여주기 때문에 제대로 된 값이 출력되진 않는다. ${musicList[0]}는 "Zero 7"이 ${musicList["1"]}는 "Tahiti 80"이 나오게 된다.

php에서 $array[key] 라고 하면 key라는 상수가 있나 없나를 확인 후 없을 경우 해당 key에 맵핑 된 value를 찾아 보여준다.(따라서 한번의 확인 과정을 더 거치므로 속도가 떨어진다.)
이와 마찬가지로 EL에서도 다음과 같이 작성해도 무방하다.

서블릿 코드

java.util.Map musicMap = new java.util.HashMap();
musicMap.put("Ambient", "Zero 7");
musicMap.put("Surf", "Tahiti 80");
musicMap.put("DJ", "BT");
musicMap.put("Indie", "Frou Frou");

request.setAttribute("musicMap", musicMap);
request.setAttribute("Genre", "Ambient");

JSP 코드

${musicMap[Genre]}
${musicMap["Genre"]}

위 코드에서 따옴표가 없는 Genre는 request.setAttribute를 통해서 Ambient라는 String이 할당되어 있다. 따라서 ${musicMap[Genre]}는 ${musicMap["Ambient"]}와 같은 내용이며 결과 값은 "Zero 7"이 나오게 되는 것이다.
하지만 따옴표가 있는 "Genre"는 말 그대로 String Genre이므로 변환이 되지 않으며 musicMap에서 해당 키가 있나 찾게 되는 것이다.
musicMap에는 Genre라는 키가 없으므로 결과 값이 null이 나오게 된다.

위와 같은 형식으로 아래와 같은 표현도 가능하다.

서블릿 코드

java.util.Map musicMap = new java.util.HashMap();
musicMap.put("Ambient", "Zero 7");
musicMap.put("Surf", "Tahiti 80");
musicMap.put("DJ", "BT");
musicMap.put("Indie", "Frou Frou");

String[] musicType = {"Ambient", "Surf", "DJ", "Indie"};
request.setAttribute("MusicType", musicType);

JSP 코드

${musicMap[MusicType[0]]}    //${musicMap["Ambient"]}와 같은 뜻.

MusicType[0]의 값이 "Ambient"이기 때문에 ${musicMap["Ambient"]}와 같은 뜻이다.
주의 할 점은 도트연산자의 우측에 오는 내용은 자바 명명규칙을 따르기 때문에 ${musicList["1"]}은 가능해도 ${musicList.1}과 같이 사용할 수는 없다.

* EL 내장객체

EL에서 사용하는 내장객체가 있다. EL에서 사용하는 내장 객체는 pageContext만 제외하고는 모드 맵이다. EL에서 사용하는 내장 객체는 다음과 같다.

pageScope, requestScope, sessionScope, applicationScope, param, paramValues, header, headerValues, cookie, initParam, pageContext

요청 파라미터와 같은 경우에는 다음과 같이 사용할 수 있다.

<form action="TestBean.jsp">
    <input type="text" name="name">
    <input type="text" name="empID">
   
    <input type="checkbox" name="food">
    <input type="checkbox" name="food">
</form>

${param.name}
${param.empID}
${param.food}
${paramValues.food[0]}
${paramValues.food[1]}
${paramValues.name[0]}

이름이 같은 경우에 paramValues를 사용할 수 있으며 이름이 한개인 경우에 paramValues를 사용하게 되면 0번째 인덱스가 그 값이 된다.

request parameter를 param 또는 paramValues를 이용해서 사용할 수 있는데 그보다 더 많은 내용은 어떻게 알 수 있을까?
기타 정보는 다음과 같은 방법으로 알 수 있다.

host 정보

${header["host"]}
${header.host}

http 요청 메소드

${pageContext.request.method}

스크립팅에서는 <%= request.getMethod() %>와 같이 사용하였지만, EL에서 ${request.method} 또는 ${requestScope.method}라고 하면 오류가 난다.
request란 내장객체가 EL에는 존재하지 않고, 또한 requestScope는 단순 request 생존 범위에 묶여 있는 속성에 대한 단순 맵이기 때문이다.

* 생존 범위

생존범위를 사용하는 이유는 이름 충돌을 피하기 위해서이다. 또한 한가지 이유로 생존범위를 쓰는데 다음과 같은 경우를 위해서이다.

서블릿

request.setAttribute("foo.person", p);

JSP

${foo.person.name}    //틀린 표현
${requestScope["foo.person"].name}    //맞는 표현

${foo.person.name}와 같이 표현하게 되면 foo란 속성 밑에 person이란 프로퍼티가 있다는 식으로 컨테이너가 생각할 우려가 있다.("foo.person"이란 String임에도 불구하고)
따라서 ${requestScope["foo.person"].name}와 같은 식으로 표현하게 되면 문자열에 도트가 들어가 있어도 문제 없이 사용할 수 있다.

* 쿠키

쿠키를 스크립팅을 사용해서 보여주기 위해서는 매우 복잡(?)한 코드가 필요하다.

스크립팅

<%
Cookie[] cookies = request.getCookies();

for(int i=0 ; i<cookies.length ; i++) {
    if((cookies[i].getName().equals("userName"))) {
        out.println(cookies[i].getValue());
    }
}
%>

EL

${cookie.userName.value}

* 컨텍스트 초기화 파라미터

web.xml

  <context-param>
      <param-name>breed</param-name>
      <param-value>Great Dane</param-value>
  </context-param>

스크립팅

<%= application.getInitParameter("breed") %>

EL

${initParam.breed}

context-param이지만 EL에서는 contextParam이라고 하지 않고 initParam이라고 한다.



신고

'Java > Servlet & JSP' 카테고리의 다른 글

템플릿 형태로 JSP 사용하기  (0) 2009.02.16
EL 함수 사용하기  (0) 2009.02.13
EL 사용하기  (3) 2009.02.12
표준 액션을 사용한 JSP  (0) 2009.02.11
JSP 초기화 하기  (0) 2009.02.10
스크립틀릿에서 변수 선언하기  (0) 2009.02.04

WRITTEN BY
체리필터
프로그램 그리고 인생...

받은 트랙백이 없고 , 댓글  3개가 달렸습니다.
  1. 정말 잘 정리하셨네요. ^^
    잘 보고 갑니다~!
  2. 비밀댓글입니다
secret