매일 조금씩

01/08 - JSP(13) : 표준태그라이브러리(JSTL), 특수한 서블릿 - 필터(filter), 리스너(listener) 본문

빅데이터 플랫폼 구축을 위한 자바 개발자 양성과정

01/08 - JSP(13) : 표준태그라이브러리(JSTL), 특수한 서블릿 - 필터(filter), 리스너(listener)

mezo 2021. 1. 17. 19:03
728x90
반응형

MVC Model2

       parameter

              controller?action=list

       url

              list.do (*)

 

view

       EL

              ${ 데이터/변수(객체)} = <%= %>

 

 

EL 확장 + action확장  →  java 안쓰고 view 사용 ==== > JSTL

 

 

 

 

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


▷p292 chapter12. 표준태그 라이브러리

JSTL <= cutom action tag

action tag = <jsp:명령어> - 사용자별로 다름   =>   표준화   =>   JSTL(Java Standard Template(Tag) Library)

            + EL = view(jsp에 java 언어 안쓰는게 목적!)

 

 

1. JSTL 이란?

1- 1.  JSTL이 제공하는 태그의 종류

                            내가 정함                                  고정

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

   <c:기능>   

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

 

 

1-2. JSTL 라이브러리 받기

JSTL 쓰려면 그냥은 안되고 라이브러리가 있어야한다. 

jstl.jar, standard.jar 를 lib 폴더에 추가한다.

 

 

 

 

2. 코어 태그

아래의 라이브러리 주소를 사용한다. 

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

 

 

JSTLEx01

2-1. <c:out> 태그

ex01.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ 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>

<%
	pageContext.setAttribute("data1", "value1");
%>
출력 : <%=pageContext.getAttribute("data1")  %><br />
출력 : ${ data1 }<br />
출력 : <c:out value="${ data1 }" /><br />
출력 : <c:out value="${ data2 }" default="value2" /><br />
출력 : <c:out value="${ data3 = 'value3' }" /><br />
출력 : <c:out value="${ data2 }" >value4</c:out><br />

</body>
</html>

 

 

 

2-2. <c:set> 태그

default는 page다.

request나 다른 객체를 쓰려면 scope쓰면 된다.

ex02.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ 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>

<c:set var="data1" value="test1" /><!-- pages -->
<c:set var="data2" value="test2" scope="request"/>
<%
	//String data1 = "test1";
	pageContext.setAttribute("data1","test1");
	//request.setAttribute("data2", "test2");
%>
출력 : ${ data1 }<br />
출력 : <c:out value="${ data1 }" /><br />
출력 : <%=pageContext.getAttribute("data1") %><br />
출력 : <%=request.getAttribute("data2") %><br />
</body>
</html>

 

2-3. 객체별 <c:set> 태그 사용, 출력

JSTL은 view페이지만의 새로운 문법이다.

ex03.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ 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>

<%
	pageContext.setAttribute("data1", "test1");
	request.setAttribute("data2", "test2");
	session.setAttribute("data3", "test3");
	application.setAttribute("data4", "test4");
%>
<c:set var="data1" value="test1" scope="page" />
<c:set var="data2" value="test2" scope="request" />
<c:set var="data3" value="test3" scope="session" />
<c:set var="data4" value="test4" scope="application" />
출력 : ${requestScope.data2 }<br />
출력 : ${sessionScope.data3 }<br />
출력 : ${applicationScope.data4 }<br />

</body>
</html>

 

 

2-4. <c:remove > 태그

ex04.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ 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>

<c:set var="data1" value="test1" scope="page" />
출력 : <c:out value="${ data1 }" /><br />
<c:remove var="data1" /><br />
출력 : <c:out value="${ data1 }" /><br />
</body>
</html>

 

 

2-5. 기본 객체 말고 사용자가정의한 객체를 jsp usebean처럼 쓸수 있게 제공

BoardTO.java

package model1;

public class BoardTO {
	private String subject;
	private String writer;
	
	public BoardTO() {
		// TODO Auto-generated constructor stub
		System.out.println("생성자 호출");
	}
	
	public String getSubject() {
		return subject;
	}
	public void setSubject(String subject) {
		this.subject = subject;
	}
	public String getWriter() {
		return writer;
	}
	public void setWriter(String writer) {
		this.writer = writer;
	}
}

ex05.jsp

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

<!-- BoardTO to1 = new BoardTO() -->
<c:set var="to1" value="<%=new model1.BoardTO() %>" scope="page" />
<c:set target="${ to1 }" property="subject" value="제목1" />
<c:set target="${ to1 }" property="writer" value="작성자1" />

<c:set var="to2" value="<%=new model1.BoardTO() %>" scope="page" />
<c:set target="${ to2 }" property="subject" value="제목2" />
<c:set target="${ to2 }" property="writer" value="작성자2" />

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- 
	기본 객체 쓸땐 ${ requestScope.var명 } 이렇게 했는데 
	여기선 var의 value값으로 객체를 생성하므로 다르다.
-->
<!-- ${ var명.property명 } -->
제목 : ${ to1.subject }<br />
작성자 : ${ to1.writer }<br />
제목 : ${ to2.subject }<br />
작성자 : ${ to2.writer }<br />


</body>
</html>

 

 

2-6. <c:if> 태그

test값 true/false에 따라 태그가 실행/실행X 

ex06.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ 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>

<c:if test="true">
	무조건 실행<br />
</c:if>
끝<br />

<hr />

<c:set var="country" value="korea" />
<c:if test="${ country == 'korea' }">
	한국입니다.<br />
</c:if>

<c:if test="${ country != null }">
	국가명은 <c:out value="${ country }" />입니다.<br />
</c:if>

</body>
</html>

 

2-7. <c:choose> ~ <c:when>, <c:otherwise>

if~else문이다.

ex07.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ 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>


<c:set var="country" value="korea" />


<c:choose>
	<c:when test="${ country == 'korea' }">
		<c:out value="${ country }" />는 춥다.<br />
	</c:when>
	<c:when test="${ country == 'canada' }">
		<c:out value="${ country }" />는 더 춥다.<br />
	</c:when>
	<c:otherwise>
		겨울은 안춥다.<br />
	</c:otherwise>
</c:choose>

</body>
</html>

 

 

2-8. <c:forEach>태그

for문이다. 

ex08.jsp

JSTL에서 변수정의를 할때 변수값은 var=변수명 으로 정의하고 

그걸 가져다 쓸땐 항상 ${변수명} 으로 변수값을 가져올 수 있다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<%@ 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>

<c:forEach var="i" begin="1" end="5" step="2">
	Hello JSTL - ${ i }<br />
	<c:out value="${ i }" /><br />
</c:forEach>

</body>
</html>

 

 

 

응용실습)구구단 테이블 만들기

gugudan.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<%@ 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>

<table width="800" border="1" >
<tr>
	<c:forEach var="i" begin="0" end="9">
		<c:choose>
			<c:when test="${i == 0 }">
				<td></td>
			</c:when>
			<c:otherwise>
				<td>X ${ i }</td>
			</c:otherwise>
		</c:choose>
	</c:forEach>
</tr>
<c:forEach var="row" begin="1" end="9">
	<tr>
		<td>${ row } 단</td>
		<c:forEach var="col" begin="1" end="9">
			<td>${ row } X ${ col } = ${ row*col }</td>
		</c:forEach>
	</tr>
</c:forEach>
</table>

</body>
</html>

 

 

 

2-9. 배열, HashMap, for문

배열이기때문에 배열 인덱스에 의존한다.

ex09.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ 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>

<c:set var="intArr" value="<%=new int[]{1,2,3,4,5} %>" />
<c:out value="${ intArr[0] }" /><br />
<c:out value="${ intArr[1] }" /><br />
<c:out value="${ intArr[2] }" /><br />

<hr />

<c:forEach var="data" items="${intArr}" >
	<c:out value="${ data }" /><br />
</c:forEach>

<hr />

<!-- 배열 인덱스에 의존 -->
<c:forEach var="data" items="${intArr}" begin="2" end="4">
	<c:out value="${ data }" /><br />
</c:forEach>

<hr />

<c:set var="strArr" value='<%=new String[]{"AA","BB","CC","DD","EE"} %>' />

<c:forEach var="data" items="${strArr}" >
	<c:out value="${ data }" /><br />
</c:forEach>

<hr />

<%
	//hashmap java for문
	//HashMap<String, Object> hm1 = new HashMap<String, Object>();
	//hm1.put("name","홍길동");
	//hm1.put("today", new java.util.Date());
%>

<c:set var="hm1" value="<%=new java.util.HashMap()  %>" />
<c:set target="${ hm1 }" property="name" value="홍길동" />
<c:set target="${ hm1 }" property="today" value="<%=new java.util.Date() %>" />

<c:forEach var="data" items="${ hm1 }">
	${ data.key } = ${ data.value }<br />
</c:forEach>


</body>
</html>

 

 

2-10. HeaderValues 가져오기

HashMap구조여서 HashMap처럼 가져올수있다.

이 안에 user-agent도 있어서 이걸 사용해서 user-agent도 가져올수 있다.

ex10.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ 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>

<c:forEach var="h" items="${ headerValues }">
	<c:forEach var="val" items="${h.value }">
		param: ${ h.key } / ${ val } <br />
	</c:forEach>
</c:forEach>

</body>
</html>

 

 

2-11. 다른 페이지에서 입력받은 값 출력하기 - param, paramValues(forEach)

이것도 HashMap처럼 key와 value로 값 가져올수 있게 되어ㅓ 있다.

같은 이름으로 여러개 되어 있으면 param이 아니고 paramValues로 가져와야한다.

key로 변수명만 가져올수있다.

form.jsp

<%@ 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>

<form action="form_ok.jsp" method="post">
이름: <input type="text" name="irum" /><br />
성적1: <input type="text" name="sung" /><br />
성적2: <input type="text" name="sung" /><br />
<input type="submit" value="전송" /><br />
</form>

</body>
</html>

form_ok.jsp

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

<%
	request.setCharacterEncoding("utf-8");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

이름 : ${ param.irum }<br />
이름 : ${ param.sung }<br />

성적1 : ${ paramValues.sung[0] }<br />
성적2 : ${ paramValues.sung["1"] }<br />

<hr />

<c:forEach var="p" items="${ paramValues }">
	${ p.key }<br />
	<c:forEach var="val" items="${ p.value }" >
		param : ${ p.key } / ${ val }<br />
	</c:forEach>
</c:forEach>

</body>
</html>

 

 

2-12. ArrayList<BoardTO> 값 쓰기

ex11.jsp

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

<%
	BoardTO to1 = new BoardTO();
	to1.setSubject("제목1");
	to1.setWriter("작성자1");
	
	BoardTO to2 = new BoardTO();
	to2.setSubject("제목2");
	to2.setWriter("작성자2");
	
	ArrayList<BoardTO> lists = new ArrayList();
	lists.add(to1);
	lists.add(to2);
	
	request.setAttribute("lists", lists);
%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

<c:forEach var="i" begin="0" end="<%=lists.size() - 1 %>">
	${ lists[i].subject }<br />
	${ lists[i].writer }<br />
</c:forEach>

<hr />

<c:forEach var="data" items="${ lists }" >
	${ data.subject }<br />
	${ data.writer }<br />
</c:forEach>


</body>
</html>

 

 

 

2-13. <c:forTokens> 태그

ex12.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ 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>

<c:forTokens var="c" items="1,2,3,4,5" delims=",">
	데이터: ${ c }<br />
</c:forTokens>

<hr />
<c:set var="lists" value="홍길동,김길동,고길동" />
<c:forTokens var="c" items="${ lists }" delims=",">
	데이터: ${ c }<br />
</c:forTokens>

<hr />
<c:set var="lists" value="빨간색,주황색.노란색,파랑색,남색.보라색" />
<c:forTokens var="c" items="${ lists }" delims=",.">
	데이터: ${ c }<br />
</c:forTokens>


</body>
</html>

 

 

 

 

... 추가적인것들 (url에 관한거)

2-14. <c:redirect>

ex13.jsp

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

<!--
	<c:redirect url="https://www.daum.net" /> 
	%EC%BD%94%EB%A1%9C%EB%82%98
	
	https://search.naver.com/search.naver?
	query=%EC%BD%94%EB%A1%9C%EB%82%98
-->

<!-- 주석없어야 제대로 실행됨 -->

<!-- 다음 -->
<c:redirect url="https://search.daum.net/search">
	<c:param name="w" value="tot" />
	<c:param name="q" value="코로나" />
</c:redirect>

<!-- 네이버 -->
<c:redirect url="https://search.naver.com/search.naver">
	<c:param name="query" value="코로나" />
</c:redirect>

 

 

2-15. <c:url>

ex14.jsp

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


<c:url var="url1" value="./list.do" />
${ url1 } <br />

<c:url var="url2" value="https://search.daum.net/search">
	<c:param name="w" value="tot" />
	<c:param name="q" value="코로나" />
</c:url>
${ url2 } <br />
<c:redirect url="${ url2 }" />

 

 

2-16. <c:import>

ex15.jsp

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

<hr />
<hr />

<c:import url="https://m.daum.net" />

 

 

2-17. <c:import>로 html 긁어 오기 (크롤링 역할 해줌)

import된 사이트의 html 데이터를 가져올수 있다.

ex16.jsp

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

<c:import var="htmlData" url="https://m.daum.net" />


<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
html 내용 : <br />
<textarea rows="50" cols="800">
${ htmlData }
</textarea>

</body>
</html>

 

 

 

3. 데이터베이스 태그

아래의 라이브러리주소를 사용한다. 

 

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

<s:setDataSource> 사용

<s:setDataSource
	var="ds"
	url="jdbc:mysql://localhost:3307/sample" 
	driver="org.mariadb.jdbc.Driver"
	user="root"
	password="!123456"
	scope="page" />

dataSource 속성으로 <s:setDataSource> 에서 연결한 데이터 베이스를 정의된 ${변수명} 으로 넣는다.

 

JSTLEx02

3-1. insert문 구현 <s:update>

PreparedStatement방식으로도 넣기 가능하다.

      →  <s:param value="값"> 으로 ?에 하나씩 값을 넣는다.

ex01.jsp

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

<s:setDataSource
	var="ds"
	url="jdbc:mysql://localhost:3307/sample" 
	driver="org.mariadb.jdbc.Driver"
	user="root"
	password="!123456"
	scope="page" />

<!--<s:update dataSource="${ds}" sql="insert into dept2 values (93, '생산', '부산')" />-->

<s:update dataSource="${ ds }" sql="insert into dept2 values (?,?,?)">
	<s:param value="97" />
	<s:param value="조사" />
	<s:param value="대구" />
</s:update>

<s:update dataSource="${ ds }">
	insert into dept2 values (?,?,?)
	<s:param value="98" />
	<s:param value="생산" />
	<s:param value="부산" />
</s:update>


 

 

3-2. select문 구현 <s:query>

ex02.jsp

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

<s:setDataSource
	var="ds"
	url="jdbc:mysql://localhost:3307/sample" 
	driver="org.mariadb.jdbc.Driver"
	user="root"
	password="!123456"
	scope="page" />

<!--<s:query var="rs" dataSource="${ds}" sql="select * from dept2" ></s:query>-->
<!--<s:query var="rs" dataSource="${ds}" sql="select deptno as no, dname as name, loc as location from dept2" ></s:query>-->
<s:query var="rs" dataSource="${ds}">
	select deptno as no, dname as name, loc as location from dept2
</s:query>


<c:forEach var="columnName" items="${ rs.columnNames }" >
	${ columnName }<br />
</c:forEach>

<hr />

<c:forEach var="data" items="${ rs.rows }">
	${data["deptno"] } / ${data["dname"] } / ${data["loc"] }<br />
</c:forEach>


 

3-3. 커넥션 풀 사용

톰캣껏다 켜서 재실행 (그래야 context.xml 파일 읽어옴)

<s:setDataSource > 의 dataSource속성에  연결하고자 하는 데이터베이스가 context.xml에서 정의된이름을 쓴다.

ex03.jsp

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

<s:setDataSource 
	var="ds"
	dataSource="jdbc/mariadb1"
	scope="page" />

<s:query var="rs" dataSource="${ds}">
	select deptno as no, dname as name, loc as location from dept2
</s:query>

<hr />

<c:forEach var="data" items="${ rs.rows }">
	${data["deptno"] } / ${data["dname"] } / ${data["loc"] }<br />
</c:forEach>

 

3-4. <s:setDataSource> + <s:query> 

가장빠른방법이다.

<s:query> 의 dataSource에  <s:setDataSource>의 dataSource를 넣으면 끝!

sql에서 limit와 같은 startRow, maxRows를 <s:query> 를 통해 쓸수 있다.

ex) startRow, maxRows startRow="2" maxRows="4" => limit 2,4

where절 쓰는 법 - startRow, maxRows 같이 사용 불가

ex04.jsp

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

<!--
<s:setDataSource 
	var="ds"
	dataSource="jdbc/mariadb1"
	scope="page" />
-->


<!-- startRow="2" maxRows="4" => limit 2,4 -->
<!--
	<s:query var="rs" dataSource="jdbc/mariadb1" startRow="2" maxRows="4">
-->

<!-- 주석처리 없애야 에러 안남 -->

<s:query var="rs" dataSource="jdbc/mariadb1">
	select deptno as no, dname as name, loc as location from dept2 where deptno=?
	<s:param value="10" />
</s:query>

<c:forEach var="data" items="${ rs.rows }">
	${data["deptno"] } / ${data["dname"] } / ${data["loc"] }<br />
</c:forEach>

 

 

 

 

 

 

 

 

 

 

 

필터


servlet에서 안했던 부분

특수한 Servlet

 

1. 필터란?

 

▷p544

HTTP가 요청과 응답을 자원과주고 받을때 그 사이에 있다.

자원과 함께 웹 컨테이너에 존재한다.

간단하게 말해서 필터는 'HTTP 요청과 응답을 변경할 수 있는 재사용 가능한 클래스' 이다.

 

 

 

2. 필터의 구현

2-1. 필터 만들기

FilterEx01

1) web.xml을 포함해서 프로젝트를 만들어야 한다.

 

2) 필터 클래스를 만들때 javax.servlet.Filter 를  implement해줘야 한다.

 

3)  클라이언트

ex01.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	System.out.println("Hello Filter");
	out.println("Hello Filter");
%>

 

4) 필터

FirstFilter.java  

package filter;
import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class FirstFilter implements Filter {

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		System.out.println("init() 호출");
	}
	
	@Override
	public void destroy() {
		System.out.println("destroy() 호출");
	}
	
	@Override
	public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
			throws IOException, ServletException {
		// TODO Auto-generated method stub

		// 전처리 구간
		System.out.println("첫번째 전처리");
		//servlet/jsp 호출 부분
		
		// 사용자 요청에 의해 jsp를 요청하는 거다.
		// 이걸 안하면 filter에만 왔다 가는 거다.
		arg2.doFilter(arg0, arg1);
		
		System.out.println("첫번째 후처리");
		// 후처리 구간
	}

}

 

5) 필터 등록

web.xml에 filter등록해주기

5) 클라이언트 실행

ex01.jsp를 실행시키면

arg0 이 request, agr1이 response, arg2가filterchain일 때

doFilter() 메서드 안에서 순서대로 실행 

arg2.doFilter(arg0, arg1);

@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
        throws IOException, ServletException {
    // TODO Auto-generated method stub

    // 전처리 구간
    System.out.println("첫번째 전처리");
    //servlet/jsp 호출 부분
    arg2.doFilter(arg0, arg1);

    System.out.println("첫번째 후처리");
    // 후처리 구간
}

출력은

 

여기서

arg2.doFilter(arg0, arg1);

이걸 안하면 사용자가 요청을 했을 때 jsp파일까지 안가고 filter에만 왔다 가는 걸로 실행이 된다.

 

 

 

 

2-2. 필터 여러개 만들기 (annotation 사용)

FilterEx02

FirstFilter.java

package filter;

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;

/**
 * Servlet Filter implementation class FirstFilter
 */
@WebFilter("*.jsp")
public class FirstFilter implements Filter {

    /**
     * Default constructor. 
     */
    public FirstFilter() {
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see Filter#destroy()
	 */
	public void destroy() {
		// TODO Auto-generated method stub
	}

	/**
	 * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
	 */
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		// TODO Auto-generated method stub
		// place your code here
		
		System.out.println("첫번째 전처리");
		
		chain.doFilter(request, response);
		
		System.out.println("첫번째 후처리");
		
		
	}

	/**
	 * @see Filter#init(FilterConfig)
	 */
	public void init(FilterConfig fConfig) throws ServletException {
		// TODO Auto-generated method stub
	}

}

 

SecondFilter.java

package filter;

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;

/**
 * Servlet Filter implementation class SecondFilter
 */
@WebFilter("*.jsp")
public class SecondFilter implements Filter {

    /**
     * Default constructor. 
     */
    public SecondFilter() {
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see Filter#destroy()
	 */
	public void destroy() {
		// TODO Auto-generated method stub
	}

	/**
	 * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
	 */
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		// TODO Auto-generated method stub
		// place your code here
		System.out.println("두번째 전처리");
		
		chain.doFilter(request, response);
		
		System.out.println("두번째 후처리");
	}

	/**
	 * @see Filter#init(FilterConfig)
	 */
	public void init(FilterConfig fConfig) throws ServletException {
		// TODO Auto-generated method stub
	}

}

 

ex01.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	System.out.println("Hello Filter");
	out.println("Hello Filter");
%>

annotation 사용

여러개 필터 사용 ( 이름만 다르고 doFilter() 메서드의 코드가 같은 여러개의 filter를 만들면 이름순서대로 실행이됨)

 

 

 

2-3. form, form_ok 페이지를 filter로 처리하기

form.jsp와 form_ok.jsp 사이에 filter가 있다.

form.jsp에서 입력받은 값 검사를 form_ok.jsp 가 아닌 filter가 진행하는 식으로 한다.기존에 다국어 처리를 위해서 form_ok.jsp 에서 pageEncoding="utf8"을 해줬는데 filter에서 이걸 처리하게 해서  pageEncoding="utf-8"을 써주지 않아도 되도록 한다.또한, 데이터가 입력됐으면 form_ok.jsp로 입력되지 않았으면 다른페이지로 이동하게  filter에서 처리해주도록 한다.

 

FilterEx03

form.jsp

<%@ 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>

<form action="form_ok.jsp" method="post">
데이터 <input type="text" name="data" /> 
<input type="submit" value="전송" />
</form>


</body>
</html>

form_ok.jsp

<%@ 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>
data : <%=request.getParameter( "data" ) %>
</body>
</html>

EncodingFilter.java

package filter;


import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;



/**
 * Servlet Filter implementation class EncodingFilter
 */
@WebFilter("*.jsp")
public class EncodingFilter implements Filter {

	/**
	 * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
	 */
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		// TODO Auto-generated method stub
		// place your code here

		if( request.getCharacterEncoding() == null ) {
			request.setCharacterEncoding( "utf-8" );
		}
		
		String data = request.getParameter( "data" );
		if( !data.equals("") ) {
			// pass the request along the filter chain
			chain.doFilter(request, response);
		} else {
			RequestDispatcher dipaDispatcher = request.getRequestDispatcher("error.jsp");
			dipaDispatcher.forward(request, response);
		}
	}
}

 

그러면

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

여기서 pageEncoding="UTF-8"이 필요 없게 된다.

 

error.jsp 페이지 추가

<%@ 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>
data를 입력하지 않았습니다.
</body>
</html>

 

 

Listener


어플리케이션이 시작/종료 에대한 이벤트 외에

session시작, request등의 이벤트에 대한 처리를 한다.

 

  • ServletContextListener  : 서버의 시작과 종료
  • HttpSessionListener  :  접속의 시작과 종료
  • ServletRequestListener  :  요청의 시작과 종료
  • Attribute  :  속성값의 변화

 

1. ServletContextListener 구현

1-1. ServletContextLister  만들기

ListenerEx01

1) web.xml을 포함해서 프로젝트를 만들어야 한다.

 

2) listener 클래스를 만들때 javax.servlet.ServletContextListener 를  implement해줘야 한다.

 

3)  listener

FirstListener.java

package listener;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class FirstListener implements ServletContextListener {
	@Override
	public void contextInitialized(ServletContextEvent sce) {
		// TODO Auto-generated method stub
		ServletContextListener.super.contextInitialized(sce);
	
		// 서버의 시작과 관련
		System.out.println("contextInitialized(ServletContextEvent sce) 호출");
	}
	
	@Override
	public void contextDestroyed(ServletContextEvent sce) {
		// TODO Auto-generated method stub
		ServletContextListener.super.contextDestroyed(sce);
		
		// 서버의 종료와 관련
		System.out.println("contextDestroyed(ServletContextEvent sce) 호출");
	}
}

 

4) 클라이언트

ex01.jsp

<%@ 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>
Hello Listener
</body>
</html>

 

5) listener 등록

web.xml에 listener등록해주기

 

 

1-2. ServletContextListener 여러개 만들기 (annotation 사용)

한 개 이상의 리스너가 등록된 경우, contextInitialized() 메서드는 등록된 순서대로 실행되고 contextDetroyed() 메서드는 등록된 반대 순서대로 실행된다.  

서블릿 3.0 버전부터는 web.xml 파일에 등록하지 않고, @WebListener annotation을 리스너 클래스에 적용하면 자동으로 리스너로 등록된다.

 

ListenterEx02

1) listener

FirstListener.java

package listener;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

/**
 * Application Lifecycle Listener implementation class FirstListener
 *
 */
@WebListener
public class FirstListener implements ServletContextListener {

    /**
     * Default constructor. 
     */
    public FirstListener() {
        // TODO Auto-generated constructor stub
    }

	/**
     * @see ServletContextListener#contextDestroyed(ServletContextEvent)
     */
    public void contextDestroyed(ServletContextEvent sce)  { 
         // TODO Auto-generated method stub
    	System.out.println("contextDestroyed(ServletContextEvent sce) 호출");
    }

	/**
     * @see ServletContextListener#contextInitialized(ServletContextEvent)
     */
    public void contextInitialized(ServletContextEvent sce)  { 
         // TODO Auto-generated method stub
    	System.out.println("contextInitialized(ServletContextEvent sce) 호출");
    }
	
}

SecondListener.java

package listener;

import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.annotation.WebListener;

/**
 * Application Lifecycle Listener implementation class SecondListener
 *
 */
@WebListener
public class SecondListener implements ServletContextAttributeListener {

    /**
     * Default constructor. 
     */
    public SecondListener() {
        // TODO Auto-generated constructor stub
    	System.out.println("SecondListener() 생성자 호출");
    }

	/**
     * @see ServletContextAttributeListener#attributeAdded(ServletContextAttributeEvent)
     */
    public void attributeAdded(ServletContextAttributeEvent scae)  { 
         // TODO Auto-generated method stub
    	
    	System.out.println("attributeAdded(ServletContextAttributeEvent scae) 호출");
    }

	/**
     * @see ServletContextAttributeListener#attributeRemoved(ServletContextAttributeEvent)
     */
    public void attributeRemoved(ServletContextAttributeEvent scae)  { 
         // TODO Auto-generated method stub
    	System.out.println("attributeRemoved(ServletContextAttributeEvent scae) 호출");
    }

	/**
     * @see ServletContextAttributeListener#attributeReplaced(ServletContextAttributeEvent)
     */
    public void attributeReplaced(ServletContextAttributeEvent scae)  { 
         // TODO Auto-generated method stub
    }
	
}

 

ex01.jsp

<%@ 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>
Hello Listener

<%
	ServletContext context = getServletContext();

	context.setAttribute("name" , "홍길동");
	out.println("context 추가 완료<br />");
	
	context.setAttribute("name" , "박문수");
	out.println("context 추가 완료<br />");
	
	context.removeAttribute("name" );
	out.println("context 삭제 완료<br />");
%>
</body>
</html>

 

ListenerEx02를 ListenerEx01이랑 똑같이 만든후 ListenerEx01를 실행시키면

"contextInitialized(ServletContextEvent sce) 호출" 이게 두개가 뜬다.

 

왜? ListenerEx02도 자동 실행된다. 그래서 두개 뜬다. 

ServletContextListener는 서버의 시작과 종료에 실행되기 때문에

jsp 실행에 영향을 받지 않고 tomcat이 실행되면 자동으로 ServletContextListener는 전부 실행된다.

 

 

728x90
반응형