14.1 표현 언어란?
508p
jsp의 발전 과정
초기-html 태그를 중심으로 자바를 이용해 화면을 구현했음 -> 요구사항이 복잡해지며 자바코드를 대체하는 액션태그가 등장함 ->jsp 2.0에서는 스크립트 요소보다 표현언어와 JSTL을 사용해서 구현함
표현언어(EL, Expression Language)는 자바코드가 들어가는 표현식을 좀더 편리하게 사용하기 위해 jsp 2.0부터 도입된 데이터 출력 기능임. 표현식의 자바코드가 복잡해짐에 따라 자바코드로 출력하는 표현식을 대체하기 위해 표현언어가 등장했음.
*** JSP 페이지에서 표현언어를 사용하려면 페이지 디렉티브 태그의 isELIgnored 속성을 "false"로 설정해야함
- 표현언어의 특징
기존 표현식보다 편리하게 값을 출력함
변수와 여러가지 연산자를 포함할 수 있음
jsp의 내장객체에 저장된 속성 및 자바 빈 속성도 표현언어에서 출력할 수 있음
표현언어 자체 내장객체도 제공됨
jsp 페이지 생성 시 기본 설정은 표현언어를 사용할 수 없음
페이지 디렉티브 태그에서 반드시 isELIgnored=false로 설정해야함
표현언어의 형식
${ 표현식 or 값 }
표현 언어에서 사용되는 자료형과 연산자
▼표현언어에서 사용되는 자료형
자료형 | 설명 |
불(boolean) | true와 false 값을 가짐 |
정수 | 0~9로 이루어진 값을 갖고, 음수인 경우 마이너스(-)가 붙음 |
실수 | 소수점(.)을 사용할 수 있고, 1.4e5 등 지수형으로 표현할 수도 있음 |
문자열 | 따옴표를 함께 사용함 |
널(null) | null을 가짐 |
▼표현언어의 여러가지 연산자
연산자 종류 | 연산자 | 설명 |
산술 연산자 | + | 덧셈 |
- | 뺄셈 | |
* | 곱셈 | |
/ 또는 div | 나눗셈 | |
% 또는 mod | 나머지 | |
비교 연산자 | == 또는 eq (equal) | 두 값이 같은지 비교 |
!= 또는 ne (not equal) | 두 값이 다른지 비교 | |
< 또는 lt ( little) | 값이 다른 값보다 작은지 비교 | |
> 또는 gt (greater) | 값이 다른 값보다 큰지 비교 | |
<= 또는 le (little or equal) | 값이 다른 값보다 작거나 같은지 비교 | |
>= 또는 ge (greater or equal) | 값이 다른 값보다 크거나 같은지 비교 | |
논리 연산자 | && 또는 and | 논리곱 연산을 함 |
|| 또는 or | 논리합 연산을 함 | |
! 또는 not | 부정 연산을 함 | |
empty 연산자 | empty <값> | <값>이 null이거나 빈 문자열이면 true를 반환함 |
조건 연산자 | <수식> ? <값1> : <값2> | <수식>의 결과값이 true이면 <값1>을 반환하고, false이면 <값2>를 반환 |
jsp에서 표현언어 사용 실습
[ elTest1.jsp ]
<%@ page ...... isELIgnored="false" %> // 표현언어 기능을 활성화함
...
<body>
${100} // 100
${"안녕하세요"} // 문자열 -> 따옴표 떼고 내용만 출력됨
${10+1} // 숫자의 합인 11
${"10"+1} // 문자열을 숫자로 바꿔서 합을 구함. 11 출력.
${null+10} // null은 0으로 변환되어 더함
${"안녕"+1} // 숫자로 바꿀 수 없는 문자열은 숫자와 더하지 못함.
${"hello"+"world"} // 문자열과 문자열은 더하지 못함
*** 자바에서와 달리 문자열에 + 연산시 문자열을 이어붙이지 않음. 숫자->문자로 바꾸지 않고 문자->숫자로 바꿔서 숫자의 합을 계산함
표현 언어의 산술 연산자
[ elTest2.jsp ]
나눗셈 시 / 기호 대신 div, 나머지 연산 시 % 기호 대신 mod를 사용할 수 있음
${100/9} = ${100 div 9}
${100%9} = ${100 mod 9}
표현언어의 비교 연산자
[ elTest3.jsp ]
비교연산자의 연산 결과는 true 또는 false임
문자열이 서로 같은지 비교할 때는 ==나 eq를 사용함
서로 다른지 비교할 때는 !=나 ne를 사용 ...
기타 위의 표에서 정리한 내용과 동일함
표현언어의 논리 연산자
&& / and 연산자는 논리곱 연산을 함 : 연산자 양쪽 둘다 true일 때만 true를 반환함
|| / or 연산자는 논리합 연산을 함 : 연산자 양쪽 중 하나라도 true이면 true를 반환함
! / not 연산자는 반대의 결과를 출력함 : 연산대상(피연산자)이 true이면 false, false이면 true를 반환함
표현언어의 empty 연산자
empty 연산자는 자바빈의 속성이 값으로 설정됐는지 or List, Map 등 저장객체에 값(객체)이 존재하는지 판단하는 연산자.
[ elTest5.jsp ]
m1 : setProperty 액션태그로 property와 value로 값을 설정한 자바 빈
m2 : ArrayList 객체를 빈으로 생성, 값을 저장하지 않아 빈 List
${empty m1} // 값이 설정되어 있으므로 false
${not empty m1} // false에 not이 붙으면 true
${empty m2} // 값이 저장되지 않았으므로 true
${not empty m2} // true에 not이 붙으면 false
...
=>
empty 연산자가 true를 반환하는 경우
: 빈 List 등 값이 저장되지 않은 자바 빈, 빈 문자열(" "), null 등
empty 연산자가 false를 반환하는 경우
: 값이 저장된 자바 빈, 내용이 있는 문자열 등
14.2 표현 언어 내장객체(내장변수)
518p
JSP에서 제공하는 기본 내장객체들과 별도로 표현언어에서 제공하는 내장객체들이 있음. 표현언어에서 제공하는 내장객체들은 ${ } 안에서만 사용할 수 있음
표현 언어에서 제공하는 내장 객체의 종류와 기능
구분 | 내장 객체 | 설명 |
스코프 | pageScope | jsp의 page와 같은 기능을 함, page 영역에 바인딩된 객체를 참조함 |
requestScope | jsp의 request와 같은 기능을 함, request 영역에 바인딩된 객체를 참조함 | |
sessionScope | jsp의 session와 같은 기능을 함, session 영역에 바인딩된 객체를 참조함 | |
applicationScope | jsp의 application와 같은 기능을 함, application 영역에 바인딩된 객체를 참조함 | |
요청 매개변수 | param | request.getParameter() 를 호출한 것과 같음 한 개의 값을 전달하는 요청 매개변수를 처리함 |
paramValues | request.getParameterValues() 를 호출한 것과 같음 여러 개의 값을 전달하는 요청 매개변수를 처리함 |
|
헤더 값 | header | request.getHeader() 를 호출한 것과 같음 요청 헤더 이름의 정보를 단일 값으로 반환함 |
headerValues | request.getHeaderValues() 를 호출한 것과 같음 요청 헤더 이름의 정보를 배열로 반환함 |
|
쿠키 값 | Cookies | 쿠키 이름의 값을 반환함 |
JSP 내용 | pageContext | pageContext 객체를 참조할 때 사용함 |
초기 매개변수 | initParam | 컨텍스트의 초기화 매개변수 이름의 값을 반환함 |
param 내장객체 사용 실습
519p
회원가입 창에서 회원정보를 입력하고 jsp로 전송하면 getParameter()가 아닌 param 내장객체를 이용해 전송된 회원정보를 출력해보자.
회원가입창 - id, pwd, name, email을 입력 후 전송함
[ member1.jsp ]
// getParameter()로 회원정보 가져와서 표현식으로 출력
String id = request.getParameter("id");
...
<td><%=id %></td>
...
// getPrameter()와 표현식을 이용하지 않고, param 객체를 이용해 바로 회원정보 출력
...
<td>${param.id } </td>
...
=>
~~ = request.getParameter("~~"); <%= ~~ %>
를 ${ param.~~ } 로 바로 쓸 수 있음
전송된 매개변수를 getParameter() 메서드 사용 없이도 param 객체를 사용하여 매개변수 이름으로 접근해서 값 얻을 수 있음
requestScope 사용 실습
522p
requestScope 객체는 request 객체와 동일한 기능을 함.
회원가입창인 memberForm.jsp의 action 속성을 forward.jsp로 수정함
회원가입창은 id, pwd, name, email을 입력받아 전송함
[ forward.jsp ]
회원 가입창의 request 객체에 setAttribute() 메서드를 이용해 address를 바인딩한 후 member2.jsp로 포워딩함
<%
request.setCharacterEncoding("utf-8");
request.setAttribute("address", "서울시 강남구"); // 회원가입창의 request에 대해 주소정보를 바인딩함
%>
...
<body>
<jsp:forward page="member2.jsp"></jsp:forward> // member2.jsp로 포워딩
</body>
[ member2.jsp ]
requestScope를 이용해 바인딩된 address에 접근해서 주소를 출력함
<table> 태그를 이용해 회원정보를 출력할 테이블을 만듦,
${ param.id } 등 param 내장객체를 이용해 id, pwd, name, email를 가져와 출력함,
${ requestScope.address } 로 request에 바인딩된 주소정보를 출력함
=>
requestScope를 이용하면 request 객체에 바인딩된 데이터에 접근할 수 있듯
마찬가지로 sesison이나 application 객체에 바인딩된 데이터는 sessionScope, applicationScope로 접근할 수 있음
pageContext 객체 사용 실습
525p
pageContext 객체는 javax.servlet.jsp.PageContext 클래스를 상속해 웹 컨테이너가 jsp 실행시 자동으로 생성해서 제공하는 내장객체임
<a> 태그를 이용해 다른 서블릿이나 jsp로 요청하는 방법
1. 컨텍스트 이름(pro14)을 직접 입력함
<a href="/pro14/test01/memberForm.jsp">회원가입하기</a>
2. getContextPath() 메서드로 컨텍스트 이름을 가져오는 방법
<a href="<%= request.getContextPath() %>/test01/memberForm.jsp">회원가입하기</a>
1 -> 컨텍스트 이름이 바뀌면 일일이 찾아서 수정해줘야함
2 -> 자바코드가 사용되어 화면작업이 복잡해짐
=> pageContext 객체의 request 속성의 contextPath 속성을 이용해 컨텍스트의 이름을 쉽게 가져올 수 있음
<a href="${ pageContext.request.contextPath}/test01/memberForm.jsp"
빈 사용 실습
526p
표현언어에서 빈 속성에 접근하는 방법에 대해 알아보자
표현언어에서는 getter를 사용하지 않고, 빈id 뒤에 마침표(.) 연산자를 사용하여 속성에 바로 접근할 수 있음
형식
${ 빈이름.속성이름 }
회원가입창에서 전달된 회원정보를 빈에 저장한 후 표현언어를 이용해 빈의 회원정보를 출력해보자
[ member3.jsp ]
<jsp:useBean id="m" class="sec01/ex01/MemberBean" /> // 회원정보를 저장할 빈을 생성함
<jsp:setProperty name="m" property="*" /> //전송된 회원정보를 빈의 속성에 설정함
...
표현식과 getter를 이용해서 <td><%= m.getId() %></td>로 정보를 출력할수 있지만
표현언어에서는 빈이름과 속성이름으로 접근하여 <td>${ m.id }</td> 로 출력할 수 있다
Collection 객체 사용 실습
형식
${ Collection객체이름[index].속성이름 }
* index : Collection에 저장된 순서
Collection 객체 중 가장 많이 사용되는 ArrayList에 회원정보 빈을 저장한 후 다시 출력해보자
memberForm.jsp의 action 값을 member4.jsp로 수정,
[ member4.jsp ]
회원가입창에서 전송된 회원정보를 생성한 빈 m1에 저장(<jsp:setProperty>),
useBean으로 ArrayList인 빈 membersList 생성,
자바 코드로 두번째 MemberBean 객체를 생성(인자4개(id,pwd,name,email)를 갖는 생성자 이용),
두 MemberBean을 membersList에 저장함(membersList.add())
<jsp:useBean id="m1" class="sec01/ex01/MemberBean" /> // useBean으로 MemberBean 객체 생성
<jsp:setProperty name="m1" property="*" /> // 회원가입창에서 넘어온 회원정보 m1 객체에 저장
<jsp:useBean id="membersList" class="java.util.ArrayList" /> // useBean으로 ArrayList 객체를 생성
<%
MemberBean m2 = new MemberBean("son", "1234", "손흥민", "son@test.com"); // 새 MemberBean 객체 생성
membersList.add(m1);
membersList.add(m2); // 두 MemberBean 객체를 ArrayList에 저장
%>
...
<body>
...
<td>${membersList[0].id}</td>
<td>${membersList[0].pwd}</td>
<td>${membersList[0].name}</td>
<td>${membersList[0].email}</td> // 인덱스가 0인 첫번째 회원정보(m1)를 출력함
<td>${membersList[1].id}</td>
... // 마찬가지로 인덱스가 1인 두번째 회원정보(m2)를 출력함
HashMap 사용 실습
*** HashMap
맵(map) : 키key와 값value 쌍으로 데이터를 보관하는 자료구조. 키는 맵에 오직 유일해야함
해싱 : 통상적인 반복 비교가 아닌 특정 계산만으로 자료의 저장주소를 찾아내는 탐색방법
많은 양의 데이터 검색에 적합함, Map인터페이스를 상속하므로 Map의 성질을 그대로 가짐.
HashMap에서 키와 값은 모두 객체이며, HashMap 내부에 키 테이블과 값 테이블을 가짐, 해시함수를 통해 키와 값이 저장되는 위치를 결정하므로 삽입되는 순서와 위치 간에 관계없음 (삽입한 순서에 따라 정렬되지 않음)
531p
표현언어에서 자바 HashMap에 저장된 객체에 접근하는 방법
${ HashMap객체이름.name }
HashMap에 객체를 저장한 후 다시 출력해보자
memberForm.jsp의 action값을 member5.jsp로 수정,
[ member5.jsp ]
전송된 회원정보를 m1에 저장,
useBean으로 ArrayList와 HashMap을 생성,
HashMap에 한 회원의 id, pwd, name, email 저장,
자바코드로 인자4개 갖는 생성자 이용해 m2 생성,
ArrayList에 m1, m2 추가,
HashMap에 ArrayList 추가
<jsp:useBean id="m1" class="sec01.ex01.MemberBean" />
<jsp:setProperty name="m1" property="*" /> // 생성한 MemberBean m1에 회원가입창에서 넘어온 회원정보 저장
<jsp:useBean id="membersList" class="java.util.ArrayList" /> // 회원정보 저장할 arraylist 생성
<jsp:useBean id="membersMap" class="java.util.HashMap" /> // 회원정보 저장할 hashmap 생성
<%
membersMap.put("id", "park2"); // hashmap에 데이터 추가: put()
... // '박지성' 회원의 회원정보를 id, pwd, name, email 각각 키-값으로 hashmap에 저장
MemberBean m2 = new MemberBean( '손흥민' 회원 정보 )
membersList.add(m1); // arraylist에 데이터 추가 : add()
membersList.add(m2); // 가입한 회원정보, 손흥민 정보를 arraylist에 추가
membersMap.put("membersList", membersList); // 가입한회원, 손흥민 정보가 든 리스트 전체를 hashmap에 추가
%>
...
▼ membersMap에 저장된 데이터들
키 | 값 |
id | park2 |
pwd | 4321 |
name | 박지성 |
park2@test.com | |
membersList | membersList |
▼ membersList에 저장된 데이터들
인덱스 | 저장된 값 |
membersList[0] | m1 (가입한 회원 정보) |
membersList[1] | m2 ('손흥민' 회원 정보) |
<td>${membersMap.id}</td>
... // membersMap에는 4개의 키-값 쌍을 이용해 '박지성' 회원 정보를 저장하고 있음, 이를 출력
<td>${membersMap.membersList[0].id}</td>
... // membersMap에 저장된 arrayList에 인덱스로 arrayList 요소에 접근함, 인덱스[0]에 해당하는 m1의 정보 출력
<td>${membersMap.membersList[0].id}</td>
... // 마찬가지로 arrayList 요소에 접근해 m2의 정보 출력함
has-a 관계 빈 사용 실습
533p
객체가 다른 객체를 속성으로 가지는 경우를 has-a 관계라고 함
빈의 자식 빈의 속성에 접근하는 방법
${ 부모빈이름.자식빈이름.속성이름 }
[ memberBean 클래스 ]
회원 주소를 저장하는 'Address' 클래스 타입으로 선언된 addr을 속성으로 가짐
Address가 자식빈이 됨 (has-a 관계)
public class MemberBean {
...
private Address addr; // 속성으로 Address 클래스 타입을 가짐
}
[ Address 클래스 ]
public class Address {
private String city;
private String zipcode; // 회원의 거주 도시와 우편번호를 저장함
...// 생성자, 속성에 대한 getter/setter 등 작성
}
[ member6.jsp ]
회원가입 jsp의 action 값을 member6.jsp로 수정,
userBean으로 MemberBean 생성(m), setProperty로 전달받은 회원정보 저장,
<jsp:useBean id="addr" class="sec01.ex02.Address" /> // Address 빈 생성
<jsp:setProperty name="addr" property="city" value="서울" />
<jsp:setProperty name="addr" property="zipcode" value="07654" /> // Address 빈에 속성 값 저장
<%
m.setAddr(addr); MemberBean의 addr 속성에 setter를 이용해 Address빈(addr)을 설정함
%>
// 도시와 우편번호(자식빈의 속성)를 출력시
// 1. 속성들의 getter를 두번 호출하여 주소 출력 (불편함)
<td><%= m.getAddr().getCity() %></td>
// 2. 자식빈이름.자식빈속성이름 으로 주소 출력
<td>${ m.addr.city }</td>
14.3 표현 언어로 바인딩 속성 출력하기
536p
request, session, application 내장 객체에 속성 바인딩하여 다른 서블릿이나 jsp에 전달했음
표현언어를 사용하면 자바코드 없이 바인딩 된 속성이름으로 바로 값 출력할 수 있음
내장 객체 속성 값 출력 실습
1. request, session,application 내장객체에 바인딩 된 속성 값을 표현언어로 jsp에서 출력
[ forward1.jsp ]
첫번째 jsp,
브라우저에서 요청시 reqeust, session, application 내장객체에 회원정보를 바인딩 후 다시 member1.jsp로 포워딩함
<%
request.setAttribute("id","hong");
request.setAttribute("pwd","1234"); // request 내장객체에 바인딩함
session.setAttribute("name","홍길동"); // session 내장객체에 바인딩
application.setAttribute("email","hong@test.com"); // application 내장객체에 바인딩
%>
...
<body>
<jsp:forward page="member1.jsp" /> // member1.jsp로 포워딩함
</body>
[ member1.jsp ]
1) getAttribute() 메서드에 속성이름을 인자로 해 값 가져옴
2) 자바코드를 사용하지 않고 표현언어에서 바로 속성이름 사용해 회원정보 가져와 출력
<%
String id = (String)request.getAttribute("id")
... // 각 내장객체에 바인딩된 속성값들을 getAttribute() 메서드로 가져옴
%>
...
<td><%= id %></td>
... // 1) getAttribute()로 가져온 정보 표현식으로 회원정보 출력
<td>${ id }</td>
... // 2) 별도의 코드 없이 표현언어만으로 바인딩된 속성이름을 써주어 바인딩된 정보 출력
=> forward1.jsp 요청시 getAttribute()로 출력되는 회원정보, 표현언어에서 속성이름으로 바로 출력되는 회원정보 둘 모두를 확인할 수 있음
2. request에 MemberBean 객체를 바인딩 후 출력
[ forward2.jsp ]
MemberBean 객체 생성(인자있는 생성자 이용),
request 내장객체에 속성이름 member로 MemberBean 객체 바인딩 후 member1.jsp로 포워딩
<%
... // 인코딩
MemberBean member = new MemberBean("lee","1234","이순신","lee@test.com"); // MemberBean 객체 생성, 속성 설정.
request.setAttribute("member", member); // 속성이름 "member"로 MemberBean객체 member를 바인딩함
%>
...
<jsp:forward page="member2.jsp" />
[ member2.jsp ]
request 내장객체에 속성이름 member로 접근하여 MemberBean 속성값을 출력함
<td>${ member.id }</td>
... // 바인딩 시 속성 이름으로 각각의 MemberBean 속성에 접근하여 회원정보를 출력함
3. 회원정보를 저장한 ArrayList를 request에 바인딩 후 출력
[ forward3.jsp ]
ArrayList 객체 생성 후 MemberBean 객체를 저장, request 내장객체에 ArrayList 바인딩함,
member3.jsp로 포워딩
<%
...//인코딩
List memberList = new ArrayList(); // MemberBean 객체 저장할 ArrayList 생성
MemberBean m1 = new MemberBean("lee", "1234", "이순신", "lee@test.com");
MemberBean m2 = new MemberBean("son", "1234", "손흥민", "son@test.com"); //MemberBean 객체 2개 생성
memberList.add(m1);
memberList.add(m2); // ArrayList에 추가
request.setAttribute("memberList", memberList); // request 내장객체에 ArrayList 바인딩
%>
....
<jsp:forward page="member3.jsp" />
...
[ member3.jsp ]
바인딩할때 사용했던 속성이름("memberList")을 표현언어에서 사용해 ArrayList에 접근한 후 인덱스로 저장된 MemberBean에 접근하여 속성이름("id" 등)으로 회원정보 출력
...
<td>${ memberList[0].id }</td>
... // request에 바인딩할때 사용한 속성이름 "memberList"을 그대로 사용하여 접근, 인덱스로 요소 가져와 출력할 속성명(id) 붙임
...
스코프 우선 순위
542p
request, session, application 내장객체 각각에 데이터를 바인딩해서 다른 jsp로 전달할 수 있음
이때 각 내장객체에 바인딩하는 속성이름이 같은 경우, 우선순위에 따라 순서대로 속성에 저근함
[ forward4.jsp ]
request에 "address"(값: 서울시 강남구)를 바인딩 후 member4.jsp로 포워딩
[ member4.jsp ]
session에 똑같이 "address"(값 : 수원시 팔달구)를 바인딩함,
${ address } 로 출력시, request가 session보다 우선순위가 높으므로 request에 바인딩된 값인 "서울시 강남구"가 출력됨
=>
표현언어에서는 동일한 속성이름이 존재할 경우, 같은 이름의 속성에 대한 우선순위는 다음과 같음
page > request > session > application
'(책) 자바 웹을 다루는 기술' 카테고리의 다른 글
Chap 14 표현 언어와 JSTL -3 (0) | 2023.08.30 |
---|---|
Chap 14 표현 언어와 JSTL -2 (0) | 2023.08.29 |
Chap 13 자바 코드를 없애는 액션 태그 (0) | 2023.08.26 |
Chap 12 JSP 스크립트 요소 기능 (0) | 2023.08.25 |
Chap 11 JSP 정의와 구성 요소 (0) | 2023.08.23 |