표현 언어(EL, Expression Language)란?
자바 코드의 표현식(<%= ... %>)을 편리하게 사용하기 위해 만든 데이터 출력 기능
${표현식}
형태로 되어 있으며 식에서 다양한 데이터 타입과 연산자를 사용할 수 있음
jsp 페이지에서 사용하려면 해당 페이지의 page 디렉티브 속성에서 isELIgnored="false"로 설정해야 함
<%@ page isELIgnored="false" %>
자바빈 객체가 존재하는지, List/Map 등의 컬렉션에 값(객체)가 존재하는지 판단하는 연산자
<%@ page language="java" contentType="text/html; charset=UTF-8"
import="java.util.*, sec01.ex01.*"
pageEncoding="UTF-8"
isELIgnored="false"
%>
<jsp:useBean id="m1" class="sec01.ex01.MemberBean" scope="page" />
<jsp:useBean id="m2" class="java.util.ArrayList" scope="page" />
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>표현 언어의 여러 가지 연산자들</title>
</head>
<body>
<h2>
\${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>
\${empty null} : ${empty null}<br>
\${empty ""} : ${empty ""}<br>
</h2>
</body>
</html>
[실행 결과]
${empty m1} : false
${not empty m1} : true
${empty m2} : true
${not empty m2} : false
${empty "hello"} : false
${empty null} : true
${empty ""} : true
DTO
객체 m1은 useBean 태그로 객체가 생성되었으므로 empty
연산자를 사용하면 false
를 반환하고, ArrayList
객체 m2는 객체는 존재하지만 안에 값(객체)가 하나도 없기 때문에 empty
연산자를 사용하면 true
를 반환함
null과 빈 문자열 "" 도 empty
연산자를 사용하면 true
를 반환함
JSP의 내장 객체처럼 표현 언어에서 사용할 수 있는 내장 객체가 존재함
자바 코드 request.getParameter("이름")
대신
표현 언어 ${param.이름}
으로
요청 파라미터에 접근할 수 있음
자바 코드 request.getAttribute("속성명")
대신
표현 언어 ${requestScope.속성명}
으로
request에 바인딩된 데이터에 접근할 수 있음
sessionScope / applicationScope 내장 객체는 각각 session, application에 바인딩된 데이터에 접근 가능
jsp 페이지 실행 시 자동으로 생성되는 내장 객체로, pageContext
객체의 속성인 request
의 contextPath
속성을 사용하면 컨텍스트명을 가져올 수 있음
<a href="${pageContext.request.contextPath}/페이지명"></a>
jsp의 내장 객체(request, session, application)에 바인딩된 속성을 표현 언어로 출력 가능
${바인딩된 속성}
로 출력 가능하며
DTO 객체인 경우 {$DTO.변수명}
으로 해당 객체의 멤버 변수에 접근 가능
ArrayList에 담겨 있으면 {$ArrayList[n].변수명}
으로 접근 가능
각각의 내장 객체에 바인딩된 데이터 이름이 같으면
page > request > session > application 우선 순위로 데이터를 가져옴
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"
import="sec01.ex01.*, java.util.*" %>
<%
request.setCharacterEncoding("utf-8");
List membersList = new ArrayList();
MemberBean member1 = new MemberBean("park","1234","박민우","park@test.com");
MemberBean member2 = new MemberBean("son","1234","손아섭","son@test.com");
membersList.add(member1);
membersList.add(member2);
// ArrayList 객체 바인딩
request.setAttribute("membersList", membersList);
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>forward3</title>
</head>
<body>
<!-- forward 액션 태그로 포워딩 -->
<jsp:forward page="member3.jsp" />
</body>
</html>
파일명 : member3.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"
isELIgnored="false" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원 정보 출력</title>
</head>
<body>
<table border="1" align="center">
<tr align="center" bgcolor="#99ccff">
<td width="20%"><strong>아이디</strong></td>
<td width="20%"><strong>비밀번호</strong></td>
<td width="20%"><strong>이름</strong></td>
<td width="20%"><strong>이메일</strong></td>
</tr>
<!-- getAttribute() 없이 바인딩된 속성 출력하기 -->
<tr align="center">
<td>${membersList[0].id}</td>
<td>${membersList[0].pwd}</td>
<td>${membersList[0].name}</td>
<td>${membersList[0].email}</td>
</tr>
<tr align="center">
<td>${membersList[1].id}</td>
<td>${membersList[1].pwd}</td>
<td>${membersList[1].name}</td>
<td>${membersList[1].email}</td>
</tr>
</table>
</body>
</html>
💻 실행 결과
표현 언어로 request에 바인딩한 ArrayList를 가져와 값을 출력함
커스텀 태그란?
JSP 페이지에서 자주 사용하는 자바 코드를 대체하기 위해 만든 태그
대표적인 커스텀 태그로 JSTL이 있음 (라이브러리 설치 필요)
JSTL(JSP Standard Tag Library) 이란?
커스텀 태그 중 가장 많이 사용되는 태그를 표준화하여 제공하는 라이브러리
커스텀 태그 라이브러리를 사용하려면 라이브러리 jar 파일을 설치하고, 해당 JSP 페이지에 사용하려는 태그의 정보를 담은 taglib 디렉티브 태그를 추가해야 함
라이브러리 | 세부 기능 | 접두어 | 관련 URI |
---|---|---|---|
코어 | 변수 지원, 흐름 제어, 반복문 처리, URL 처리 | c | http://java.sun.com/jsp/jstl/core |
국제화 | 지역, 메세지 형식, 숫자 및 날짜 형식 | fmt | http://java.sun.com/jsp/jstl/fmt |
함수 | 컬렉션/문자열 처리 | fn | http://java.sun.com/jsp/jstl/functions |
예를 들어, 코어 태그를 사용하기 위해서는 JSP 페이지 상단에 다음과 같이 작성해야 한다.
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="변수명" value="변수값" [scope="scope 속성 지정"] />
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"
isELIgnored="false" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
request.setCharacterEncoding("utf-8");
%>
<!-- c:set 태그로 변수 선언 -->
<c:set var="name" value="정예주" scope="page" />
<c:set var="age" value="27" scope="page" />
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원 정보 출력창</title>
</head>
<body>
<table border="1" align="center">
<tr align="center" bgcolor="lightgreen">
<td><strong>이름</strong></td>
<td><strong>나이</strong></td>
</tr>
<tr align="center">
<td>${name}</td>
<td>${age}</td>
</tr>
</table>
<!-- contextPath를 변수로 선언해 사용하기 -->
<c:set var="contextPath" value="${pageContext.request.contextPath}" />
<a href="${contextPath}/test03/memberForm.jsp">회원가입하기</a>
</body>
</html>
💻 실행 결과
변수로 선언한 내용이 표현 언어로 출력됨
<c:if test="${조건식}">
참이면 실행할 내용
...
</c:if>
<c:choose>
<c:when test="조건식1">1이 참이면 실행할 내용</c:when>
<c:when test="조건식2">2가 참이면 실행할 내용</c:when>
...
<c:otherwise>모두 거짓이면 실행할 내용</c:otherwise>
</c:choose>
<c:forEach var="변수명" items="반복할 객체명" begin="시작값" end="마지막값" step="증가값" varStatus="반복 상태 변수명">
...
</c:forEach>
<%@ page language="java" contentType="text/html; charset=UTF-8"
import="java.util.*"
pageEncoding="UTF-8"
isELIgnored="false" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
List dataList = new ArrayList();
dataList.add("hello");
dataList.add("world");
dataList.add("안녕!");
%>
<!-- c:set 태그로 변수 할당 -->
<!-- List를 c:set으로 만든게 아니기 때문에 표현문 태그로 값을 넣어줌 -->
<c:set var="list" value="<%= dataList %>" />
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>forEach 태그 실습</title>
</head>
<body>
<c:forEach var="i" begin="1" end="10" step="1" varStatus="loop">
i = ${i} 반복횟수 : ${loop.count}<br>
</c:forEach>
<br>
<c:forEach var="i" begin="1" end="10" step="2">
5*${i} = ${5*i}<br>
</c:forEach>
<br>
<c:forEach var="data" items="${list}">
data : ${data}<br>
</c:forEach>
<br>
<!-- fruits 변수 할당 -->
<c:set var="fruits" value="사과, 파인애플, 바나나, 망고, 귤" />
<!-- c:forTokens 태그 사용해 구분자로 문자열 분리해 출력 -->
<c:forTokens var="token" items="${fruits}" delims=",">
token : ${token}<br>
</c:forTokens>
</body>
</html>
[실행 결과]
i = 1 반복횟수 : 1
i = 2 반복횟수 : 2
i = 3 반복횟수 : 3
i = 4 반복횟수 : 4
i = 5 반복횟수 : 5
i = 6 반복횟수 : 6
i = 7 반복횟수 : 7
i = 8 반복횟수 : 8
i = 9 반복횟수 : 9
i = 10 반복횟수 : 10
5*1 = 5
5*3 = 15
5*5 = 25
5*7 = 35
5*9 = 45
data : hello
data : world
data : 안녕!
token : 사과
token : 파인애플
token : 바나나
token : 망고
token : 귤
<c:url var="변수명" value="URL 경로">
<c:param name="파라미터 키" value="파라미터 값"/>
...
</c:url>
<%@ page language="java" contentType="text/html; charset=UTF-8"
import="java.util.*"
pageEncoding="UTF-8"
isELIgnored="false"
%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!-- c:url 태그로 이동할 url의 정보 설정하기(파라미터 전송 가능) -->
<c:url var="url1" value="/test01/member1.jsp">
<c:param name="id" value="jeong" />
<c:param name="pwd" value="1234" />
<c:param name="name" value="정예주" />
<c:param name="email" value="jeong@test.com" />
</c:url>
<!-- 전송한 데이터는 getParameter()로 접근 가능 -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>c:url 태그 실습</title>
</head>
<body>
<a href="${url1}">회원정보 출력</a>
</body>
</html>
파일명 : /test01/member1.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"
isELIgnored="false" %>
<%
request.setCharacterEncoding("utf-8");
String id = request.getParameter("id");
String pwd = request.getParameter("pwd");
String name = request.getParameter("name");
String email = request.getParameter("email");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원 정보 출력창</title>
</head>
<body>
<table align="center" width="100%">
<tr align="center" bgcolor="#99ccff">
<td width="20%">아이디</td>
<td width="20%">비밀번호</td>
<td width="20%">이름</td>
<td width="20%">이메일</td>
</tr>
<tr align="center">
<!-- param 내장 객체를 이용해 파라미터 가져오기 -->
<!-- getParameter("id") : param.id 와 동일 -->
<td>${ param.id }</td>
<td>${ param.pwd }</td>
<td>${ param.name }</td>
<td>${ param.email }</td>
</tr>
<tr height="1" bgcolor="#99ccff">
<td colspan="5"></td>
</tr>
</table>
<a href="memberForm.jsp">회원 추가하기</a>
</body>
</html>
💻 실행 결과
<c:url> 태그로 url에 param을 설정하면 url뒤에 쿼리를 붙여 get방식으로 전달하는 것과 동일하게 파라미터를 전달 가능함
<c:redirect url="이동할 URL">
<c:param name="파라미터 키" value="파라미터 값"/>
...
</c:redirect>
<c:out value="출력할 값" default="value가 없을때 사용할 기본값" />
숫자, 날짜의 표기 형식을 지정 가능
value
: 출력할 숫자의 값
type
: 출력될 타입 (percent : %, number : 숫자, currency : 통화)
groupingUsed
: 콤마 등 기호로 구분 여부 지정 (기본값 true)
currencyCode
: 통화 코드 지정 (한국 원화는 KRW)
currencySymbol
: 통화 표시에 사용할 기호 지정
var
: 해당 태그로 출력된 값을 저장할 변수명
scope
: 변수의 접근 범위 지정
value
: 출력할 날짜
type
: 출력될 타입 (date : 날짜만, time : 시간만, both : 모두)
dateStyle
: 날짜의 출력 형식 지정 (full, long, medium, short)
timeStyle
: 시간의 출력 형식 지정
timeZone
: 특정 나라 시간대로 시간 설정
<%@ page language="java" contentType="text/html; charset=UTF-8"
import="java.util.Date"
pageEncoding="UTF-8"
isELIgnored="false" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>포매팅 태그 라이브러리 예제</title>
</head>
<body>
<h2>fmt:formatNumber 태그를 이용한 숫자 포매팅</h2>
<c:set var="price" value="100000000"/>
<!-- 변수 priceNumber 선언 -->
<fmt:formatNumber value="${price}" type="number" var="priceNumber"/>
통화로 표현 시 :
<!-- type: 종류(통화,숫자,퍼센트), groupingUsed: 콤마 표시 -->
<fmt:formatNumber type="currency" groupingUsed="true" value="${price}" /><br>
퍼센트로 표현 시 :
<fmt:formatNumber type="percent" groupingUsed="true" value="${price}"/><br>
일반 숫자로 표현 시 :
${priceNumber}<br>
<hr>
<h2>fmt:formatDate 태그를 이용한 날짜, 시간 포매팅</h2>
<c:set var="now" value="<%= new Date() %>" />
<!-- type: 종류(날짜,시간,날짜+시간), dateStyle: 날짜 출력 형식 -->
[type: date / dateStyle: full]<br>
<fmt:formatDate type="date" dateStyle="full" value="${now}" /><br><br>
[type: date / dateStyle: short]<br>
<fmt:formatDate type="date" dateStyle="short" value="${now}" /><br><br>
[type: time]<br>
<fmt:formatDate type="time" value="${now}" /><br><br>
[type: time / dateStyle: full / timeStyle: full]<br>
<fmt:formatDate type="both" dateStyle="full" timeStyle="full" value="${now}" /><br><br>
[pattern: YYYY-MM-dd hh:mm:ss]<br>
<fmt:formatDate pattern="YYYY-MM-dd hh:mm:ss" value="${now}" /><br><br>
[type: both / dateStyle: full / timeStyle: full]<br>
<fmt:formatDate type="both" dateStyle="full" timeStyle="full" value="${now}" /><br><br>
[type: both / dateStyle: long / timeStyle: long]<br>
<fmt:formatDate type="both" dateStyle="long" timeStyle="long" value="${now}" /><br><br>
[type: both / dateStyle: medium / timeStyle: medium]<br>
<fmt:formatDate type="both" dateStyle="medium" timeStyle="medium" value="${now}" /><br><br>
[type: both / dateStyle: short / timeStyle: short]<br>
<fmt:timeZone value="America/New York">
뉴욕 현재 시간 :
<fmt:formatDate type="both" dateStyle="short" timeStyle="short" value="${now}" />
</fmt:timeZone>
</body>
</html>
💻 실행 결과
문자열 처리 관련 기능을 사용할 수 있음, 표현 언어 ${}
안에 해당 내용을 넣으면 출력
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"
isELIgnored="false" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>문자열 함수 사용</title>
</head>
<body>
<c:set var="title1" value="hello world!"/>
<c:set var="title2" value="쇼핑몰 중심 JSP"/>
<c:set var="title3" value=" 쇼핑몰 중심 JSP "/>
<c:set var="str1" value="중심"/>
<h2>여러 가지 문자열 함수 기능</h2>
title1 : "hello world"<br>
title2 : "쇼핑몰 중심 JSP"<br>
title3 : " 쇼핑몰 중심 JSP "<br>
str1 : "중심"<br>
<br>
fn:length(title1) : ${fn:length(title1)}<br>
fn:toUpperCase(title1) : ${fn:toUpperCase(title1)}<br>
fn:toLowerCase(title1) : ${fn:toLowerCase(title1)}<br>
<br>
<!-- title1에서 index 2~4번째 문자열 반환 -->
fn:substring(title1, 2, 5) : ${fn:substring(title1, 2, 5)}<br>
fn:trim(title3) : ${fn:trim(title3)}<br>
fn:replace(title1, " ", "/") : ${fn:replace(title1, " ", "/")}<br>
<br>
<!-- title2에서 str1이 시작되는 인덱스 -->
fn:indexOf(title2, str1) : ${fn:indexOf(title2, str1)}<br>
<!-- title1,2가 str1을 포함하는지 확인 -->
fn:contains(title1, str1) : ${fn:contains(title1, str1)}<br>
fn:contains(title2, str1) : ${fn:contains(title2, str1)}<br>
</body>
</html>
💻 실행 결과
form action을 member_action.jsp
로 수정
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원 가입창</title>
</head>
<body>
<form action="member_action.jsp" method="post">
<h1 style="text-align:center">회원 가입창</h1>
<table align="center">
<tr>
<td width="200">
<p align="right">아이디</p>
</td>
<td width="400">
<input type="text" name="id" required>
</td>
</tr>
...
</form>
</body>
</html>
해당 페이지에서 자바빈 객체를 생성하고
DAO의 회원 추가 메서드를 호출해 DB에 데이터를 추가
회원 조회 메서드를 호출해 받아온 List를 바인딩 후 출력 페이지로 포워드함
파일명 : member_action.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
import="java.util.*, sec02.ex01.*"
pageEncoding="UTF-8"
isELIgnored="false" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
request.setCharacterEncoding("utf-8");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<!-- useBean 태그로 객체 생성 -->
<jsp:useBean id="m" class="sec02.ex01.MemberBean" />
<jsp:setProperty name="m" property="*" />
<%
MemberDAO dao = MemberDAO.getInstance();
dao.addMember(m);
List membersList = dao.listMembers();
request.setAttribute("membersList", membersList);
%>
<!-- 데이터 바인딩 후 포워드 -->
<jsp:forward page="memberList.jsp" />
</body>
</html>
바인딩된 데이터는 표현 언어로 가져와 출력하고,
조건문과 반복문이 필요한 부분은 코어 태그를 사용해 자바 코드 없이 필요한 내용을 출력
<%@ page language="java" contentType="text/html; charset=UTF-8"
import="java.util.*, sec02.ex01.*"
pageEncoding="UTF-8"
isELIgnored="false" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원 정보 출력</title>
</head>
<body>
<table align="center" width="100%">
<tr align="center" bgcolor="#99ccff">
<td width="7%">아이디</td>
<td width="7%">비밀번호</td>
<td width="5%">이름</td>
<td width="11%">이메일</td>
<td width="5%">가입일</td>
</tr>
<!-- membersList가 존재하는지 확인 -->
<!-- getAttribute() 메서드 없이 표현 언어로 접근하기 -->
<c:choose>
<c:when test="${membersList == null}">
<tr>
<td colspan="5">
<p align="center">
등록된 회원이 없습니다.
</p>
</td>
</tr>
</c:when>
<c:when test="${membersList != null}">
<c:forEach var="bean" items="${membersList}">
<tr align="center">
<td>${bean.id}</td>
<td>${bean.pwd}</td>
<td>${bean.name}</td>
<td>${bean.email}</td>
<td>${bean.joinDate}</td>
</tr>
</c:forEach>
</c:when>
</c:choose>
<tr height="1" bgcolor="#99ccff">
<td colspan="5"></td>
</tr>
</table>
<a href="memberForm.html">회원 추가하기</a>
</body>
</html>
💻 실행 결과