[JSP&Servlet] 스크립틀릿의 새로운 대체제, EL 표기법

Re_Go·2024년 8월 6일
0

JSP&Servlet

목록 보기
14/19
post-thumbnail

1. 기존 스크립틀릿과의 작성 차이점

EL(Expression Language)는 JSP에서 사용하는 새로운 스크립트 언어로서 기존의 복잡했던 자바 코드 표현 체계인 스크립틀릿을 대체하기 위해 만들어졌는데요. 이러한 EL은 쉽게 사용자의 입력 데이터를 가져오고, 연산하여 출력하는 역할을 스크립틀릿보다 더 쉽게 할 수 있는데요.

왜 그런지를 이 둘의 차이점을 알아봅시다. 다음과 같은 코드가 있다고 칩시다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
 <%
 int total = 0;
 for(int i = 1 ; i <= 100 ; i++){
	 total += i;
 }
 pageContext.setAttribute("TOTAL", total);
 %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

</body>
</html>

위 코드에는 1부터 100까지를 더해서 body에 출력하려는 코드인데요. 기존의 스크립틀릿 언어로 작성한다면 어떻게 해야할까요?

<p><%=total%></p>
<p><%=pageContext.getAttribute("TOTAL")%></p>

그리고 그럼 위의 코드를 대신해 EL 표기법으로 코드를 작성해 보면 다음과 같이 작성할 수 있답니다.

<p>${TOTAL}</p>

흠... 이렇게 봐서는 차이점을 느끼지 못하시겠다고요? 좋습니다. 그럼 다음 코드를 한 번 살펴보도록 하죠.

2. 코드의 간결화

다음과 같이 사용자의 주문을 받는 특정 화면이 있다고 생각해 봅시다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<form action="showOrder.jsp">
		<h1>배다른 민족</h1>
		<h3> 주문자 <input type = "text" name = "id"> </h3>
		<input type = "checkbox" name = "order" value="하와이안피자">하와이안피자
		<input type = "checkbox" name = "order" value="불고기피자">불고기피자
		<input type = "checkbox" name = "order" value="허니콤보치즈피자">허니콤보치즈피자
		<input type = "checkbox" name = "order" value="이태리안핫소스피자">이태리안핫소스피자
		<input type = "checkbox" name = "order" value="쉬림프바질피자">쉬림프바질피자
	 <p><button>주문하기</button></p>
	</form>
</body>
</html>

그럼 개발자는 사용자의 주문(요청)을 받아서 처리를 해줘야겠죠?

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

<% 
    String name = request.getParameter("name");
    String[] orders = request.getParameterValues("order");

    pageContext.setAttribute("orders", orders);
%>    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    주문자 : <%= name %> <br>
    주문하신 음식 : <%= String.join(" ", (String[]) pageContext.getAttribute("orders")) %> 
</body>
</html>

음... 꽤 복잡해 보이죠? 그래서 이 코드를 EL 표기법으로 한 번 바꿔보면 다음과 같이 작성할 수 있답니다!

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<% 
    String name = request.getParameter("name");
    String[] orders = request.getParameterValues("order");

    request.setAttribute("name", name);
    request.setAttribute("orders", orders);
%>    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    주문자 : ${name} <br>
    주문하신 음식 : 
    <c:forEach var="order" items="${orders}">
        ${order} 
    </c:forEach>
</body>
</html>

3. EL 작성의 조건

이처럼 기존의 스크립틀릿을 대체하여 코드를 보다 간결하게 작성할 수 있도록 해주는 EL 표기법에는 그 조건이 따르는데요. 그 조건은 바로 정보 저장 객체들(pageContext, request, session, application) 중에 하나의 속성으로서 저장되어야 사용이 가능하다는 것입니다. 바로 위의 코드를 살펴보면

request.setAttribute("name1", value1);
request.setAttribute("name2", value2);

이렇게 되어있는 코드가 보이시죠? 이것이 바로 request 객체에 속성들로 name라는 속성과 그 값(name)을, orders라는 속성과 그 값(orders)을 넣어준게 바로 이 코드였던거죠.

참고로 정보 저장 객체의 저장 및 유효 범위는 해당 링크를 참조해 주시기 바랍니다!

아무튼 이렇게 속성으로서 그 값이 저장이 되어 있어야 사용이 가능한 EL이지만, 물론 사용자가 전달한 파라미터 값, 즉 전달한 값이 있다면 EL로 표기가 가능한데요. 바로 직전에 주문 페이지에서 사용자가 요청한 정보가 request, 즉 파라미터 값으로 들어온다는 특성을 이용해 param과 paramvalues 객체를 다음과 같이 이용하면 되죠!

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

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    주문자 : ${param.name}<br>
    주문하신 음식 : ${paramValues.order[0]} ${paramValues.order[1]} ${paramValues.order[2]} 
</body>
</html>

물론 앞전에서 출력 홈페이지에 pageContext로 속성을 설정해 준거라 해당 페이지에서 스크립틀릿을 쓰긴 했지만, 이전 페이지에서 request나 session로 속성을 설정해 줬다면 위의 코드와 같이 굳이 스크립틀릿 태그로 속성을 설정해줄 이유도 없겠지요.

이처럼 EL로 변수들에 접근할 때에는 파라미터의 경우 param(단수)와 paramValues(복수), 혹은 속성으로 설정한 경우 그냥 속성명을 적어주면 되는데요. 물론 속성의 경우 각 정보 저장 객체가 동일한 속성의 이름으로 저장을 했다면 그건 또 문제가 될 수 있겠죠? 그래서 다음 예제를 한 번 살펴보도록 하겠습니다.

4. 속성 중복 이름의 방지, Scope

스코프는 말 그대로 어떠한 정보 저장 객체에 해당 속성이 있는지를 구별할 때 사용하는 객체로, 정보 저장 객체인 pageContext, request, session, application에게 각각 부여되어 있으며, 사용법은 접미사로 Scope 라는 단어를 작성하면 됩니다.

좀 더 쉬운 이해를 위해 다음 예시 코드를 한 번 살펴볼까요?

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

<% 
    // 요청 파라미터에서 값 가져오기
    String name = request.getParameter("name");
    String order = request.getParameter("order");

    // 세션과 요청에 속성 설정
    session.setAttribute("name", name);
    session.setAttribute("orders", order);
  
    request.setAttribute("name", "진상 손님");
    request.setAttribute("orders", "경찰을 불러서 퇴치를 했다!");
%>    

위 코드에서는 request와 session의 속성으로 각각 같은 이름에 다른 값을 부여했는데요. 그래서 일반적인 접근 방법(그냥 속성의 이름을 쓰는 것)으로 접근한다면 다음과 같이 출력될 것입니다.

주문자 : ${name} <br>
주문하신 음식 : ${orders}

분명 주문자 명으로 하와이안피자를 불렀는데 나타난 정보는 다음과 같이 전혀 딴판인 정보가 나왔죠? 그 이유는 그냥 속성명만 지정할 경우 페이지에서부터 가장 가까운 정보 저장 객체의 속성을 접근하기 때문에 나타난 현상인데요. 이 페이지의 경우 pageContext는 설정되어 있지 않기 때문에 request에 설정된 각 속성들이 출력이 된 것이죠.

그래서 이런 상황을 대비하기 위해 스코프를 사용하면 다음과 같이 정상적으로 코드가 출력되는 모습을 확인하실 수 있으실 겁니다.

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <!-- 세션 스코프의 속성 접근 -->
    <h2>Session Scope</h2>
    주문자 : ${sessionScope.name} <br>
    주문하신 음식 : ${sessionScope.orders}
</body>
</html>

profile
인생은 본인의 삶을 곱씹어보는 R과 타인의 삶을 배워 나아가는 L의 연속이다.

0개의 댓글