50일차 JSP JSTL

자바코드를 대신하는 태그들 if choose forEach를 배웟다.

12.22 JSTL SET

SET에는 두가지 방법이 있다.
EL변수의 값 혹은 EL변수의 프로퍼티값을 지정할때 사용한다.
우리는 전자만 배울 것이다.

정확한 표현은 4개의 영역 page request session application의 attribute를 set하는 것이다.
같이 사용하는 것이 var value scope이다.
scope는 영역을 위의 4개의 영역에서 지정하는 것이다.
var 변수명이 attribute명 value가 attribute의 값이다.

<h1>set 태그 : 4개 영역에 attribute 추가</h1>
<c:set var="attr1" value="value1" scope="page"/>
<c:set var="attr2" value="value2" scope="request"/>
<c:set var="attr3" value="value3" scope="session"/>
<c:set var="attr4" value="value4" scope="application"/>

<p>${pageScope.attr1 }</p> <!-- value1 -->
<p>${requestScope.attr2 }</p> <!-- value2 -->
<p>${sessionScope.attr3 }</p> <!-- value3 -->
<p>${applicationScope.attr4 }</p> <!-- value4 -->

12.23 SET - 2

set의 scope를 지정하지 않으면 기본값은 page이다.
가능하다면 좁은 영역부터 값을 지정하는 것이 좋다.

<p>set 태그의 Scope의 기본 값은 page</p>
<c:set var="attr1" value="value1" scope="page"/>
<c:set var="attr2" value="value2"/>

<p>${pageScope.attr1 }</p> <!-- value1 -->
<p>${attr1 }</p> <!-- value1 -->
<p>${pageScope.attr2 }</p> <!-- value2 -->
<p>${attr2 }</p> <!-- value2 -->

12.24 SET - 3

attribute에 값이 아니라 객체를 넣을 수 있었다.
pageContext영역에 만약 객체가 들어있다고 가정해봣을때
다른페이지에도 넘기기 위해 이것을 request로 옮겨담고 싶다

자바코드엿다면 request.setAttribute("list", pageContext.getAttribute("list"));라고 작성햇을 것이다.

<%
    List<String> list = List.of("java", "css", "spring");
    pageContext.setAttribute("list", list);
%>

<p>${pageScope.list[0] }</p> <!-- java  -->

<p>${requestScope.list[0] }</p> <!-- null -->

<c:set var="list" value="${pageScope.list}" scope="request"/>

<p>${requestScope.list[0] }</p> <!-- java -->

12.25 SET

set태그를 사용할때 주의해야할 점이 있다.
실수로 value에 존재하지않는 값 null값 넣으면 attribute가 삭제되게 되니 주의하자.
null이 세팅되는게 아니라 그냥 삭제가 된다.
null값이 들어가지 않도록 주의하자.

모든영역에 같은 attribute이름의 값이 있는데 scope를 생략하고 null값을 넣으면
모든 영역의 attribute의 value가 삭제가 되니 주의하자.

<c:set var="attr1" value="value1" scope="page"/>
<c:set var="attr1" value="value2" scope="request"/>
<c:set var="attr1" value="value3" scope="session"/>
<c:set var="attr1" value="value4" scope="application"/>

<p>${pageScope.attr1 }</p> <!-- value1 -->
<p>${requestScope.attr1 }</p> <!-- value2 -->
<p>${sessionScope.attr1 }</p> <!-- value3 -->
<p>${applicationScope.attr1 }</p> <!-- value4 -->

<c:set var="attr1" value="${abcd }"/>
<p>${pageScope.attr1 }</p> <!-- 삭제 -->
<p>${requestScope.attr1 }</p> <!-- 삭제 -->
<p>${sessionScope.attr1 }</p> <!-- 삭제 -->
<p>${applicationScope.attr1 }</p> <!-- 삭제 -->

12.26 JSTL REMOVE

attribute를 삭제하는 태그가 존재한다.
set에 null값을 넣어서 삭제하는 것이 아니라 remove태그로 삭제하는 것이 좋다.
remove 태그 사용시 scope를 지정하지 않으면 모든 영역에서 삭제되니 주의하자.

<c:set var="attr1" value="value1" scope="page"/>
<c:set var="attr2" value="value2" scope="page"/>

<p>삭제전 : ${attr1}</p> <!-- value1 -->
<p>삭제전 : ${attr2}</p> <!-- value2 -->

<c:set var="attr1" value="${adfad }" scope="page"/>
<c:remove var="attr2" scope="page"/>

<p>삭제후 : ${attr1}</p> <!-- 삭제 -->
<p>삭제후 : ${attr2}</p> <!-- 삭제 -->

12.27 JSTL OUT

OUT태그는 출력하기 위한 태그이다.

<c:set var="attr1" value="some text" />
<p>${attr1 }</p>
<p><c:out value="${attr1}"/></p>

그냥 EL태그를 출력하는 것과 비슷한데 뭐가다른가?
EL은 가지고 있는 값을 그대로 출력을 하게 된다.
set에 html태그와 같은 것을 넣으면 태그를 해석해서 출력하게 된다.
이런 것을 원치 않을때 사용하는 것이 out태그이다.
html entity로 바꿔서 출력해준다.

<c:set var="attr1" value="<br/>" />
<p>${attr1}은 줄바꿈태그다.</p> <!-- 은 줄바꿈태그다 -->
<p><c:out value="${attr1}"/>은 줄바꿈태그다.</p> 
<!-- &lt;br/&gt;은 줄바꿈태그다 -->
<!-- <br/>은 줄바꿈태그다 -->

우리 프로젝트에서는 잘 안쓰는데 실제 업무에서는 자주 사용해서 알아두어야한다.
이름을 받아서 넘기는 폼이 있다고 가정해보자.
만약 그냥 EL태그를 사용한다면 이름이 손<br>흥민 이라면 손 줄바꿈 흥민이 되버린다.
만약 중간에 JS코드를 다루는 코드가 들어가 있다면 스크립트 변경에 취약해진다.
손 <script>document.body.style.backgroundColor="red"</script> 흥민
이런코드를 작성하면 화면전체가 빨개지게 된다.

이런 간단한 것이 아닌 악의적인 의도의 스크립트가 들어간다면 서버가 공격받거나 정보가 탈취되는 일이 일어날 수 있다.
이런 공격을 Cross-site scripting attack이라고한다.
이 것을 막으려면 JSP에서 제일 간단한 방법은 OUT태그를 사용하면 막을 수 있다.
이것을 사용하지 않더라도 실제 업무에서는 다양한 방법으로 방지하는 다른 코드들을 사용해야할 것이다.

게시물작성할때 아예 특수기호를 작성하지 못하거나 작성부터 변환시키는 방법도 있다.
적절한 방법을 찾아서 해야한다. 실무에서는 회사마다 다른 방법을 사용한다.

<h1>3번파일</h1>
<form action="04process" method="post">
    이름 : <input type="text" name="username" />
    <input type="submit" value="전송" />
</form>

<a href="03form.jsp">3번으로 가기</a>
<h1>4번 파일</h1>
<p>${param.username}님 반갑습니다.</p>
<p><c:out value="${param.username}"/>님 반갑습니다.</p> 

12.28 JSTL URL

URL태그는 경로를 출력하는 태그이다.

경로를 쓸때 contextpath경로를 썻엇어야햇다.
그런데 이 경로는 바뀔 수 있었으니 <%=request.contextPath%>로 값을 저장하고 사용햇엇다.
그런데 JSTL은 이런 자바코드를 없애는 것이니 이것을 없앨 수 있다.
URL태그를 사용하면 CONTEXTPATH를 알아서 추가해준다.

<h1>경로 출력 태그</h1>
<p><c:url value="https://wwww.daum.net"/></p>
<!-- https://wwww.daum.net -->

<p>/JSP2023/ch12/lecutre/07url/01url.jsp</p>
<p>${pageContext.request.contextPath}/ch12/lecture/07url/01url.jsp</p>

<!-- context path 추가해줌 -->    
<p><c:url value="/ch12/lecutre/07url/01url.jsp"/></p>

12.29 JSTL URL

하나의 사이트에 같은 경로가 여러개 잇을 수 있다.
예를들어 네이버에서 상단바 뉴스나 안쪽의 뉴스나 같은 곳으로 이동된다

링크를 여러번 작성할 수 있지만 반복해서 사용하는 곳이 있다면
attribute로 URL을 저장해서 사용할 수도 있다.

아주 특별한 경우 request영역에 넣어두고 다른페이지에 사용하게 하고 싶다면
scope attribute를 넣어주면된다.

<div>
    <a href="https://www.daum.net">다음</a>
</div>

<div>
    <a href="https://www.daum.net">다음</a>
</div>

<c:url value="https://www.naver.com" var="naverUrl"/>

<div>
    <a href="${naverUrl }">네이버</a>
</div>

<div>
    <a href="${naverUrl }">네이버</a>
</div>

12.30 JSTL URL - 2

경로를 만들때 쿼리스트링을 붙이는 경우가 종종있다.
쿼리스트링을 붙일때 유용하게 사용할 수 있다.
우리가 직접 url에 쿼리스트링을 붙여서 작성할 수도 잇다.
그런데 쿼리스트링이 한개가아니라 여러개라면 읽기가 어렵다.
c:url의 파라미터로 담아준다면 읽기 쉬운 경로가 된다.
쿼리스트링을 완성할일이 있다면 이런 방법이 쉬울 수도 있다.
원하는 방법으로 사용하면된다.

<div>
    <a href="https://search.daum.net/search?q=아바타">다음에서 아바타 검색</a>
</div>

<c:url value="03url" var="someUrl">
    <c:param name="page" value="3"/>
    <c:param name="q" value="slamdunk"/>
    <c:param name="form" value="04url"/>
    <c:param name="add" value="def"/>
</c:url>

<div>
    <a href="${someUrl}">어떤 경로</a>
</div>

16장 커스텀 태그 만들기

JSTL의 CORE태그들은 이미 만들어져있는 태그이다.
이런 태그를 내가 직접 만들어서 사용할 수 있는데 이것이 커스텀 태그이다.
custom tag는 /WEB-INF/tags 폴더 또는 그 하위 폴더에 저장되어 있어야한다.
사용할 tag이름과 같은 파일명이 있어야한다.
new - other - JSP tag로 만들면된다.

어딘가 포함될 컨텐츠이기때문에 html head body같은 것이 필요없다.
태그 디렉토리의 tag를 사용하겠다고 tagdir을 지정해줘야한다.
내가만든 tag와 core tag이름이 같을 수 있어서 prefix를 달아주는 것이다.
<%@ taglib prefix="custom" tagdir="/WEB-INF/tags"%>
core태그를 사용해주듯이 prefix:태그이름으로 사용하면된다.

반복해서 작성해야하는 코드가 있다면 태그로 만들어두고 사용하면 편리할 수 있다.

<%@ 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="custom" tagdir="/WEB-INF/tags"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <p>custom tag는 /WEB-INF/tags 폴더 또는 그 하위 폴더에 저장</p>
    <custom:mytag01/>
</body>
</html>

16.1 tag만들기

jsp를만들때는 page디렉티브를 사용햇는데 tag에서는 tag디렉티브를 사용하면된다.
이름만 다르고 결국엔 같은 내용을 하는 것이다.

<%@tag import="java.util.Calendar"%>
<%@ tag language="java" pageEncoding="UTF-8"%>

<%
    Calendar cal = Calendar.getInstance();
%>
<%= cal.get(Calendar.YEAR)%>년
<%= cal.get(Calendar.MONTH) + 1%>월
<%= cal.get(Calendar.DATE)%>일

<%@ 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="tf" tagdir="/WEB-INF/tags" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>now</title>
</head>
<body>
    오늘은 <b><tf:now/></b> 입니다.
</body>
</html>

16.2 tag body

tag의 안쪽을 jsp의 doBody 액션태그를 사용하면된다.
tag의 안쪽 내용이 doBody부분에 포함되게 된다.

<div>
    <h1>태그 시작</h1>
</div>

<!-- body로 받는 내용 출력 -->
<jsp:doBody/>

<div>
    <h1>태그 종료</h1>
</div>

<h1>tag의 body</h1>
<d:mytag02>
    <div>
        <h1>Lorem.</h1>
    </div>
</d:mytag02>

<hr />

<d:mytag02>
    <div>
        <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quisquam beatae excepturi rem nemo tenetur eius quas fugiat eveniet aliquid possimus assumenda autem consectetur repellendus quod obcaecati quis quos at suscipit.</p>
    </div>
</d:mytag02>

16.3 tag

tag안에서 JSTL을 사용해서 또 다른 JSP처럼 사용할 수 있다.

<%@ tag language="java" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<c:forEach begin="1" end="2">
    <jsp:doBody/>
</c:forEach>

<d:mytag04>
    <p>또 다시 두번 출력</p>
</d:mytag04>
<!-- 또 다시 두번 출력
또 다시 두번 출력 -->

16.4 tag attribute

body로 값을 전달했엇다.
태그는 또 다른 jsp이기때문에 tag에 attribute로 값을 넘길 수 있다.
<d:mytag06 attr1="value1"/>다른 태그들처럼 attribute를 사용할 수 잇도록 tag를 작성하는 방법이 있다.

tag에서 attribute 디렉티브로 이름을 명시해주면 사용할 수 있다.
<%@ attribute name = "attr1" %>

태그에서는 이 attribute를 EL로 꺼내서 사용하면된다.
작성하지 않은 attibute는 사용할 수가 없다.

<p>attribute</p>
<d:mytag06 attr1="value1"/>
<d:mytag06 attr1="value2"/>

<%@ tag language="java" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ attribute name = "attr1" %>

<div>
    <h5>6번 태그</h5>
    <p>${attr1}</p>
</div>

16.5 tag attribute - 2 연습
tag에서 attribute가 출력되게 코드를 작성해보자.

<h1>7번 파일 attribute 연습</h1>
<d:mytag07 name="흥민" age="30"/>
<d:mytag07 name="태웅" age="40"/>

<%@ tag language="java" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ attribute name="name"%>
<%@ attribute name="age"%>

<div>
    <p>${name}의 나이는 ${age}입니다.</p>
</div>

16.6 dynamic attributes

명시하지 않은 attribute도 사용할 수 있다.
attribute를 사용하려면 원래는 명시를 해줘야한다.
명시하지 않은 attributre를 차용하고 싶을때 사용하는 것이 dynamic attributes이다.
명시하지 않은 attribute들만 모아서 저장할 수 있다.
tag디렉티브에 dynamic-attributes속성을 주면된다.
<%@ tag dynamic-attributes="others" %>
EL에 사용할 수 있게 attribute가 담긴 MAP이 생긴다.

명시하지 않았던 attribute의 이름을 키 로 값을 value로 map에 담는다.
키 밸류쌍으로 들어가기 때문에 map을 사용하던 것처럼 사용하면된다.

<h1>dynamic attributes</h1>
<d:mytag08 attr1="value1" attr2="value2" attr3="value3"/> 

<%@ tag language="java" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ attribute name="attr1"%>
<%@ attribute name="attr2"%>
<%@ tag dynamic-attributes="others" %>

<div>
    <p>${attr1}, ${attr2}</p>
</div>

<div>
    ${others.attr3 }
</div>

16.7 tag scope

이전 태그 의 attribute(속성)과는 구분해야한다.
4개의 영역에 attribute를 넣어서 값을 전달하는 방법이 있다.

request, session, application은 공유할 것이라고 생각된다.
page는 같은 영역이 아니라 공유할 수 없다.
별일없으면 좁은 영역부터 활용하자.

<h1>영역 객체 이용해서 값 전달</h1>
<c:set var="attr1" value="value1" scope="page"/>
<c:set var="attr2" value="value2" scope="request"/>
<c:set var="attr3" value="value3" scope="session"/>
<c:set var="attr4" value="value4" scope="application"/>

<d:mytag09/> 

<%@ tag language="java" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

<div>${pageScope.attr1}</div> <!-- x -->
<div>${requestScope.attr2}</div> <!-- value2 -->
<div>${sessionScope.attr3}</div> <!-- value3 -->
<div>${applicationScope.attr4}</div> <!-- value4 -->

16.8 tag연습

pagenation을 여러군데서 사용할 것 같으니 태그로 만들어보자.
미리 저장해두고 원하는 데서 사용할 수 있다.
여기서는 태그이름은 mytag11로 지었지만
태그이름은 실제 프로젝트를 짤때 사용할 때 용도에 맞게 지어주자.

<%@ tag language="java" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ attribute name="begin" %>
<%@ attribute name="end" %>

<nav>
    <ul class="pagination">
        <c:forEach begin="${begin }" end="${end }" var="pageNumber" >
            <li class="page-item">
                <a href="#" class="page-link">${pageNumber }</a>
            </li>
        </c:forEach>
    </ul>
</nav>

<d:mytag10 />

<hr />

<d:mytag11 begin="11" end="20" />

<hr />

<d:mytag11 begin="21" end="30" />

16.9 tag 연습

페이징을 만드는데 1~10페이지 5페이지가 active되도록해보자.
부트스크렙 active는 클래스에추가하면포커싱이되게 된다.
nav바에 만약 pageNumber와 active가 같다면 active class가 추가되도록 했다.
EL의 삼항연산을 사용할 수도 있다.

<!-- 1~10페이지 5페이지가 active되도록 -->
<d:mytag12 begin="1" end="10" active="5"/> 

<!-- 11~20 13번페이지 active -->
<d:mytag12 begin="11" end="20" active="13"/> 

<nav>
    <ul class="pagination">
        <c:forEach begin="${begin }" end="${end }" var="pageNumber" >
            <li class="page-item 
            <c:if test="${pageNumber == active}"> 
                active
            </c:if>" >
                <a href="#" class="page-link">${pageNumber }</a>
            </li>
        </c:forEach>
    </ul>
</nav>

<nav>
    <ul class="pagination">
        <c:forEach begin="${begin }" end="${end }" var="pageNumber">
            <li class="page-item ${pageNumber eq active ? 'active' : '' }">
                <a href="" class="page-link">
                    ${pageNumber }
                </a>
            </li>
        </c:forEach>
    </ul>
</nav>

16.10 tag 연습 - 2

만든 태그를 현실적으로 사용해보자.
페이징은 쿼리스트링으로 넘어오게 된다.
url를 만들어서 사용하면 편하게 사용할 수 있다.
value를 비우면 현재 패이지를 기준으로 한다.

<nav>
    <ul class="pagination">
        <c:forEach begin="${begin }" end="${end }" var="pageNumber" >
            <c:url value="" var="pageLink">
                <c:param name ="page" value="${pageNumber}"/>
            </c:url>

            <li class="page-item 
            <c:if test="${pageNumber eq active}"> 
                active
            </c:if>" >
                <a href="${pageLink}" class="page-link">${pageNumber }</a>
            </li>
        </c:forEach>
    </ul>
</nav>

2023 04 06

스크립트를 넣어서 공격을 한다는 것은 상상도 하지 못햇다.
예전에 모바일 게임에서 이름에 html 태그를 넣어서 이름 색을 변경하거나 굵게 만드는 일이 잇엇는데
이런 단순한 허점을 이용했다고 생각된다.
실제 업무를 한다는 느낌에서 주의해야함을 상기하고 있어야할 것 같다.

자바코드를 없애게 되엇다 이제 자바코드가 어디로 들어가는가?
서블릿으로 들어간다 내일부터 배울예정이다.

'국비 > JSP' 카테고리의 다른 글

2023.04.07 51일차 JSP - 2  (0) 2023.04.07
2023.04.07 51일차 JSP  (0) 2023.04.07
2023.04.05 49일차 JSP  (0) 2023.04.05
2023.04.04 48일차 JSP  (5) 2023.04.04
2023.04.03 47일차 JSP  (0) 2023.04.03

+ Recent posts