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에서 메서드 호출
'JSP > 성낙현의 JSP 자바 웹 프로그래밍' 카테고리의 다른 글
파일 업로드 및 다운로드 (0) | 2023.06.23 |
---|---|
JSP 표준 태그 라이브러리(JSTL) (0) | 2023.06.21 |
JSP, Oracle을 사용한 회원제 게시판(페이징 O) (0) | 2023.06.19 |
JSP, Oracle을 사용한 회원제 게시판(페이징 X) (0) | 2023.06.16 |
액션 태그(Action Tag) (0) | 2023.06.13 |
댓글