(책) 자바 웹을 다루는 기술

Chap 14 표현 언어와 JSTL -2

EunaSon 2023. 8. 29. 11:50

14.4 커스텀 태그

544p

액션태그나 표현언어를 사용하더라도 조건식이나 반복문에서는 여전히 자바 코드를 사용하고 있음

이러한 자바코드를 제거하기 위해 JSTL이나 커스텀 태그가 등장함

커스텀태그 : JSP 페이지에서 자주 사용하는 자바코드를 대체하기 위해 만든 태그

 

커스텀 태그의 종류

-JSTL(JSP Standard Tag Library) : jsp 페이지에서 가장 많이 사용하는 기능을 태그로 제공함. jstl 라이브러리를 따로 설치해서 사용해야함

-개발자가 만든 커스텀 태그 : 개발자가 필요에 의해 만든 태그. 스트러츠나 스프링 프레임워크에서는 프레임워크 기능과 편리하게 연동할 수 있도록 미리 태그를 만들어서 제공하기도 함

 

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

545p

jstl이란 커스텀 태그 중 가장 많이 사용되는 태그를 표준화하여 라이브러리로 제공하는 것을 말함

 

▼여러가지 JSTL 태그 종류

라이브러리 세부 기능 접두어 관련 URI
코어 변수 지원, 흐름제어, 반복문 처리, URL 처리 c http://java.sun.com/jsp/jstl/core
국제화 지역, 메세지 형식, 숫자 및 날짜 형식 fmt http://java.sun.com/jsp/jstl/fmt
XML XML 코어, 흐름제어, XML 변환 x http://java.sun.com/jsp/jstl/xml
데이터베이스 SQL sql http://java.sun.com/jsp/jstl/sql
함수 컬렉션 처리, 문자열 처리 fn http://java.sun.com/jsp/jstl/functions

 

jstl은 jsp 2.0부터 추가된 기능이므로 현재 톰캣에서 기본 제공되지 않음

아래 링크에서 라이브러리 다운로드 해 설치해야 함

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

-> 접속 후 4개의 jar 파일을 각각 다운로드 함(Imle, Spec, EL, Compat)

-> 다운밭은 파일을 복사해 프로젝트의 lib 폴더에 붙여넣음으로써 jstl 사용에 필요한 라이브러리를 설정함

 

14.6 Core 태그 라이브러리

코어 라이브러리를 사용하면 변수선언, 조건식, 반복문 등의 자바 기능도 태그로 대체할 수 있음

톰캣은 jstl 라이브러리를 기본제공하지 않으므로 외부 라이브러리에서 가져와 기능 수행함

=> 자바의 import문처럼, 코어 태그 라이브러리를 사용하기 위해선 반드시 jsp 페이지 상단에 다음과 같이 taglib 디렉티브 태그를 추가해서 톰캣에게 알려줘야함

 

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

 

*** 399p 디렉티브 태그는 jsp 페이지의 전반적인 정보를 설정할 때 사용함

page 디렉티브 태그, include 디렉티브 태그, taglib 디렉티브 태그가 있음

 

Core 태그 라이브러리의 기능을 수행하는 태그의 종류와 각 기능에 대해 알아보자

▼Core 태그 라이브러리 기능

기능 태그 설명
변수 지원 <c:set> jsp 페이지에서 변수를 지정함
<c:remove> 지정된 변수를 제거함
흐름 제어 <c:if> 조건문 사용
<c:choose> switch문을 사용함
<c:when>과 <c:otherwise> 서브 태그를 가짐
<c:forEach> 반복문 사용
<c:forTokens> 구분자로 분리된 각각의 토큰을 처리할 때 사용함
URL 처리 <c:import> URL을 이용해 다른 자원을 jsp 페이지에 추가함
<c:redirect> response.sendRedirect() 기능을 수행함
<c:url> 요청 매개변수로부터 URL을 생성함
기타 태그 <c:catch> 예외 처리에 사용함
<c:out> JspWriter에 내용을 처리한 후 출력함

 

<c:set> 태그를 이용한 실습

548p

<c:set> 태그를 이용하면 변수 선언을 대체할 수 있음

형식

<c:set var="변수명" value="변수값" [scope="page/request/session/application 중 하나"] />

var에 변수 이름, value에 변수에 저장할 값, scope에 변수 스코프를 지정함

 

- <c:set>으로 변수를 선언 후 출력해보자

[ member1.jsp ]

상단에 taglib 디렉티브 태그를 선언,

<c:set> 태그를 이용해 회원정보를 저장하는 변수를 선언한 후 값을 초기화함, 이때 <c:set>의 value 속성은 표현언어( ${ } )로 값을 설정할 수 있음,

출력할 때는 표현언어에서 변수 이름을 이용하자

 

...

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

// core 태그 라이브러리를 사용하기 위해 반드시 선언해야함

 

...

// <c:set> 태그를 이용해 변수를 선언함

<c:set var="id" value="hong" scope="page" />

<c:set var="pwd" value="1234" scope="page" />

<c:set var="name" value="${ '홍길동' }" scope="page" /> // value 속성에 표현언어 써서 초기화할 수도 있음

<c:set var="age" value="${ 22 }" scope="page" />

<c:set var="height" value="${ 177 }" scope="page" />

...

<td>${ id }</td>

... // 표현언어로 변수 이름 사용해 변수값 출력할 수 있음

 

- <c:set> 태그를 이용해 너무 긴 변수나 속성 이름을 간결하게 만들어보자

예) <a> 태그를 이용해 다른 페이지로 이동할 때 표현언어로 pageContext.request.contextPath 와 같은 긴 속성을 그대로 사용했는데, 이를 미리 <c:set> 태그를 이용해 해당 속성 이름을 contextPath로 줄여서 사용할 수 있음


*** <a> 태그를 이용해 다른 서블릿이나 jsp로 요청하는 방법

525p

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"


[ login.jsp ]

...

<c:set var="contextPath" value="${ pageContext.request.contextPath}" />

...

<a href="${ contextPath }/test03/memberForm.jsp">회원가입하기</a>

 

=>

<a href="${ pageContext.request.contextPath}/test03/memberForm.jsp"

-> <a href="${ contextPath }/test03/memberForm.jsp"> 로 간단히 출여서 사용 가능

 

- <c:set> 태그를 이용해 바인딩 된 속성의 긴 이름을 길이가 짧은 변수로 대체해서 사용해보자

membersMap 이라는 HashMap에 저장된 ArrayList인 membersList의 요소를 꺼내 속성을 가져오려면

${ membersMap.membersList[0].id } 로 사용해야 했음, 불편하고 가독성이 떨어짐

=> <c:set>을 이용해 미리 ${ membersMap.membersList } 를 "membersList"로 설정 

 

<c:set var="membersList" value="${ membersMap.membersList }" />

...

<td>${ membersList[0].id }</td> // <c:set> 태그로 설정한 변수이름으로 접근하여 출력함

...

 

<c:remove> 태그를 이용한 실습

<c:remove> 태그를 이용해 선언한 변수를 제거할 수 있음

 

형식

<c:remove var="변수이름" [scope="scope 속성 중 하나"]  />

 

[ member3.jsp ]

<c:remove> 태그를 이용해 <c:set>으로 선언한 변수를 삭제함

 

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> // core 태그라이브러리 사용 전 설정해줘야함

...

<c:set var="age" value="${ 22 }"/>

<c:remove var="age" />

=> ${ age }로 출력해도 age의 값(22)이 출력되지 않음

 

 

<c:if> 태그를 이용한 실습

554p

<c:if> 태그는 jsp 페이지에서 조건물을 대신하는 태그

 

조건

<c:if test="${ 조건식 }"  var="변수이름"  [scope="scope 속성 중 하나"] >

... // 조건식이 참이면 수행할 코드

</c:if>

test : 수행할 조건식 위치를 표현언어로 저장

var : 조건식의 결과값을 저장

scope : 변수의 스코프를 지정(page, request, session, application 중 하나)

 

[ member4.jsp ]

<c:if> 태그의 test 속성에는 표현언어 안에 비교연산자나 논리연산자 등으로 조건식을 써주고, 이를 수행하여 참이면 <c:if> ~ </c:if> 사이의 코드를 실행함

 

<c:if test="${ true }"> // test에 표현언어로 쓴 조건식이 항상 참(true)임

<c:if test="${ 11 == 11 }"> // 조건식에 비교연산자 (==, !=, <, >, <=, >= 등)를 사용할 수 있음

<c:if test="${ (id == 'hong') && (name == '홍길동') }"> // 조건식에 논리연산자(&&, || 등)를 사용할 수 있음

 

 

<c:choose> 태그를 이용한 실습

556p

jsp 페이지에서 switch문의 기능을 수행함

 

<c:choose> // = switch

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

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

  ...

  <c:otherwise>본문내용n</c:otherwise>  // = default문

</c:choose>

 

따로 break문 없어도 조건에 맞는 내용만 찾아서 수행함

즉, <c:when> ~ <c:otherwise>가 아무리 많아도 위에서부터 조건식이 true인 딱 하나만 수행함

true인 조건식을 찾아서 수행했으면 <c:choose>문을 빠져나옴 

 

[ member5.jsp ]

<c:choose>

  <c:when test="${ empty name }">  // 변수 name이 null 또는 빈문자열인지 체크

    ...

  </c:when>

  <c:otherwise> // name이 정상적이면 아래 내용을 출력함

    ...

 </c:otherwise>

</c:choose>

 

<c:forEach> 태그를 이용한 실습

jsp 페이지에서 반복문을 수행하는 태그

 

형식

<c:forEach var="변수이름" items="반복할객체이름" begin="시작값" end="마지막값"

                   step="증가값" varStatus="반복상태변수이름">

...

</c:forEach>

var : 반복할 변수 이름

items : 반복할 객체 이름

begin과 end : 반복 시작값, 종료값

step : 한 번 반복할 때마다 반복 변수를 증가시킬 값

varStatus : 반복 상태 속성

▼varStatus의 속성

속성 설명
index int items에서 정의한 항목을 가리키는 index 번호. 0부터 시작함.
count int 몇 번째 반복인지 나타냄. 1부터 시작함.
first boolean 첫 번째 반복인지 나타냄
last boolean 마지막 반복인지 나타냄

varStatus="status"

-> ${ status.index} 등과 같이 사용함

 

 

[ member6.jsp ]

자바 코드로 ArrayList 객체를 만들어 문자열을 저장한 후 <c:forEach> 태그에서 사용할 수 있도록 <c:set>태그로 변수 list에 재할당함, varStatus의 loop 속성을 이용해 반복 횟수를 출력함

 

...

<%

  List dataList = new ArrayList();

  dataList.add("hello");

  dataList.add("world");

  dataList.add("안녕하세요");

%> // ArrayList 생성해서 문자열을 3개 저장함

 

<c:set var="list" value="<%=dataList %>" />  // dataList를 변수 list에 할당함

...

<c:forEach var="i" begin="1" end="10" step="1" varStatus="loop"> // for (int i=1; i<=10; i++)

  i= ${ i } 반복횟수 : ${ loop.count } // 해당 반복회차의 i값과 반복회차를 출력함

</c:forEach>

 

<c:forEach var="data" items="${ list }" > // list(dataList)에 저장된 값을 하나씩 가져와서 변수 data에 대입함

  ${ data }

</c:forEach>


*** member6.jsp 중 &nbsp 에 대하여

567p 참고

<, >, ' , " 등의 특수문자들은 HTML 태그에도 사용되므로 이 특수문자들을 브라우저에 출력하기 위해서는 각각의 특수문자에 지정된 문자를 이용해야함. 

&nbsp; : html에서 사용되는 특수문자 중 하나, 공백을 의미함

&amp; : ampersand, &을 의미함

&quot : double quotes, " 를 의미함

등등...

 

▼escapeXml이 false일 때 변환되는 문자(567p)

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

 출처 https://sensechef.com/957


 

<c:set var="fruits" value="사과, 파인애플, 바나나, 망고, 귤" />

<c:forTokens var="token" items="fruits" delims="," >

// delims : 구분기호,

// 구분기호를 기준으로 items를 토막내서 첫번째 토막부터 하나씩 var에 대입함

  ${ token } // 사과 파인애플 바나나 망고 귤 이 하나씩 출력됨

</c:forTokens>

 

[ member7.jsp ]

<c:forEach> 태그의 반복변수 i를 ArrayList의 인덱스로 사용해서 저장된 회원정보를 차례대로 출력해보자

 

MemberBean m1, m2, m3를 생성후 ArrayList인 membersList에 add()로 추가함,

<c:set>으로 ArrayList인 membersList를 변수 membersList에 할당,

 

<c:forEach var="i" begin="0" end="2" step="1" >

<tr> // 테이블의 한 행 시작

  <td>${ membersList[i].id }</td>

  <td>${ membersList[i].pwd }</td>

  ... // membersList에서 첫번째 요소부터 하나씩 꺼내와 해당 요소의 속성값을 출력함

</tr> 첫번째 요소를 모두 출력하면 한 행이 끝남

</c:forEach>

 

[ member8.jsp ]

이번에는 membersList를 items에 할당하여 자동으로 var에 membersList의 요소인 MemberBean 객체가 차례로 할당되도록 함

 

<c:forEach var="member" items="${ membersList }" >

<tr align="center">

  <td>${ member.id }</td> // var인 member에 membersList의 요소인 MemberBean 객체가 대입되어 속성(id)을 가져옴

  <td>${ member.pwd }</td>

  ...

</tr>

</c:forEach>

 

<c:url> 태그를 이용한 실습

562p

jsp 페이지에서 URL 정보를 저장하는 역할을 함

 

형식

<c:url var="변수이름" value="URL경로" [scope="scope 속성 중 하나"]

          [ <c:param name="매개변수이름" value="전달값" />]

          ...

</c:url>

var : 생성된 URL이 저장될 변수

value : 생성할 URL

scope : scope 속성의 값(page/request/session/application)

 

[ urlTest.jsp ]

<c:url> 태그를 이용하여 다른 페이지로 이동하면서 데이터를 전달함.

이동할 페이지로 전달할 데이터가 많을 경우에 사용하면 편리함.

 

<%@ taglib ~~~ %> // core 태그라이브러리 추가

<c:set var="contextPath" value="${pageContext.request.contextPath}" /> // 컨텍스트 이름 가져오는 변수 설정

<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@tset.com" />  // 이동할 페이지로 전달할 데이터를 설정함

</c:url>

...

<a href="${ url1 }">회원정보출력</a> //<c:url>에서 설정한 변수이름으로 이동할 jsp 페이지 간단히 설정

*** member1.jsp (537p) : 넘겨받은 회원정보 두가지 방식(getAttribute() / ${ } )으로 출력

 

 

<c:redirect> 태그를 이용한 실습

564p

지정된 jsp 페이지로 리다이렉트 할 때 사용함

response.sendRedirect() 기능과 동일함

리다이렉트 시 <c:param> 태그를 이용해 매개변수를 전달할 수도 있음

  

형식

<c:redirect url="redirect할 URL">

  [ <c:param name="매개변수 이름" value="전달할 값"  /> ]

  ...

</c:redirect>

url : 리다이렉트 될 URL이 저장되는 변수

 

[ redirectTest.jsp ]

...

<body>

  <c:redirect url="/test01/member1.jsp" >  // 리다이렉트할 페이지를 설정

    <c:param name="id"="${ hong }" />

    ... // 리다이렉트할 페이지로 전달할 매개변수를 설정

  </c:redirect>

</body>

 

<c:out> 태그를 이용한 실습

565p

화면에 지정한 값을 출력해주는 태그

표현언어 ${ }와 기능은 거의 동일, but 기본값설정 기능 등을 제공하여 더 편리함

 

형식

<c:out value="출력값" default="기본값" [excaoeXml="boolean값(true/false)"] />

value : 출력할 값

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

escapeXml : escape문자를 변환하는 역할(기본값은 true, 생략가능)

 

[ memberForm.jsp ]

회원가입창. 정보를 입력받아 member9.jsp로 전달함(form태그, action 속성 이용)

 

[ member9.jsp ]

...

<c:choose>

  <c:when test="${ empty param.id }"> //getParameter() 대신 param 내장객체 이용해 id 가져옴, id가 제대로 입력안됐으면
    <tr align="center">
      <td colspan=5>아이디를 입력하세요</td>

    </tr>

  </c:when>

  <c:otherwise> // id가 제대로 입력됐으면

    <tr align="center">

      <td><c:out value="${ param.id }" /></td>

      ... // <c:out> 태그와 param 내장객체로 입력받은 값들 출력

    </tr>

  </c:otherwise>

</c:choose>

...

 

*** escapeXml이 false일때 변환되는 문자

특수문자를 브라우저에 출력하고 싶을 때 html 태그로 인식되지 않게 하려면 지정된 문자를 이용해야함

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

[ escapeXml.jsp ]

특수문자 사용 예제

<c:out> 태그의 escapeXml 속성을 이용하여 문자를 특수문자로 변환함

 

<c:out value="&lt;" escapeXml="true" /> // escapeXml 속성이 true이면 화면에 "&lt;" 가 그대로 출력됨

<c:out value="&lt;" escapeXml="false" /> // escapeXml 속성이 false이면 화면에 변환된 특수기호 "<" 가 출력됨

 

<c:import> 태그

569p

<jsp:include>와 같은 기능을 수행함