Back-end/JSP

[JSP] EL JSTL

peridott 2024. 8. 2. 16:17
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.util.*, com.tjoeun.vo.*" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>JSTL Core Library</h1>
	
	<h3>1. 변수(속성==attribute)</h3>
	
	<h4>1.1 변수 선언과 초기화</h4>
	
	<pre>
	* 변수 선언과 동시에 초기화 (c:set var="" value="" [scope=""])
	  - 변수를 선언하고 초기값을 대입해두는 기능을 제공
	  - 해당 변수를 어떤 scope에 담아둘건지 지정가능(생략시 기본값은 pageScope에 담김)
	    => 해당 scope에 setAttribute를 통해 key-value형태로 데이터를 담아 놓는것이라고 생각하면 됨
	    => c:set으로 선언된 변수는 EL로 접근하여 사용가능
	    
	  - 변수 타입을 별도로 지정하지 않음
	  - **초기값은 반드시 지정해줘야 함!!!!  
	</pre>

	<c:set var="num1" value="10" />					<!-- pageContext.setAttribute("num1","10") -->
	<c:set var="num2" value="20" scope="request" /> <!-- request.setAttribute("num2","20") -->
	
	num1 변수값 : ${ num1 }<br>
	num2 변수값 : ${ num2 }<br><br>
	
	<%-- <c:set var="result" value="num1+num2" />  String문자열이 됨 --%>
	<c:set var="result"  value="${num1 + num2}"  scope="session"/>
	result 변수값 : ${ result }<br><br>
	
	pageScope.num1 : ${pageScope.num1}<br>
	requestScope.num2 : ${requestScope.num2}<br>
	sessionScope.result : ${sessionScope.result}<br>
	requestScope.result : ${requestScope.result}<br><br>
	
	
	<!-- value속성 대신에 시작태그와 종료태그 사이에 초기값 지정 가능 -->
	<c:set var="result" scope="request">
		77777
	</c:set>
	
	requestScope.result : ${requestScope.result}<br><br>
	
	<hr>
	
	<h4>1.2 변수 삭제</h4>

	<pre>
	* 변수 삭제 : (c:remove var="삭제하고자하는 변수명" [scope=""])
	  - 해당 scope영역에서 해당 변수를 찾아서 제거하는 태그
	  - scope 지정 생략시 모든 scope에서 해당 변수를 다 찾아서 제거함	
	    => 해당 scope에 .removeAttribute를 통해 삭제와 동일
	</pre>
	
	삭제전 result : ${result}<br><br>
	 
	1) 특정 scope지정하여 삭제<br>
	<c:remove var="result" scope="request" />
	삭제후 result : ${result}<br><br>
	 
	2) 모든 scope에서 삭제<br>
	<c:remove var="result" />
	모두 삭제후 result : ${result}<br><br>
	
	<hr>
	
	<h4>1.3. 변수 출력</h4>
	
	<pre>
	* 데이터를 출력하고자 할 때 사용하는 태그
	  - (c:out value="출력하고자하는 값" [default="기본값"] [escapeXml="true|false"])
	</pre>
	
	<c:out value="${ num1 }" /><br>
	<c:out value="${ abcd }" default="없음" /><br><br>
	
	<c:set var="outTest" value="<b>출력테스트</b>" />
	
	<c:out value="${outTest}" /><br><!-- escapeXml생략시 기본값은 true == 태그로 해석하지 않음(문자열로 취금) -->
	<c:out value="${outTest}" escapeXml="false" /><br><br>

	<hr>
	
	<h3>2. 조건문 - if</h3>
	<pre>
	* (c:if test="조건식")
	  - java의 if문과 비슷한 역할을 하는 구문
	  - 조건식은 test속성에 작성(단, EL구문으로 기술해야 됨)
	</pre>
	
	<c:if test="${ num1 < num2 }" >
		<b>num1이 num2보다 작다</b>
	</c:if>
	
	<c:if test="${ num1 >= num2 }">
		<b>num1이 num2보다 크거나 같다</b>
	</c:if>
	<br>
	
	<c:set var="str" value="안녕하세요" />
	
	<c:if test="${ str eq '안녕하세요' }">
		<b>Hello 안녕</b>
	</c:if>
	
	<c:if test="${ str ne '안녕하세요' }">
		<b>Bye 안녕</b>
	</c:if>
	
	<hr>
	
	<h3>3. choose</h3>
	<pre>
	* (c:choose, c:when, c:otherwise)
	  - java의 if-else 와 비슷한 역할을 하는 태그
	  - 각 조건들을 c:choose의 하위요소로 c:when을 통해서 작성(else문의 역할은 c:otherwise)
	</pre>
	
<%-- 
	<% if(num1 > 20) { %>
	
	<% } else if(num1 >= 10) { %>
	
	<% } else { %>
	
	<% } %>
--%>

	<c:choose>
		<c:when test="${ num1 gt 20 }">
			<b>20보다 큰값</b>
		</c:when>
		<c:when test="${ num1 ge 10 }">
			<b>10보다 크고 20보다 작은값</b>
		</c:when>
		<c:otherwise>
			<b>10보다 작은값</b>
		</c:otherwise>
	</c:choose>
	
	<hr>
	
	<h3>4. 반복문</h3>
	<pre>
	* for loop문 - (c:forEach var="변수명" begin="초기값" end="끝값" [step="증가값"])
	* 향상된 for문 - (c:forEach var="변수명" items="순자적으로접근하고자하는객체(배열|컬렉션)" [varStatus="현재접근된요소의 상태값을 보관할 변수명"])
	</pre>
	
	<c:forEach var="i" begin="1" end="10" step="2">
		반복확인 : ${i}<br>
	</c:forEach>
	
	<c:forEach var="i" begin="1" end="6">
		<h${i}>태그안에서도 적용가능</h${i}>
	</c:forEach>
	
	<c:set var="colors">
		red,yellow,green,pink
	</c:set>
	
	colors 변수값 : ${colors}<br>
	
	<ul>
		<c:forEach var="c" items="${colors}">
			<li style="color:${c}">${c}</li>
		</c:forEach>
	</ul>
	
	<%
		ArrayList<Person> list = new ArrayList<Person>();
		list.add(new Person("이고잉",25,"여자"));
		list.add(new Person("이순재",35,"남자"));
		list.add(new Person("송미영",22,"여자"));
	%>
	
	<c:set var="plist" value="<%=list %>" scope="request" />
<%-- 	1. 기본 for문 사용
	<table border="1">
		<thead>
			<tr>
				<th>이름</th>
				<th>나이</th>
				<th>성별</th>
			</tr>
		</thead>
		<tbody>
			<c:choose>
				<c:when test="${ empty plist }">
					<tr>
						<td colspan="3">조회된 사람이 없습니다</td>
					</tr>
				</c:when>
				<c:otherwise>
					<c:forEach var="p" items="${plist}">
						<tr>
							<td>${p.name}</td>
							<td>${p.age}</td>
							<td>${p.gender}</td>
						</tr>
					</c:forEach>
				</c:otherwise>
			</c:choose>
		</tbody>
	</table>			
--%>	

<%-- 2. 속성추가 forEach 사용  --%>
	<table border="1">
		<thead>
			<tr>
				<th>index번호</th>
				<th>count번호</th>
				<th>이름</th>
				<th>나이</th>
				<th>성별</th>
			</tr>
		</thead>
		<tbody>
			<c:choose>
				<c:when test="${ empty plist }">
					<tr>
						<td colspan="5">조회된 사람이 없습니다</td>
					</tr>
				</c:when>
				<c:otherwise>
					<c:forEach var="p" items="${plist}" varStatus="status">
						<tr>
							<td>${status.index}</td> <!-- index 속성 : 0부터 시작 -->
							<td>${status.count}</td> <!-- count 속성 : 1부터 시작 -->
							<td>${p.name}</td>
							<td>${p.age}</td>
							<td>${p.gender}</td>
						</tr>
					</c:forEach>
				</c:otherwise>
			</c:choose>
		</tbody>
	</table>			

	<hr>
	
	<h3>5. 반복문 : forTokens</h3>
	<pre>
	* (c:forTokens var="변수명" items="분리시키고자하는 문자열" delims="구분자")
	  - 구분자를 통해서 분리된 각각의 문자열을 순차적으로 접근하면서 반복 수행
	  - java의 split("구분자") 또는 StringTonkenizer와 비슷한 기능
	</pre>
	
	<c:set var="device" value="컴퓨터,핸드폰,TV,에어컨/냉장고.세탁기" />
	
	<ol>
		<c:forTokens var="d" items="${device}" delims=",./">
			<li>${d}</li>
		</c:forTokens>
	</ol>
	
	<hr>
	
	<h3>6. url, 쿼리스트링 관련</h3>
	<pre>
	* url 경로를 생성하고, 쿼리스트링을 정의 둘수 있는 태그
	
	&lt;c:url var="변수명" value="요청할 url"&gt;
		&lt;c:param name="키" value="전달할 값" /&gt;
		&lt;c:param name="키" value="전달할 값" /&gt;
	&lt;/c:url&gt;
	</pre>
	
	<a href="list.bo?nowpage=2&num=3">기존방식</a><br><br>
	
	<c:url var="u" value="list.bo">
		<c:param name="nowpage" value="2" />
		<c:param name="num" value="3" />
	</c:url>
	<a href="${u}">c:url을 이용한 방식</a>
	
</body>
</html>

 

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

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>1. formatNumber</h1>
	<p>
	* 숫자 데이터의 포맷(형식) 지정<br>
	  - 표현하고자하는 숫자 데이터의 형식을 통화기호, % 등 원하는 쓰임에 맞게 형식을 지정하는 태그<br>
	  (fmt:formatNumber value="출력할 값" [groupingUsed="true|false" type="percent|currency" currencySymbol="통화기호문자"])
	    => groupingUsed : 세자리마다 구분자(,) 표시 여부 (기본값 true = 세자리마다 구분자 표시)
		=> type : percent = %로 출력
		          currency = 현재 local지역의 화폐 표시 여부
		=> currencySymbol : 화폐단위를 넣어 줄 때          	    	
	</p>
	
	<c:set var="num1" value="123456789"/>
	<c:set var="num2" value="0.75" />
	<c:set var="num3" value="50000" />
	
	그냥 출력 : ${num1}<br>
	세자리마다 구분하여 출력 : <fmt:formatNumber value="${num1}" /><br>
	숫자 그대로 출력 : <fmt:formatNumber value="${num1}" groupingUsed="false"/><br><br>
	
	percent : <fmt:formatNumber value="${num2}" type="percent" /><br>
	currency : <fmt:formatNumber value="${num3}" type="currency" groupingUsed="false"/><br>
	currency $ : <fmt:formatNumber value="${num3}" type="currency" currencySymbol="$" /><br><br>
	
	<hr>
	
	<h3>2. formatDate</h3>
	<p>날짜와 시간 데이터의 포맷 지정(java.util.Date 객체 사용)</p>
	
	<c:set var="cDate" value="<%= new java.util.Date() %>" />
	그냥 출력 : ${ cDate }<br>
	
	<ul>
		<li>현재 날짜 : <fmt:formatDate value="${cDate}" /></li><!-- type 생략시 기본값 : date -->
		<li>현재 시간 : <fmt:formatDate value="${cDate}" type="time" /></li>
		<li>현재 날짜와 시간 : <fmt:formatDate value="${cDate}" type="both" /></li>
		<li>Medium : <fmt:formatDate value="${cDate}" type="both" dateStyle="medium" timeStyle="medium"/></li>
		<li>Long: <fmt:formatDate value="${cDate}" type="both" dateStyle="long" timeStyle="long"/></li>
		<li>Full: <fmt:formatDate value="${cDate}" type="both" dateStyle="full" timeStyle="full"/></li>
		<li>Short: <fmt:formatDate value="${cDate}" type="both" dateStyle="short" timeStyle="short"/></li>
		<li>내패턴 : <fmt:formatDate value="${cDate}" type="both" pattern="yyyy-MM-dd(E) hh:mm:ss(a)"/> </li>
	</ul>
</body>
</html>

 

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>JSTL Function Library</h1>
	
	<c:set var="str" value="How are you?" />
	
	str : ${ str }<br><br>
	
	문자열의 길이 : ${ str.length() }<br>
	문자열의 길이 : ${ fn:length(str) } <br><br> <!-- ArrayList도 사용가능 함 -->
	
	모두 대문자로 출력 : ${ fn:toUpperCase(str) } <br>
	모두 소문자로 출력 : ${ fn:toLowerCase(str) }<br><br>
	
	are의 시작 인덱스 번호 : ${ fn:indexOf(str, 'are') }<br><br>
	
	are를 were로 변경 : ${ fn:replace(str, 'are', 'were') }<br><!-- 원본은 바뀌지 않음 -->	
	str : ${ str }<br><br>
	
	<c:if test="${ fn:contains(str, 'are') }" >
		str에 are가 들어있음
	</c:if>
	
</body>
</html>

 

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>JSTL이란?</h1>
	<p>
		JSP Standard Tag Library의 약자로 jsp에서 사용되는 커스텀 액션태그<br>
		공통적으로 자주 사용되는 코드들을 집합하여 보다 쉽게 사용할 수 있도록 태그화해서 표준으로 제공하는 라이브러리<br>
		필요한 라이브러리를 추가한 후 사용가능
	</p>
	
	<h2>* JSTL 선언 방법</h2>
	<p>
		JSTL을 사용하고자 하는 해당 JSP페이지 상단에 taglib 지시어를 사용하여 선언함<br><br>
		
		&lt;%@ taglib prefix="접두어" uri="라이브러리 파일상의 uri주소" %&gt;
	</p>
	
	<h3>1. JSTL Core Library</h3>
	<p>변수와 조건문, 반복문 등의 로직과 관련된 문법을 제공</p>
	<a href="01.core.jsp">core library</a><br><br>
	
	<h3>2. JSTL Formatting Library</h3>
	<p>숫자, 날짜, 시간 등의 데이의 출력 형식을 지정할 때 사용하는 문법 제공</p>
	<a href="02.fmt.jsp">fmt library</a><br><br>
	
	<h3>3. JSTL Function Library</h3>
	<p>EL안에서 사용할 수 있는 메소드 제공</p>
	<a href="03.fn.jsp">fn library</a><br><br>
</body>
</html>

 

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>EL_JSTL</title>
</head>
<body>
	<h1>* EL(Expression Language)</h1>
	<p>
		기존에 사용했던 표현식(출력문) &lt;%=변수명 %&gt;<br>
		jsp상에서 표현하고자 하는 값을 \${변수명}의 형식으로 표현하여 작성하는 것
	</p>
	
	<h3><a href="el.do">01_EL 구문</a></h3><br>
	<!-- 
		1. src에 패키지 만들기
		   com.tjoeun.controller
		   com.tjoeun.vo
		2. com.tjoeun.vo 패키지 안에 Person 의 bean파일 만들기
		3. com.tjoeun.controller / Elservlet 만들기 : /el.do, doGet()
		4. views/01_EL/01_el.jsp 파일 만들기
	 -->
	 
	 <h3><a href="operation.do">02_EL의 연산자</a></h3>
	 <!--
	 	1. com.tjoeun.controller / OperationServlet 만들기 : /operation.do, doGet()
		2. views/01_EL/02_operation.jsp 파일 만들기
	 -->
	 
	 <h1>* JSP Action Tag</h1>
	 <p>xml 기술을 이용하여 기존의 jsp문법을 확장시키는 기술을 제공하는 태그들</p>
	 <p>표준 액션 태그 : include와 forward</p>
	 
	 <h3>- 커스텀 액션태그</h3>
	 <a href="views/02_customAction/jstl.jsp">JSTL</a>
</body>
</html>

 

 

package com.tjoeun.controller;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;

import java.io.IOException;

import com.tjoeun.vo.Person;

public class ElServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		/*
		 * 데이터를 담을 수 있는 jsp내장 객체의 종류
		 1. ServletContext(Application Scope)
		 	한 애플리케이션당 단 1개만 존재하는 객체
		 	이 영역에 데이터를 담으면 애플리케이션 전역에서 사용가능
		 	공유범위가 가장 큼(jsp / servlet / java)
		 2. HttpSession(Session Scope)
		 	한 브라우저당 1개가 존재하는 객체
		 	이 영역에 데이터를 담으면 jsp / servlet단에서 가용가능
		 	공유범위가 2번째로 큼
		 3. HttpServletRequest(request Scope)
		 	요청 때마다 매번 생성되는 객체
		 	이 영역에 데이터를 담으면 request객체를 포워딩 받는 응답jsp에서만 사용가능
		 	공유범위는 응답jsp
		 4. PageContext(page Scope)
		 	jsp페이지마다 존재하는 객체
		 	공유범위가 가장 작음(해당 페이지 내에서만 사용가능)
		 	
		 위의 4개의 객체들을
		 데이터를 담을 때    .setAttribute("키", 담고자하는 데이터)
		 데이터를 꺼낼 때    .getAttribute("키") => 키에 담겨있는 데이터 반환
		 데이터를 삭제 할 때  .removeAttribute("키")		 
		 */
		
		// requestScope에 담기
		request.setAttribute("classRoom", "801호");
		request.setAttribute("student", new Person("홍길동", 23, "남자"));
		
		// sessionScope에 담기
		HttpSession session = request.getSession();
		session.setAttribute("academy", "tjoeun");
		session.setAttribute("teacher", new Person("김지원", 35, "여자"));
		
		// requestScope와 sessionScope에 동일한 키값으로 데이터 담기
		request.setAttribute("scope", "request");
		session.setAttribute("scope", "session");
		
		// 응답페이지를 지정하여 포워딩 되도록 설정
		request.getRequestDispatcher("views/01_EL/01_el.jsp").forward(request, response);
	}

}

 

 

package com.tjoeun.controller;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;

import com.tjoeun.vo.Person;

public class OperationServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setAttribute("big", 10);
		request.setAttribute("small", 3);
		
		request.setAttribute("sOne", "");
		request.setAttribute("sTwo", "");
		request.setAttribute("sThree", "안녕");
		
		request.setAttribute("pOne", new Person("", 20, ""));
		request.setAttribute("pTwo", null);
		
		ArrayList<String> list1 = new ArrayList<>();
		request.setAttribute("aOne", list1);  // 텅빈 리스트
		
		ArrayList<String> list2 = new ArrayList<>();
		list2.add("배열에 값 넣기");
		request.setAttribute("aTwo", list2);
		
		request.getRequestDispatcher("views/01_EL/02_operation.jsp").forward(request, response);
		
	}

}

 

 

package com.tjoeun.vo;

public class Person {
	private String name;
	private int age;
	private String gender;
	
	public Person() {
	}
	public Person(String name, int age, String gender) {
		super();
		this.name = name;
		this.age = age;
		this.gender = gender;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getGender() {
		return gender;
	}
	public void setGender(String gender) {
		this.gender = gender;
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + ", gender=" + gender + "]";
	}
	
}