JSTL_기본 개념&Core Tag

zooyeong·2023년 5월 31일
0

18주차

목록 보기
1/5
post-thumbnail

📌JSTL이란?

JSTL이란 jsp에서 HTML 코드 내에 java 코드인 스크립틀릿 <%= sample %>을 ${sample}로, <%=if %>문을 <c:if>, <%=for %>문을 <c:forEach> 등으로 대체하여 사용하는 라이브러리다.

즉, 자바코드를 html 태그형식으로 간편하게 사용하기 위해 나온 라이브러리이다.

💡 JSTL 사용법

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

JSTL은 라이브러리이기 때문에 반드시 위 코드를 header에 추가해야 한다. 추가하지 않고 사용하려고 하면

위와 같은 경고창(Unknown tag (c:if))을 확인할 수 있다.

💡JSTL Core Tag

태그명설명
<c:if>조건식에 해당하는 블럭과 사용될 scope 설정
<c:choose>java의 switch와 비슷
<c:when>switch문의 case
<c:otherwise>switch문의 default
<c:forEach>for문(향상된 for문처럼 활용)
<c:set>변수명에 값을 할당
<c:url>url에 자동으로 contextPath를 붙여주는 역할
<c:param>파라미터를 전달(속성-name:파라미터명/value:값)
<c:out>화면에 출력

💡JSTL 사용하기

▶<c:if>

@Controller
public class JstlController {

	@RequestMapping("/jstl1")
	public String jstl1(Model model) {
		
		model.addAttribute("memberType", "admin");
		
		return "jstl1";
	}
}

>>> 컨트롤러

<h1>jstl1</h1>

<c:if test="${memberType == 'admin'}">
	<h2>관리자입니다.</h2>
</c:if>

>>> jsp 파일

↓ 실행결과

▶<c:choose>

@Controller
public class JstlController {

	@RequestMapping("/jstl1")
	public String jstl1(Model model) {
		
		model.addAttribute("type", "morning");
		
		return "jstl1";
	}
}

>>> 컨트롤러

<h1>jstl1</h1>

<c:choose>
	<c:when test="${type=='morning'}">
		
		<p>choose 아침</p>
			
	</c:when>
	<c:when test="${type=='lunch'}">
		
		<p>choose 점심</p>
		
	</c:when>
	<c:otherwise>
    
		<p>아침도 점심도 아니다.</p>
        
	</c:otherwise>
</c:choose>

>>> jsp 파일

↓ 실행결과

▶<c:forEach>

<h1>jstl1</h1>

1~10까지 반복
<c:forEach var="i" begin="1" end="10" step="1">
	<p>${i}</p>
</c:forEach>

>>> jsp 파일

↓ 실행결과

▶<c:forEach> - 향상된 for문처럼 활용!

@Controller
public class JstlController {

	@RequestMapping("/jstl1")
	public String jstl1(Model model) {

		//memberDto 멤버 정보 리스트를 불러왔다~라는 과정이 있다고 가정
		List<MemberDto> memberList = new ArrayList<MemberDto>();
		memberList.add( new MemberDto("firstid", "pww1", "가멤버") );
		memberList.add( new MemberDto("secondid", "pww2", "나멤버") );
		memberList.add( new MemberDto("thirdid", "pww3", "다멤버") );
		
		model.addAttribute("memberList", memberList);
		
		return "jstl1";
	}
}

>>> 컨트롤러

<h1>jstl1</h1>

	<p>멤버 리스트 확인하기</p>
	
	
	<table>
		<thead>
			<tr>
				<td>아이디</td>
				<td>비밀번호</td>
				<td>이름</td>
			</tr>
		</thead>
		
		<tbody>
			<c:forEach var="memberItem" items="${memberList}">
				<tr>
					<td>${memberItem.id}</td>
					<td>${memberItem.pw}</td>
					<td>${memberItem.name}</td>
				</tr>
			</c:forEach>
		</tbody>
	</table>

>>> jsp 파일

↓ 실행결과

▶<c:set>

jstl2.jsp 파일에서 a태그 링크를 누르면 jstl3.jsp 파일로 이동하는 상황을 만들어보겠다.

<h1>jstl2</h1>

<a href="/jstl3">jstl3페이지로 이동</a>

위와 같은 상황이 있다고 가정해본다. 링크를 클릭하게 되면 아래와 같은 오류를 만난다.

>>> 이는 url 경로에 프로젝트명이 따라오지 않았기 때문이다. 요청 url을 받아오기 위해 <c:set>을 사용한다.

<h1>jstl2</h1>

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

<a href="${contextPath}/jstl3>jstl3페이지로 이동</a>

>>> jsp 파일

↓ 실행결과

▶<c:url>

<h1>jstl2</h1>

<c:url var="jstl3url" value="/jstl3">
	<c:param name="data1" value="abc" />
	<c:param name="data2" value="def" />
</c:url>
    
<a href="${jstl3url}">jstl3페이지로 이동 curl</a>
<!-- <c:url> 태그의 var에서 정한 변수명으로 부름 -->

↓ 실행결과

>>> 요청한 url로 이동하고 파라미터 값도 잘 전달되는 것을 확인할 수 있다. 그런데 url에 ;jsessionid= 값이 따라오는 것을 발견했다.
이는 서버에서 클라이언트에 세션을 유지하기 위해 쿠키를 생성해야 하는데 클라이언트가 쿠키생성을 허용했는지가 불확실하기때문에 ;jsessionid=를 붙여 다니는 것이다.

이는 jstl의 기본 설정 방식이기 때문에 그냥 사용하기로 결정..ㅎㅎ

이 부분이 걸린다면 <c:url> 태그 대신 위에서 사용했던 ${pageContext.request.servletContext.contextPath} 를 변수에 저장해서 경로 앞에 붙이면 된다.

▶<c:out>

@Controller
public class JstlController {

	@RequestMapping("/jstl5")
	public String jstl5(Model model) {
		
		model.addAttribute("str2", "<script>alert('경고메시지');</script>");
		
		return "jstl5";
	}
}

>>> 컨트롤러

	<h1>jstl5</h1>	
    
 	${str2}

>>> jsp 파일

↓ 실행결과

>>> str2에 들어있는 문자열이 jsp 파일 안에서 스크립트로 인식되어 alert 창이 실행된 것을 볼 수 있다. 문자열 그대로 출력하고 싶을 땐 어떻게 해야 할까? 이럴 때 <c:out> 태그를 사용하면 된다.

	<h1>jstl5</h1>	
    
 	<%-- 	${str2} --%>
    <c:out value="${str2}"></c:out>

>>> jsp 파일

↓ 실행결과

>>> 원하는 값이 출력됨

❓ <c:out>을 사용하는 이유?

  • html이나 스크립트가 실행되어 위험
  • 엄격한 태그 규칙을 위해
  • 개행문자 파싱의 차이 때문
  • 보안성 때문에 사용
  • *HTML 특수문자를 탈락시키는 기능 有
    *ex)
    > - &lt;
    < - &gt;
    & - &amp;
    ' - &#039;
    '' - &#034;

<c:out value='${값}'/>에는 디폴트로 escapeXml 옵션이 true로 되어있어 출력할 문자열에 HTML 특수문자가 포함되어 있을 경우 HTML을 해석하지 않고 그대로 출력해준다. escapeXml을 false로 바꾸면 HTML 코드를 그대로 해석해서 내보내게 된다.

결론 : ${}에는 escape 기능이 지원되지 않아 XSS 공격에 노출될 수 있음!

profile
Have a good day ⌯’▾’⌯

0개의 댓글