14장. 표현 언어와 JSTL - ①표현언어
14.1 표현 언어란?
- JSP의 발전 과정 : HTML 태그를 중심으로 자바를 이용한 화면 구현 -> 액션 태그 -> (현재)표현 언어와 JSTL
- 스크립트 요소 보다 표현언어와 JSTL을 요즘 많이 사용해서 구현
<표현 언어>
- 자바 코드가 들어가는 표현식을 좀 더 편리하게 사용하기 위해 JSP 2.0부터 도입된 데이터 출력 기능
- 변수와 여러 가지 연산자를 포함할 수 있음
- JSP의 내장 객체에 저장된 속성 및 자바의 빈속성도 표현 언어에서 출력할 수 있음
- 표현 언어 자체 내장 객체도 제공
- JSP 페이지 생성 시 기본 설정은 표현 언어를 사용할 수 없음 => 페이지 디렉티브 태그에서 반드시 isELIgnored="false"로 설정 해아 함
- 형식 : ${표현식 or 값}
<표현 언어의 자료형과 연산자>
- 자료형 : boolean, 정수, 실수, 문자열, null
- 연산자
연산자 종류 | 연산자 | 설명 |
산술 연산자 | + | 덧셈 |
_ | 뺼셈 | |
* | 곱셈 | |
/ or div | 나눗셈 | |
% or mod | 나머지 | |
비교 연산자 | == or eq | 두 값이 같은지 비교 |
!= or ne | 두 값이 다른지 비교 | |
< or lt | 값이 다른 값보다 작은지 비교 | |
> or gt | 값이 다른 값보다 큰지 비교 | |
<= or le | 값이 다른 값보다 작거나 같은지 비교 | |
>= or ge | 값이 다른 값보다 크거나 같은지 비교 | |
논리 연산자 | && or and | 논리곱 연산 |
|| or OR | 논리합 연산 | |
! or not | 부정 연산 | |
empty연산자 | empty<값> | <값>이 null이거나 빈 문자열이면 true를 반환 * 문자열에 대해 false반환 * null은 true 반환 * 빈 문자열은 true 반환 |
조건 연산자 | <수식>?<값1>:<값2> | <수식>의 결과값이 true면 <값1>을 반환하고, false면 <값2>를 반환 |
~표현 언어 실습~
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isELIgnored="false"%>
...
<!-- 자료형 -->
\${100}: ${100}<br>
\${"안녕하세요" }: ${"안녕하세요" }<br>
\${10+1} : ${10+1}<br>
\${"10"+1} : ${"10"+1 }</h1> <!-- 숫자형 문자열+숫자는 문자열을 자동으로 숫자로 변환하여 더함 -->
<h1>\${null+10 }: ${null+10 }</h1>
<!--\${"안녕"+11 }: ${"안녕"+11 }<br> -->
<!--\${"hello"+"world"}:${"hello"+"world"}<br> --> <!-- 문자열+숫자, 문자열+문자열은 안된다 -->
<!-- 산술 연산자 -->
\${10+10} : ${10+10} <br>
\${20-10} : ${20-10} <br>
\${10*10} : ${10*10} <br>
\${100/9} : ${100/9} <br>
\${100 div 9} : ${100 div 9} <br>
\${100%9} : ${100%9}<br>
\${100 mod 9} : ${100 mod 9}<br>
<!--비교 연산자 -->
\${10==10} : ${10==10} <br> <!-- 결과는 bool형으로 나옴 -->
\${10 eq 10} : ${10 eq 10} <br><br>
\${"hello"=="hello"} : ${"hello"=="hello"} <br>
\${"hello" eq "hello"} : ${"hello" eq "hello"} <br><br>
\${20!=10} : ${20!=10}<br>
\${20 ne 10} : ${20 ne 10}<br><br>
\${"hello"!="apple"} : ${"hello"!="apple"} <br>
\${"hello" ne "apple"} : ${"hello" ne "apple"} <br><br>
\${10 < 10} : ${10 < 10} <br>
\${10 lt 10} : ${10 lt 10} <br><br>
\${100>10} : ${100 > 10}<br>
\${100 gt 10} : ${100 gt 10}<br><br>
\${100 <=10} : ${100 <= 10}<br>
\${100 le 10} : ${100 le 10}<br><br>
\${100 >=10} : ${100 >= 10}<br>
\${100 ge 10} : ${100 ge 10}<br><br>
<!-- 논리 연산자 -->
\${(10==10) && (20==20)} : ${(10==10)&&(20==20)} <br> <!-- 둘 다 true일 때만 true반환 -->
\${(10==10) and (20!=20)} : ${(10==10) and (20!=20)} <br><br>
\${(10==10) || (20!=30)} : ${(10==10)||(20==30)} <br>
\${(10!=10) or (20!=20)} : ${(10!=10) or (20!=20)} <br><br>
\${!(20==10)} : ${!(20==10)}<br>
\${not (20==10)} : ${not (20==10)}<br><br>
\${!(20!=10)} : ${!(20!=10)}<br>
\${not(20!=10)} : ${not(20!=10)}<br><br>
<!-- -->
</body>
</html>
- empty 연산자
: 자바 빈의 속성이 값으로 설정되었는지, List, Map 같은 저장 객체에 값(객체)이 존재하는지를 판단하는 연산자
: 자바 빈을 생성 후 속성에 값을 설정하면 empty 연산자의 값은 false
ArrayList 등 또한 객체 생성 후 아무 값도 저장하지 않으면 true
: 문자열은 항상 false
null과 빈 문자열은 항상 true
ex)
..
isELIgnored="false" %>
<jsp:useBean id="m1" class="sec01.ex01.MemberBean" scope="page" />
<jsp:setProperty name="m1" property="name" value="이순신"/> <!-- m1 속성 설정 -> false -->
<jsp:useBean id="m2" class="java.util.ArrayList" scope="page" />
<!-- ArrayList 생성 후 아무 값도 안 넣음 -> true -->
...
\${empty m1 } : ${empty m1 } <br>
\${not empty m1 } : ${not empty m1 } <br><br>
\${empty m2 } : ${empty m2 } <br>
\${not empty m2} : ${not empty m2 } <br><br>
\${empty "hello"} : ${empty "hello" }<br> <!--false -->
\${empty null} : ${empty null } <br> <!--true -->
\${empty ""} : ${empty "" } <br> <!--true -->
14.2 표현 언어 내장 객체(내장 변수)
- JSP는 기본적으로 내장 객체들을 제공하지만 이 객체들은 표현식에서만 사용할 수 있음
- 표현언어만의 내장 객체들을 제공. => ${} 안에서 사용
구분 | 내장 객체 | 설명 |
스코프 | pageScope | JSP의 page와 같은 기능을 하고 page 영역에 바인딩된 객체를 참조 |
requestScope | JSP의 request와 같은 기능을 하고 request에 바인딩된 객체를 참조 ${requestScope.id} == request.getAttribute("id") |
|
sessionScope | JSP의 session과 같은 기능을 하고 session에 바인딩된 객체를 참조 | |
applicationScope | JSP의 application과 같은 기능을 하고 application에 바인딩된 객체를 참조 | |
요청 매개변수 | param | request.getParameter() 메서드를 호출한 것과 같으며 한 개의 값을 전달하는 요청 매개변수를 처리 |
paramValues | request.getParameterValues() 메서드를 호출한 것과 같으며 여러 개의 값을 전달하는 요청 매개변수를 처리 | |
헤더 값 | header | request.getHeader() 메서드를 호출한 것과 같으며 요청 헤더 이름의 정보를 단일 값으로 반환 |
headerValues | request.getHeader() 메서드를 호출한 것과 같으며 요청 헤더 이름의 정보를 배열로 반환 | |
쿠키 값 | Cookies | 쿠키 이름의 값을 반환 |
JSP 내용 | pageContext | pageContext 객체를 참조할 때 사용 (여기 실습에선 프로젝트 이름) |
초기 매개변수 | initParam | 컨텍스트의 초기화 매개변수 이름의 값을 반환 |
1) param 내장 객체 실습
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="java.util.*, sec01.ex01.*"%>
<%
request.setCharacterEncoding("utf-8");
%>
...
<tr align="center">
<td>${param.id}</td>
<td>${param.pwd}</td>
<td>${param.name}</td>
<td>${param.email}</td>
</tr>
${param.id} : <%-- getParameter & getId(혹은 <jsp:getProperty)를 한줄로 --%>
2) requestScope 실습
- forward.jsp
<%
request.setCharacterEncoding("utf-8");
request.setAttribute("address","서울시 강남구");
%>
..
<jsp:forward page="member2.jsp"></jsp:forward>
<!-- 여는 태그와 닫는 태그 사이에 공백 없어야 함에 주의 -->
- member2.jsp
..
<td width="7%" >주소</td>
</tr>
<tr align="center">
<td>${param.id}</td>
<td>${param.pwd}</td>
<td>${param.name}</td>
<td>${param.email}</td>
<td>${requestScope.address }</td>
3) pageContext 실습
- pageContext 객체 : 웹 컨테이너가 JSP 실행 시 자동으로 생성해서 제공하는 내장 객체
- <a> 태그를 이용해 다른 서블릿이나 JSP를 요청하는 방법(href 값 입력 방법)
1) 컨텍스트 이름(여기선 pro14)를 직접 입력 => 컨텍스트 이름이 바뀌면 일일이 찾아서 수정해야 함
ex) "/pro14/~"
2) getContextPath() 이용 => 자바 코드가 사용되므로 화면 작업이 복잡해짐
ex) "<%=request.getContextPath() %>/~"
- 그래서 pageContext 객체의 속성인 request의 contextPath 속성 이용!!
:"${pageContext.request.contextPath}/~"
...
<a href="${pageContext.request.contextPath}/test01/memberForm.jsp">회원가입하기</a>
4) 빈 사용 실습
- 빈 속성에 접근할 때는 ${빈이름.속성이름} 형식을 사용함.
- 표현언어에서는 getter를 사용하지 않고 ${빈id.속성이름} 으로 속성에 바로 접근할 수 있음
<jsp:useBean id="m" class="sec01.ex01.MemberBean"></jsp:useBean>
<jsp:setProperty name="m" property="*"/>
...
<td>${m.id}</td> <%-- <%=m.getId() %> 와 동일하다 --%>
<td>${m.pwd}</td>
<td>${m.name}</td>
<td>${m.email}</td>
5) Collection 객체 사용 실습
- 형식 : ${Collection객체이름[index].속성이름}
- Collection의 ArrayList 객체 이름으로 접근하기
<jsp:useBean id="m" class="sec01.ex01.MemberBean"></jsp:useBean>
<jsp:setProperty name="m" property="*"/>
<jsp:useBean id="memberList" class="java.util.ArrayList"/>
<%
MemberBean m2=new MemberBean("son","3231","손흥민","son@totnum.com");
memberList.add(m);
memberList.add(m2);
%>
...
<tr align="center">
<td>${memberList[0].id}</td>
<td>${memberList[0].pwd}</td>
<td>${memberList[0].name}</td>
<td>${memberList[0].email}</td>
</tr>
<tr align="center">
<td>${memberList[1].id}</td>
<td>${memberList[1].pwd}</td>
<td>${memberList[1].name}</td>
<td>${memberList[1].email}</td>
</tr>
6) HashMap 사용 실습
- HashMap에 저장된 객체에 접근하는 방법: ${HashMap객체이름.키이름}
<jsp:useBean id="m" class="sec01.ex01.MemberBean"></jsp:useBean>
<jsp:setProperty name="m" property="*"/>
<jsp:useBean id="memberList" class="java.util.ArrayList"/>
<jsp:useBean id="hashMap" class="java.util.HashMap"/>
<%
hashMap.put("id","park2");
hashMap.put("pwd","1234");
hashMap.put("name","박지성");
hashMap.put("email","park@test.com");
MemberBean m2=new MemberBean("son","3231","손흥민","son@totnum.com");
memberList.add(m);
memberList.add(m2);
hashMap.put("memberList",memberList);
%>
...
<tr align="center">
<td>${hashMap.id}</td>
<td>${hashMap.pwd}</td>
<td>${hashMap.name}</td>
<td>${hashMap.email}</td>
</tr>
<tr align="center">
<td>${hashMap.memberList[0].id}</td>
<td>${hashMap.memberList[0].pwd}</td>
<td>${hashMap.memberList[0].name}</td>
<td>${hashMap.memberList[0].email}</td>
</tr>
<tr align="center">
<td>${hashMap.memberList[1].id}</td>
<td>${hashMap.memberList[1].pwd}</td>
<td>${hashMap.memberList[1].name}</td>
<td>${hashMap.memberList[1].email}</td>
</tr>
>> hashMap에 박지성의 속성들을 저장하고, 손흥민-요청값을 넣은 ArrayList를 저장하여 거기서 key로 객체를 접근
7) has-a 관계 빈 사용 실습
- has-a 관계 : 객체가 다른 객체를 속성으로 가지는 경우
- ${부모빈이름.자식속성이름.속성이름} 으로 접근
<jsp:useBean id="m" class="sec01.ex01.MemberBean"></jsp:useBean>
<jsp:setProperty name="m" property="*"/>
<jsp:useBean id="address" class="sec01.ex01.Address"/>
<jsp:setProperty name="address" property="city" value="NewYork"/>
<jsp:setProperty name="address" property="zipcode" value="07453"/>
<%
m.setAddress(address);
%>
...
<tr align="center">
<td>${m.id}</td>
<td>${m.pwd}</td>
<td>${m.name}</td>
<td>${m.email}</td>
<td>${m.address.city}</td>
<td>${m.address.zipcode }</td>
</tr>
>> address를 m에 set할 땐 자바코드로 setter를 호출하는 방법밖에...
>> ${자바 빈이름.자식이름.속성이름}으로 접근!
14.3 표현 언어로 바인딩 속성 출력하기
- request, session, application 내장 객체에 속성을 바인딩한 후 다른 서블릿이나 JSP에 전달할 수 있음
- 즉, ~.setAttribute()로 바인딩 한 후 포워딩하면 어떤 객체이건 간에 상관없이 속성 이름으로만 접근 가능
- getAttribute + <%= >두개를 ${속성이름} 하나로 해결
- 다른 종류의 내장 객체에 같은 이름으로 속성이 들어가 있으면 우선순위에 따라 출력됨
-내장 객체 우선순위 : page>request>session>application
속성 바인딩 ex)
- forwrard1.jsp
<%
request.setCharacterEncoding("utf-8");
request.setAttribute("id","hong");
request.setAttribute("pwd","1234");
session.setAttribute("name","홍길동");
application.setAttribute("email","hong@test.com");
%>
...
<jsp:forward page="member1.jsp"></jsp:forward>
- member1.jsp
<tr align="center">
<td>${id}</td>
<td>${pwd}</td>
<td>${name}</td>
<td>${email}</td>
</tr>
객체 바인딩 ex)
<!-- forward2.jsp -->
MemberBean member=new MemberBean("lee","1234","이순신","lee@test.com");
request.setAttribute("member",member);
%>
..
<jsp:forward page="member2.jsp"></jsp:forward>
<!-- member2.jsp -->
<td>${member.id}</td>
<td>${member.pwd}</td>
<td>${member.name}</td>
<td>${member.email}</td>
ArrayList 바인딩 ex)
<!-- forward3.jsp -->
<%
request.setCharacterEncoding("utf-8");
MemberBean m1=new MemberBean("lee","1234","이순신","lee@test.com");
MemberBean m2=new MemberBean("hong","2222","홍길동","hong@test.com");
List members=new ArrayList();
members.add(m1);
members.add(m2);
request.setAttribute("members",members);
%>
<!-- member3.jsp -->
<tr align="center">
<td>${members[0].id}</td>
<td>${members[0].pwd}</td>
<td>${members[0].name}</td>
<td>${members[0].email}</td>
</tr>
<tr align="center">
<td>${members[1].id}</td>
<td>${members[1].pwd}</td>
<td>${members[1].name}</td>
<td>${members[1].email}</td>
</tr>