BackEnd/JSP

14장. 표현 언어와 JSTL - ②JSTL

제이드Jade 2022. 2. 22. 23:07

14.4 커스텀 태그

- 커스텀 태그 : 조건식이나 반복문 등 JSP 페이지에서 자주 쓰이는 자바 코드를 대체하기 위해 만든 태그

  • JSTL : JSP 페이지에서 가장 많이 사용하는 기능을 태그로 제공, JSTL 라이브러리로 제공(따로 설치 필요)
  • 개발자가 만든 커스텀 태그 : 개발자가 필요에 의해 만든 태그, 스트러츠나 스프링 프레임워크에서 미리 만들어서 제공

 

14.5 JSP 표준 태그 라이즈러리(JSTL)

JSTL 태그 종류

- JSTL은 JSP2.0 규약부터 추가된 기능이므로 현재 톰캣에서 기본으로 제공X

사이트에서 라이브러리를 다운로드해야 함 

* http://tomcat.apache.org/download-taglibs.cgi 

사이트에 접속한 후 Impl, Spec, EL, Compat 네 개의 jar파일을 다운 > lib 폴더에 복사

 

14.6 Core 태그 라이브러리 사용하기

- 코어 라이브러리로 변수 선언, 조건식, 반복문 기능을 태그로 대체할 수 있음

- (import문 처럼) 코어 태그 라이브러리를 사용하려면 JSP 페이지 상단에 taglib 디렉티브 태그를 추가 해서 톰캣에게 알려줘야 함 : <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

- Core 태그 라이브러리 기능 (<c:태그 ~~> 형태로 사용)

기능 태그 설명
변수지원 set JSP 에서 사용될 변수를 설정
remove 설정한 변수를 제거
흐름제어 if 조건문
choose switch문, when, otherwise 서브 태그를 가짐
forEach 반복문
forTokens 구분자로 분리된 각각의 토큰을 처리
URL 처리 import URL을 사용해 다른 자원의 결과를 삽입
redirect 지정한 경로로 redirect (==response.sendRedirect() )
url URL 재작성
기타 태그 catch 예외 처리에 사용
out JspWriter에 내용을 알맞게 처리한 후 출력

- 각 태그의 속성에는 표현 언어를 사용할 수 있음

 


1) <c:set>
- JSP에서 변수를 사용을 위함

- <c:set var="변수이름" value="변수값" [scope="scope속성"] />

 

일반 변수 ex)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="java.util.*, sec01.ex01.*"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

<%
request.setCharacterEncoding("utf-8");
%>

<c:set var="id" value="hong"/>
<c:set var="pwd" value="1234"/>
<c:set var="name" value="홍길동"/>
<c:set var="age" value="22"/>
<c:set var="height" value="177"/>

<!DOCTYPE html>
...
	   <tr align="center">
	       <td>${id}</td>        //표현언어로 바로 쓰면 됨
	       <td>${pwd}</td>
	       <td>${name}</td>
	       <td>${age}</td>
	       <td>${height}</td> 
	   </tr>

 

contextPath를 변수로 담기 ex)

<c:set var="contextPath" value="${pageContext.request.contextPath}"/>
...
<a href="${contextPath}/test03/memberForm.jsp">회원가입하기</a>

 

hashMap.ArrayList를 변수로 담기 ex)

<jsp:useBean id="membersList" class="java.util.ArrayList"/>
<jsp:useBean id="membersMap" class="java.util.HashMap"/>

<%
membersMap.put("id","hong");
membersMap.put("pwd","1223");
membersMap.put("name","홍길동");
membersMap.put("email","hong@test.com");

MemberBean m1=new MemberBean("park","1234","박지성","park@test.com");
MemberBean m2=new MemberBean("son","2321","손흥민","son@test.com");
membersList.add(m1);
membersList.add(m2);

membersMap.put("membersList",membersList);
%>
<c:set var="membersList" value="${membersMap.membersList }"/>

..

	   <tr align="center">
	       <td>${membersMap.id}</td>
	       <td>${membersMap.pwd}</td>
	       <td>${membersMap.name}</td>
	       <td>${membersMap.email}</td>
	   </tr> 
	   <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>

 

2) <c:remove>

- 변수 제거, 그 삭제된 변수를 표현언어 등으로 접근해도 값은 나오지 않음(화면에는 빈공간)

- <c:remove var="변수이름" [scope=""]/>

 

 

3) <c:if>

- <c:if test="${조건식}" var="변수이름" [scope="'] /> </c:if>

- var에는 조건식의 결과(true/false)를 저장

ex)

 <c:if test="${true }">
  <h1>항상 참입니다.</h1></c:if>
 <c:if test="${11==11}">
  <h1>두 값은 같습니다</h1></c:if>
 <c:if test="${(id=='hong') && (name=='홍길동')}"> 
  <h1>아이디는 ${id }이고 이름은 ${name }입니다.</h1></c:if>
<!-- 조건식의 값은 큰따옴표가 아닌 작은 따옴표로 해야 함 -->
 <c:if test="${age==22}">
  <h1>${name }의 나이는 ${age }살 입니다.</h1></c:if>
 <c:if test="${height>170}">
  <h1>${name }의 키는 170보다 큽니다.</h1></c:if>

 

4) <c:choose>

- == switch문

<c:choose>

  <c:when test="조건식1">본문내용1</c:when>

  <c:when test="조건식2">본문내용2</c:when>

   ..

   <c:otherwise>본문내용 </c:otherwise>

</c:choose>

 

ex)

<c:choose>
		<c:when test="${empty name }">
			<h1>이름을 입력하세요</h1></c:when>
		<c:otherwise>
		   <tr align="center">
		       <td>${id}</td>
		       <td>${pwd}</td>
		       <td>${name}</td>
		       <td>${age}</td>
		       <td>${height}</td> 
		   </tr> 
	   	</c:otherwise>
</c:choose>

 

 

5) <c:forEach>와 <c:forTokens>

- forEach : 반복문

<c:forEach var="변수이름" items="반복할객체이름" begin="시작값" end="마지막값" step="증가값" varStatus="반복상태변수이름"> </c:forEach>

- varStatus의 속성

  • index : items에서 정의한 항목을 가리키는 index번호(0부터 시작)
  • count : 몇 번째 반복인지 나타냄(1부터 시작)
  • first : 첫 번째 반복인지
  • last : 마지막 반복인지

- <c:forTokens> var="" items="" delims="구분자" </c:forTokens> >>구분자로 분리된 토큰을 차례로 var에

 

ex)

<%
List dataList=new ArrayList();
dataList.add("hello");
dataList.add("world");
dataList.add("안녕하세요!");
%>

<c:set var="list" value="<%= dataList %>"/> <!-- 변수 선언 해줘야 함.. ${dataList}로 접근하면 안됐음; -->

...

 <c:forEach var="i" begin="1" end="10" step="1" varStatus="loop">
  i=${i }   반복횟수 : ${loop.count }<br> </c:forEach> <!-- var 변수를 이용할 때 ${}안에 쓰기 -->

<br>
 <c:forEach var="i" begin="1" end="10" step="2">
  5 * ${i } = ${5*i }<br></c:forEach> <!-- 변수를 이용한 식을 쓰고 싶으면 ${}한번만 써서 변수 맘대로 쓰면 되는듯 -->
  
<br>
 <c:forEach var="item" items="${list }"> <!--  --> <!-- 선언한 변수 사용이므로 ${list} -->
  ${ item}<br></c:forEach> <!-- list가 만약 객체 리스트였음 ${item.id}식으로 하면 됨 -->
  
<br>
<c:set var="fruits" value="사과,파인애플,키위,바나나"/> <!-- 문자열을 토큰으로 분리 -->
<c:forTokens var="fruit" items="${fruits }" delims=",">
 ${fruit }<br>
</c:forTokens>

 

 

6) <c:url>

- URL 정보를 저장하는 역할

- <c:url var="변수이름" value="URL 경로" [scope=""]>

     [<c:param var="매개변수이름" value="" />]

   </c:url>

- 이 var로 주소에 간편하게 접근하여 href의 값으로 넣는 등 하면 됨

 

ex)

<c:url var="url1" value="/test01/member1.jsp">
 <c:param name="id" value="hong"/>
 <c:param name="pwd" value="1234"/>
   <c:param name="name" value="홍길동"/>
    <c:param name="email" value="hong@test.com"/>
  </c:url>
 
...
<a href="${url1 }">회원정보출력</a>

 

7) <c:redirect>

- response.sendRedirect()와 같다

<c:redirect url="">

 [<c:param name="" value="" />]

</c:redirect>

 

ex)

 <c:redirect url="/test01/member1.jsp">
 <c:param name="id" value="hong"/>
 <c:param name="pwd" value="1234"/>
 <c:param name="name" value="홍길동"/>
    <c:param name="email" value="hong@test.com"/>
  </c:redirect>

 

8) <c:out>

- 표현 언어와 기능은 거의 동일

- 기본값 설정 기능 등을 제공하므로 더 편리하게 사용할 수 있음

- <c:out value="출력값" default="기본값" [excapeXml="boolean값"] />

- default속성 : value속성에 지정된 값이 없을 때 출력할 기본 값

  escapeXml : excape 문자 변환(기본값 true - 변환 안한다는 말)

 

ex)

<c:choose>
    <c:when test="${empty param.id }">
        <h1>아이디를 입력하세요</h1></c:when>
    <c:otherwise>
       <tr align="center">
           <td><c:out value="${param.id}"/></td>
           <td><c:out value="${param.pwd}"/></td>
           <td><c:out value="${param.name}"/></td>
           <td><c:out value="${param.email}"/></td>
       </tr> 
   </c:otherwise>
</c:choose>

 

- <, >, ' , " 같은 특수 문자를 출력해야 하는 경우 각각의 특수문자에 지정된 문자를 이용해서 브라우저에 출력

- escapeXml을 false로 설정하고 변환된 문자를 입력하면 특수문자가 나온다.

특수문자 변환된 문자
< &lt;
> &gt;
& &amp;
' &#039;
" &#034

 

ex)

<c:out  value="&gt;" escapeXml="true" />
<c:out  value="&gt;" escapeXml="false" />

결과

 

 

- 그 외 <c:import>태그는 <jsp:include>와 같은 기능을 수행함

 

 

 

14.7 Core 태그 라이브러리 실습 예제

<c:if test="${not empty param.user_id }">
	 <c:if test="${param.user_id =='admin'}"> <!-- test="${조건식}" 임에 유의!! -->
	  <h1>관리자로 로그인 했습니다.</h1>
	  <form>
	  	<input type="button" value="회원정보 삭제하기"/>
	  	<input type="button" value="회원정보 수정하기"/>
	  </form>
	 </c:if>
	 <c:if test="${param.user_id !='admin'}">
	  <h1>환영합니다. ${param.user_id }님!!!</h1>
	 </c:if>
</c:if>
<c:if test="${empty param.user_id }">
 아이디를 입력하세요.<br>
 <a href=${login }>로그인 창</a></c:if>

 

- 현재 JSP 페이지는 JSTL로 구현하므로 라이브러리를 사용하는 방법에 익숙해지면 좋음

 

14.8 다국어 태그 라이브러리 사용하기

- 쇼핑몰 같은 곳에서 언어 변환하는 기능 >> JSP에서 다국어 태그 라이브러리를 사용하는 것

다국어 태그 라이브러리 종류

- 사용하기 위해 <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> 를 선언해야 함

태그 설명
<fmt:setLocale> Locale(언어)을 지정
<fmt:message> 리소스 번들에서 로케일에 맞는 메시지를 가져와 출력
<fmt:bundle> 사용할 번들 지정
<fmt:setBundle> 리소스번들을 읽어와 특정 변수에 저장
<fmt:setParam> 전달할 매개변수 지정
<fmt:requestEncoding> 요청 매개변수의 문자 인코딩 지정

 

 

14.9 한글을 아스키 코드로 변환하기

- 다국어 기능을 사용하기 위해선 미리 한글을 아스키 코드로 변환한 형태로 저장하고 있다가 요청 시 이 아스키 코드를 다시 한글로 변환해서 표시. 영어는 변환 필요없이 그냥 영어로 저장하면 됨

 

<방법>

1. 이클립스에서 한글을 아스키 코드로 변환하는 기능을 제공하는 Properties Editor 플러그인 설치(방법 p.583~586참고)

2. 한글 아스키 파일 만들기

   * 프로젝트의 src폴더에 resource패키지 생성

   > File 3개 생성(이름 : member.properties, member_en.properties, member_ko.properties)

   > member_ko.properties에 키/값 쌍으로 회원 정보를 한글로 작성한 후 저장(작성과 동시에 아스키코드로 변환됨)

member.properties ex)

<!-- member_ko.properties -->
mem.name=\uD64D\uAE38\uB3D9
mem.address=\uC11C\uC6B8\uC2DC \uAC15\uB0A8\uAD6C
mem.job= \uD68C\uACC4\uC0AC

<!-- member_us.properties -->
mem.name = hong-kil-dong
mem.address = kang-nam gu, seoul
mem.job = account

3. JSP 페이지에 다국어 표시하기

ex)

<fmt:setLocale value="en_US"/>  <!-- locale을 영어로 지정 -->
 <%--<fmt:setLocale value="ko_KR"/>--%>  		
 <!-- locale을 한글로 지정, 둘 중 하나를 택하면 됨 -->
 <%--주석 시에 스크립트릿을 사용해야한다!!!ㅠ --%>
 <h1>회원정보<br><br>
 <fmt:bundle basename="resource.member" >  
  이름:<fmt:message key="mem.name" /><br>
  주소:<fmt:message key="mem.address" /><br>
  직업:<fmt:message key="mem.job" />
</fmt:bundle>
</h1>

 

 

14.10 포매팅 태그 라이브러리 사용하기

- 원하는 형태로 숫자, 날짜, 문자열을 표시 가능

- 역시 <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> 를 선언해야 함

- 포매팅 라이브러리 종류

분류  태그  설명 
포매팅  <fmt:timeZone>  둘 다 지정한 국가의 시간을 지정하는 태그.
그러나 <fmt:timeZone> 태그의 경우 태그를 열고 닫는 영역 안에서만 적용된다는 차이점을 가지고 있다.
<fmt:setTimeZone> 
<fmt:formatNumber>  표시할 숫자의 형식을 지정 
<fmt:formatDate>  지정한 형식의 날짜를 표시 

 

<formatNumber> 태그의 여러가지 속성

속성  설명 
value  출력될 숫자를 지정 
type  출력된 타입을 지정.
percent인 경우 %, number인 경우 숫자, currency인 경우 통화 형식으로 출력 
dateStyle  날짜의 출력 형식을 지정
DateFormat 클래스의 full, long, medium, short 등이 지정되어 있음 
groupingUsed  콤마(,)등 기호로 구분 여부를 지정 
이 속성이 true이면 50000이 50,000으로 표시됨
기본값은 true
currencyCode  통화 코드를 지정
한국 원화는 KRW 
currentSimbol  통화를 표시할 때 사용할 기호를 표시 
var  <formatNumber>태그 결과를 저장할 변수의 이름을 지정 
scope  변수의 접근 범위를 지정 
pattern  숫자가 출력될 양식을 지정
자바의 DecimalFormat 클래스에 정의된 형식을 따름 

 

 

- < formatDate> 태그의 여러 속성

속성  설명 
value  포맷될 날짜를 지정 (ex. value=<%=new Date()%>
type  포매팅할 타입을 지정
date인 경우 날짜만, time인 경우 시간만, both인 경우 모두 지정 
dateStyle /
timeStyle
날짜 / 시간의 출력 형식을 지정
DateFormat 클래스의 full, long, medium, short 등이 지정되어 있음 
pattern  직접 출력 형식을 지정
자바 클래스 SimpleDateFormat에 지정된 패턴을 사용 (ex. YYYY-MM-dd hh:mm:ss)
timeZone  특정 나라 시간대로 시간을 설정 (ex. <fmt:timeZone value="America/New York">~</fmt: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" %>
<% request.setCharacterEncoding("UTF-8"); %>
...
<body>
 <h2>formatNumber 예제</h2>
 <c:set var="price" value="100000000"/>
 <fmt:formatNumber value="${price }" type="number" var="priceNumber"/>
 통화로 표현 시: <fmt:formatNumber value="${price }" type="currency" currencySymbol="₩" groupingUsed="true"/><br> <%--통화 표시 특수문자에서 찾아서 해야 함.. --%>
 퍼센트로 표현 시 : <fmt:formatNumber value="${price }" type="percent" groupingUsed="false"/><br>
 일반 숫자로 표현 시 :  "${priceNumber }"<br> 
 <%--일반 변수로 담았으므로 fmt사용하는게 아니라 바로 표현언어로 변수 값 출력 --%>
 
 <h2>formatDate 예제</h2>
 <c:set var="now" value="<%=new Date() %>"/> <%--import java.util.Date해야 함, 한국시간 생성 --%>
 <fmt:formatDate value="${now }" type="date" dateStyle="full" /><br>
 <fmt:formatDate value="${now }" type="date" dateStyle="short" /><br>
 <fmt:formatDate value="${now }" type="time"/><br>
  <fmt:formatDate value="${now }" type="both" dateStyle="full" timeStyle="full" /><br>
   <fmt:formatDate value="${now }" pattern="YY-MM-DD hh:mm:ss"/><br>
   
  <br><br>
  한국 현재 시간:
 <fmt:formatDate value="${now }" type="both" timeStyle="full" dateStyle="full"/><br><br>
 <fmt:timeZone value="America/New York"> <%-- 표준시간 설정 --%>
  뉴욕 현재 시간 : <fmt:formatDate value="${now }" type="both" dateStyle="full" timeStyle="full"/><br>
  </fmt:timeZone>
</body>
</html>

 

14.11 문자열 처리 함수 사용하기

- 자바의 문자열 관련 기능을 JSTL에서 제공하는 함수를 이용해서 JSP에서도 사용할 수 있음

- <%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> 필요

- <JSTL에서 제공하는 문자열 함수>

함수  반환  설명 
fn:contains(A,B)  boolean  문자열 A에 문자열 B가 포함되어 있는지 확인 
fn:endWith(A,B)  boolean  문자열 A의 끝이 B로 끝나는지 확인 
fn:indexOf(A,B)  int  문자열 A에서 B가 처음으로 위치하는 인덱스를 반환 
fn:length(A)  int  문자열 A의 전체 길이를 반환 
fn:replace(A,B,C)  String  문자열 A에서 B에 해당되는 문자를 찾아 C로 변환 
fn:toLowerCase(A)  String  A를 모두 소문자로 변환 
fn:toUpperCase(A)  String  A를 모두 대문자로 변환 
fn::substring(A,B,C)  String  A에서 인덱스 번호 B에서 C 앞까지 해당하는 문자열을 반환 
fn:split(A,B)  String[]  A에서 B에서 지정한 문자열로 나누어 배열로 반환 
fn:trim(A)  String  문자열 A에서 앞뒤 공백을 제거 

 

ex)

<%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
...
<c:set var="title1" value="hello world!" />
	<c:set var="title2" value="쇼핑몰 중심 JSP입니다!" />
	<c:set  var="str1" value="중심" />
	<h2>여러 가지 문자열 함수 기능</h2>
	title1="hello world!"<br>
	title2="쇼핑몰 중심 JSP 입니다!"<br>
	str1="중심"<br><br>

	${fn:length(title1) }<br> //12
	${fn:toUpperCase(title1)}<br> //HELLO WORLD!
	${fn:toLowerCase(title1)}<br><br> //hello world!
	
	${fn:substring(title1,3,6)}<br> //lo 
	${fn:trim(title1)}<br> 
	${fn:replace(title1," ","/")}<br><br> //hello/world!
	
	${fn:indexOf(title2,str1) }<br> //4
	${fn:contains(title1,str1) }<br> //false
	${fn:contains(title2,str1) } //true

 

 

14.12 표현 언어와 JSTL을 이용한 회원 관리 실습

- db와 연동하고 표현언어와 JSTL로 값을 가져오기

- test06/memberList

   <c:choose>
   	<c:when test="${membersList==null }"> <%--바인딩된 속성 이름으로 바로 가져오기 --%>
	   	 <tr>
	    <td colspan=5>
	      <b>등록된 회원이 없습니다.</b>
	    </td>  
	  </tr>
	 </c:when>
    <c:otherwise>
     <c:forEach var="mem" items="${membersList }">
     <tr align="center">
     	<td>${mem.id}</td>
        <td>${mem.pwd}</td>
	     <td>${mem.name}</td>     
	     <td>${mem.email}</td>     
	     <td>${mem.joinDate}</td>     
   	</tr>

 

 

 

(기타) OracleServiceXE가 수동으로 시작하는 것으로 설정됐으므로 컴퓨터 재부팅 후에는 직접 시작해줘야 한다