본문 바로가기
JSP/성낙현의 JSP 자바 웹 프로그래밍

표현 언어(EL: Expression Language)

by k-mozzi 2023. 6. 19.
반응형
Preface

 

이번 장에선 표현 언어에 대해 공부했다.

 

딱히 어려운 부분은 없었는데, 아직까진 내장 객체를 이용하던 이전 방식과의 차이점 및 EL만의 장점을 잘 모르겠다.

 

뒷장을 공부하며 점차 EL의 효용성을 느낄 수 있다고 하니 기본적인 문법을 잘 이해하고 넘아가자.


 

1. 표현 언어란?

 

 

- 표현 언어(Expression Language): 변수의 값을 출력할 때 사용하는 스크립트 언어

1) 4가지 영역에 저장된 값을 출력할 때 사용한다.

2) 사용법이 매우 간결하다.

3) 예외와 형변환에 관대하다.

 

 

- 표현 언어의 기능

1) JSP 내장 객체의 영역에 담긴 속성을 사용할 수 있다.

2) 산술, 비교, 논리 연산이 가능하다.

3) 자바 클래스에 정의된 메서드를 호출할 수 있다.

4) 표현 언어만의 객체를 통해 JSP와 동일한 기능을 수행할 수 있다.

 

 

- EL의 기본 사용법

1) 속성: 영역에 저장된 속성

→ 변수나 값을 바로 쓸 수 있던 표현식과는 달리 반드시 영역에 저장한 후 사용해야 한다.

2) HTML 태그, JS, CSS에 사용할 수 있고, 액션 태그나 JSTL의 속성값으로도 사용할 수 있다.

3) JSP 스크립트 요소에서는 사용할 수 없다.

4) 객체를 표현할 때는 점(.)이나 대괄호([ ])를 사용한다.

→ 속성명에 특수 기호나 한글이 포함된 경우엔 대괄호만 사용할 수 있으며, 대괄호를 사용할 땐 큰따옴표나 작은따옴표를 모두 사용할 수 있다.

${ 속성 }

 


 

2. EL의 내장 객체

 

 

- EL에서 4가지 영역에 접근하기 위한 내장 객체

→ 영역을 따로 지정하지 않으면 가장 좁은 영역에서부터 속성을 찾는다.

1) pageScope: pageContext 내장 객체와 같이 page 영역에 저장된 속성값을 읽어온다.

2) requestScope: request 내장 객체와 같이 request 영역에 저장된 속성값을 읽어온다.

3) sessionScope: stssion 내장 객체와 같이 session 영역에 저장된 속성값을 읽어온다.

4) applicationScope: application 내장 객체와 같이 application 영역에 저장된 속성값을 읽어온다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
pageContext.setAttribute("scopeValue", "페이지 영역");
request.setAttribute("scopeValue", "리퀘스트 영역");
session.setAttribute("scopeValue", "세션 영역");
application.setAttribute("scopeValue", "애플리케이션 영역");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h2>ImplicationObjMain 페이지</h2>
	<h3>각 영영게 저장된 속성 읽기</h3>
	<ul>
		<li>페이지 영역 : ${ pageScope.scopeValue }</li>
		<li>리퀘스트 영역 : ${ requestScope.scopeValue }</li>
		<li>세션 영역 : ${ sessionScope.scopeValue }</li>
		<li>애플리케이션 영역: ${ applicationScope.scopeValue }</li>
	</ul>
	
	<h3>영역 지정 없이 속성 읽기</h3>
	<ul>
		<li>${ scopeValue }</li>
	</ul>
	
	<jsp:forward page="ImplicitForwardResult.jsp"></jsp:forward>
</body>
</html>

 

<%@ 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>
	<h2>ImplicitForwardResult 페이지</h2>
	<h3>각 영역에 저장된 속성 읽기</h3>
	<ul>
		<li>페이지 영역 : ${ pageScope.scopeValue }</li>
		<li>리퀘스트 영역 : ${ requestScope.scopeValue }</li>
		<li>세션 영역 : ${ sessionScope.scopeValue }</li>
		<li>애플리케이션 영역: ${ applicationScope.scopeValue }</li>
	</ul>
	<h3>영역 지정 없이 속성 읽기</h3>
	<ul>
		<li>${ scopeValue }</li>
	</ul>
</body>
</html>

 

 

- EL에서 폼값을 처리하기 위한 내장 객체

null을 표현식으로 출력하면 예외가 발생하지만, EL로 출력하면 예외가 발생하지 않는다.

1) param: request.getParameter("매개변수명")과 동일하게 요청 매개변수의 값을 받아온다.

2) paramValues: request.getParameterValues("매개변수명")과 동일하게 요청 매개변수의 값을 문자열 배열로 받아온다.

<%@ 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>
	<h2>폼값 전송하기</h2>
	<form name="frm" method="post" action="FormResult.jsp">
		이름 : <input type="text" name="name" /><br>
		성별 : <input type="radio" name="gender" value="Man"/>남자
			  <input type="radio" name="gender" value="Woman"/>여자<br>
		학력 : <select name="grade">
			      <option value="ele">초딩</option>
			      <option value="mid">중딩</option>
			      <option value="high">고딩</option>
			      <option value="uni">대딩</option>
			 </select><br>
		관심 사항 : 
			<input type="checkbox" name="inter" value="pol" />정치
			<input type="checkbox" name="inter" value="eco" />경제
			<input type="checkbox" name="inter" value="ent" />연예
			<input type="checkbox" name="inter" value="spo" />운동<br>
		<input type="submit" value="전송하기" />
	</form>
</body>
</html>

 

<%@ 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>
	<h3>EL로 폼값 받기</h3>
	<ul>
		<li>이름 : ${ param.name }</li>
		<li>성별 : ${ param.gender }</li>
		<li>학력 : ${ param.grade }</li>
		<li>관심사항 : ${ paramValues.inter[0] }
				${ paramValues.inter[1] }
				${ paramValues.inter[2] }
				${ paramValues.inter[3] }</li>
	</ul>
</body>
</html>

 

 

- 폼으로는 객체 전송이 불가능하므로, 영역을 사용한다.

→ 객체를 영역에 저장한 후, 전송하고자 하는 페이지로 전달한다.

<%@ page import="common.Person"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<html>
<meta charset="UTF-8">
<head>
<title>표현 언어(EL) - 객체 매개변수</title>
</head>
<body>
	<%
	request.setAttribute("personObj", new Person("홍길동", 33));
	request.setAttribute("stringObj", "나는 문자열");
	request.setAttribute("integerObj", new Integer(99));
	%>
	<jsp:forward page="ObjectResult.jsp">
		<jsp:param value="10" name="firstNum" />
		<jsp:param value="20" name="secondNum" />
	</jsp:forward>
</body>
</html>

 

<%@ page import="common.Person"%>
<%@ 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>
	<h2>영역을 통해 전달된 객체 읽기</h2>
	<ul>
		<li>Person 객체 => 이름 : ${ personObj.name }, 나이 : ${ personObj.age }</li>
		<li>String 객체 => ${ requestScope.stringObj }</li>
		<li>Integer 객체 => ${ integerObj }</li>
	</ul>
	<h2>매개변수로 전달된 값 읽기</h2>
	<ul>
		<li>${ param.firstNum + param['secondNum'] }</li>
		<li>${ param.firstNum }+${param["secondNum"] }</li>
	</ul>
</body>
</html>

 

 

- EL에서 쿠키나 헤더값, 컨텍스트 초기화 매개변수를 읽기 위한 내장 객체

1) cookie: 쿠키를 읽을 때 사용한다.

2) header: request.getHeader(헤더명)와 동일하게 헤더값을 읽을 때 사용한다.

3) headerValues: request.getHeaders(헤더명)와 동일하게 헤더값을 배열 형태로 읽을 때 사용한다.

4) initParam: web.xml에 설정한 컨텍스트 초기화 매개변수를 읽을 때 사용한다.

5) pageContext: JSP의 pageContext 내장 객체와 동일한 역할을 한다.

<%@ page import="utils.CookieManager"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%
CookieManager.makeCookie(response, "ELCookie", "EL좋아요", 10);
/* 쿠키 값은 공백을 포함할 수 없다. */
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h3>쿠키값 읽어오기</h3>
	<li>ELCookie값 : ${ cookie.ELCookie.value }</li>

	<h3>HTTP 헤더 읽기</h3>
	<ul>
		<li>host : ${ header.host }</li>
		<li>user-agent : ${ header['user-agent'] }</li>
		<li>cookie : ${ header.cookie }</li>
	</ul>

	<h3>컨텍스트 초기화 매개변수 읽기</h3>
	<li>OracleDriver : ${ initParam.OracleDriver }</li>

	<h3>컨텍스트 루트 경로 읽기</h3>
	<li>${ pageContext.request.contextPath }</li>
</body>
</html>

 


 

3. 컬렉션 사용하기

 

 

- List와 Map 컬렉션 사용

<%@ page import="java.util.HashMap" %>
<%@ page import="java.util.Map" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="common.Person" %>
<%@ 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>
<h2>List 컬렉션</h2>
<%
List<Object> aList = new ArrayList<Object>();
aList.add("a");
aList.add(new Person("Lay", 28));
pageContext.setAttribute("Ocean", aList);
%>
<ul>
	<li>0번째 요소 : ${ Ocean[0] }</li>
	<li>1번째 요소 : ${ Ocean[1].name }, ${ Ocean[1].age }</li>	
	<li>2번째 요소 : ${ Ocean[2] }</li>	
</ul>
<h2>Map 컬렉션</h2>
<%
Map<String, String> map = new HashMap<String, String>();
map.put("한글", "훈민정음");
map.put("Eng", "English");
pageContext.setAttribute("King", map);
%>
<ul>
	<li>영문 key : ${ King["Eng"] }, ${ King['Eng'] }, ${ King.Eng }</li>
	<li>한글 key : ${ King["한글"] }, ${ King['한글'] }</li>
	<!-- 한글은 도트 연산자 사용 불가 -->
</ul>
</body>
</html>

 

 

- EL코드를 주석 처리하려면 앞에 역슬래시를 붙이면 된다.

 


 

4. EL의 연산자들

 

 

- EL에서는 자바에서 제공하는 특수 기호 형태의 연산자와 더불어 문자 형태의 연산자도 함께 사용할 수 있다.

 

 

- EL에서는 할당 연산자(=)를 사용해 변수에 값을 할당할 수 있지만, 할당과 동시에 출력되므로 할당만 하고 싶을 땐 세미콜론과 작은따옴표를 함께 사용해야 한다.

${ var = 10 }		할당과 동시에 출력
${ var = 10; '' }	할당만 되고 출력되지 않음

 

 

- 기본적인 연산자는 자바와 동일하며 문자 형태의 연산자는 굳이 정리하지 않겠다.

※ EL에서 + 연산자는 덧셈만을 위해 사용된다: 숫자 형태의 문자열이라면 자동으로 숫자로 변환되어 계산되지만, 문자가 포함되어 있다면 에러가 발생한다.

→ 즉, + 연산자를 문자열 연결에 사용할 수 없다.

 

 

- empty 연산자: 값이 없을 때 true를 반환한다.

1) null

2) 빈 문자열

3) 길이가 0인 배열

4) size가 0인 컬렉션

 

 

- EL에서는 null을 0으로 인식한다.

→ 실행에는 문제가 없지만, null과 정수를 연산하는 코드를 작성하면 이클립스에서 에러로 표시한다.

 


 

5. 메서드 호출

 

 

- EL로 호출할 메서드를 담은 클래스

package el;

public class MyELClass {

	public String getGender(String jumin) {
		String returnStr = "";
		int beginIdx = jumin.indexOf("-") + 1;
		String genderStr = jumin.substring(beginIdx, beginIdx + 1);
		int genderInt = Integer.parseInt(genderStr);
		if (genderInt == 1 || genderInt == 3) {
			returnStr = "man";
		} else if (genderInt == 2 || genderInt == 4) {
			returnStr = "woman";
		} else {
			returnStr = "jumin error";
		}
		return returnStr;
	}

	public static boolean isNumber(String value) {
		char[] chArr = value.toCharArray();
		for (int i = 0; i < chArr.length; i++) {
			if (!(chArr[i] >= '0' && chArr[i] <= '9')) {
				return false;
			}
		}
		return true;
	}

	public static String showGugudan(int limitDan) {
		StringBuffer sb = new StringBuffer();
		try {
			sb.append("<table border='1'>");
			for (int i = 2; i <= limitDan; i++) {
				sb.append("<tr>");
				for (int j = 1; j <= 9; j++) {
					sb.append("<td>" + i + "*" + j + "=" + (i * j) + "</td>");
				}
				sb.append("</tr>");
			}
			sb.append("</table>");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return sb.toString();
	}

}

 

 

- 인스턴스 메서드 호출하기

<%@ page import="el.MyELClass" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
MyELClass myClass = new MyELClass();
pageContext.setAttribute("myClass", myClass);
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h3>영역에 저장 후 메서드 호출하기 </h3>
	001225-3000000 => ${ myClass.getGender("001225-3000000") }<br>
	001225-2000000 => ${ myClass.getGender("001225-2000000") }<br>
</body>
</html>

 

 

- 정적 메서드 호출 방법

1) 클래스명을 통해 호출

2) TLD를 이용해 호출

 

 

- 클래스명을 통한 메서드 호출

<%@ page import="el.MyELClass" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
MyELClass myClass = new MyELClass();
pageContext.setAttribute("myClass", myClass);
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h3>클래스명을 통해 정적 메서드 호출하기</h3>
	${ MyELClass.showGugudan(7) }
</body>
</html>

 

 

- TLD(Tag Library Descriptor): 사용자 정의 태그나 JSTL 태그들을 설정하기 위한 XML 파일

→ 예전 방식이므로, 최근에는 사용하지 않는다.

1) 파일 확장자는 xml이 아닌 tld를 사용한다.

2) WEB-INF 폴더에 작성한다.

 

 

- EL에서 TLD를 통한 정적 메서드 호출 과정

1) 호출할 메서드를 담은 자바 클래스 작성(public으로 선언한 정적 메서드만 호출 가능)

2) TLD 파일 생성 후 클래스와 메서드를 등록

3) JSP 파일에서 taglib 지시어로 tld 파일의 경로와 해당 tld를 지칭할 접두어 설정

4) 접두어를 통해 EL에서 메서드 호출

 

728x90
반응형

댓글