본문 바로가기
학원/servlet jsp

11.7일 (jsp 기본 객체/ 액션 태그/ 에러 페이지/ 쿠키)

by 쿠룽지 2023. 11. 8.
728x90
반응형
728x90

 

JSP

<복습>

 

스크립트 : 동적으로 출력 결과를 생성하기 위해 사용

<스크립트 요소>

  • 선언부(Declaration) - 변수 선언, 메서드 선언 <%! %>
  • 스크립트릿(Scriptlet) - 자바 코드를 실행 / 변수 선언, 연산, 제어문 사용, 출력 등 <% %>
  • 표현식(Expression) - 연산, 출력(변수의 값, 메서드의 결과 값) <%= %>\

 


 

 

기본 객체

JSP가 제공하는 기본 객체

기본객체 실제 타입 설명
request javax.servlet.http.HttpServletRequest 클라이언트의 요청 정보를 저장한다.
response javax.servlet.http.HttpServletResponse 응답 정보를 저장한다.
pageContext javax.servlet.jsp.PageContext JSP페이지에 대한 정보를 저장한다.
session javax.servlet.http.HttpSession HTTP 세션 정보를 저장한다.
application javax.servlet.ServletContext 웹 어플리케이션에 대한 정보를 저장한다.
out javax.servlet.jsp.JspWriter JSP 페이지가 생성하는 결과를 출력할 때 사용되는 출력 스트림이다.
config javax.servlet.ServletConfig JSP 페이지에 대한 설정 정보를 저장한다.
page java.lang.Object JSP 페이지를 구현한 자바 클래스 인스턴스이다.
exception java.lang.Throwable 예외 객체. 에러 페이지에서만 사용된다.

 

1) request: 웹 브라우저가 웹 서버에 전송한 요청 관련 정보 제공

  • 주요기능
    • 클라이언트(웹 브라우저)와 관련된 정보 읽기
    • 서버와 관련된 정보 읽기
    • 클라이언트가 전송한 요청 파라미터 읽기
    • 클라이언트가 전송한 요청 헤더 읽기
    • 클라이언트가 전송한 쿠키 읽기
    • 속성 처리

 

2) response: 웹 브라우저에 전송하는 응답 정보 설정

  • 주요기능
    • 헤더 정보 입력
    • 리다이렉트 처리

리다이렉트

 

 

 

client -> (요청) -> a.jsp -> (리다이렉트) -> b.jsp

client -> (재요청) -> b.jsp -> (전송) - > client

 

 

 

ch05-ServletMain

webapp

ch03-nestedObject

s09_responseA.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>response.sendRedirect() 테스트</title>
</head>
<body>
현재 페이지는 s09_responseA.jsp 입니다. 화면에 보여지지 않습니다.
</body>
</html>
<%
	response.sendRedirect("s10_responseB.jsp"); //같은 경로라 파일명만 기재
%>

 

 

 

ch03-nestedObject

s10_responseB.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>s10_responseB.jsp</title>
</head>
<body>
현재 페이지는 s10_responseB.jsp입니다.
</body>
</html>

 

<% response.sendRedirect("경로"); %> 라고 지정하면 경로로 리다이렉트 됨

s09 A -> 실행 -> s10 B url/ 내용 전송+호출

 

출력 결과

 

 


 

 

JSP 디렉티브 ( <%@ %> ) 속성 中 Buffer

 

buffer 버퍼 사용 여부 및 크기 지정(기본값 : 8kb)
autoFlush 버퍼가 다 찼을 때 처리 방식 지정
true - 버퍼가 다 찼을 경우 버퍼를 플러시하고 계속해서 작업
false - 버퍼가 다 찼을 경우 예외를 발생시키고 작업 중지

buffer

자바에서의 버퍼와 비슷하게 기본값인 8kb를 넘어 버퍼가 차버리면 플러시함

 

autoFlush

true - 버퍼가 다 찼을 경우 버퍼를 플러시하고 계속해서 작업

false - 버퍼가 다 찼을 경우 예외를 발생시키고 작업 중지

 

autoFlush랑 buffer는 기본적으로 건드릴 일이 거의 없는데 이해를 위해 만든 예제

 

 

 

autoFlush = False 예제

ch03-nestedObject

s11_autoFlushFalse.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page buffer="1kb" autoFlush="false" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>autoFlush 속성값 false 예제</title>
</head>
<body>
<%
	for(int i=0; i<1000; i++){
%>
1234
<%		
	}
%>
</body>
</html>

 

빠른 결과를 위해 buffer의 크기를 1kb로 줄이고 autoFlush=false값 설정

buffer가 다 차면 autoFlush로 보내는데 그게 안되니까 java.io.IOException: 오류: JSP 버퍼 오버플로우 예외 발생

 

 

 

autoFlush = true 예제

ch03-nestedObject

s11_autoFlushTrue.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page buffer="1kb" autoFlush="true" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>autoFlush 속성값 true 예제</title>
</head>
<body>
<%
	for(int i=0; i<1000; i++){
%>
1234
<%		
	}
%>
</body>
</html>

 

1kb지만 flush 가능해서 에러 없이 정상 출력

 

 


 

 

3) out: JSP 페이지가 생성하는 모든 내용은 out 기본 객체를 통해 전송

지금까지 쓰던 out.println() 이 여기에 해당

버퍼 크기/ autoFlush도 출력 가능함

 

 

ch03-nestedObject

s13_bufferInfo.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>버퍼 정보</title>
</head>
<body>
버퍼 크기 : <%= out.getBufferSize() %><br>
남은 크기 : <%= out.getRemaining() %><br>
auto flush : <%= out.isAutoFlush() %>
</body>
</html>

 

[출력 결과]

버퍼 크기 : 8192
남은 크기 : 8068
auto flush : true

 

 

 

버퍼 크기 : out.getBufferSize()

남은 크기 : out.getRemaining()

auto flush : out.isAutoFlush()

 

 


 

JSP가 제공하는 기본 객체

기본객체 실제 타입 설명
request javax.servlet.http.HttpServletRequest 클라이언트의 요청 정보를 저장한다.
response javax.servlet.http.HttpServletResponse 응답 정보를 저장한다.
pageContext javax.servlet.jsp.PageContext JSP페이지에 대한 정보를 저장한다.
session javax.servlet.http.HttpSession HTTP 세션 정보를 저장한다.
application javax.servlet.ServletContext 웹 어플리케이션에 대한 정보를 저장한다.
out javax.servlet.jsp.JspWriter JSP 페이지가 생성하는 결과를 출력할 때 사용되는 출력 스트림이다.
config javax.servlet.ServletConfig JSP 페이지에 대한 설정 정보를 저장한다.
page java.lang.Object JSP 페이지를 구현한 자바 클래스 인스턴스이다.
exception java.lang.Throwable 예외 객체. 에러 페이지에서만 사용된다.

데이터를 저장 및 공유할 수 있는 객체 -> 아래로 갈수록 공유 범위가 넓음
pageContext : JSP페이지에 대한 정보 저장
request : 하나의 HTTP 요청을 처리할 때 사용되는 영역
session : 하나의 웹 브라우저와 관련된 영역
application : 하나의 웹 어플리케이션과 관련된 영역

 

 

 

기본객체와 영역 (공유범위) 을 알아보기 위해 A페이지에서 데이터 저장 후 B페이지에서 호출하는 예제 작성

 

 

ch03-nestedObject

s14_scopeA.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>JSP 4개 기본 객체와 영역</title>
</head>
<body>
<%
							//속성명	속성값
	pageContext.setAttribute("msg1","봄");
	request.setAttribute("msg2", "여름");
	session.setAttribute("msg3", "가을");
%>
page 영역의 msg1 = <%= pageContext.getAttribute("msg1") %><br>
request 영역의 msg2 = <%= request.getAttribute("msg2") %><br>
session 영역의 msg3 = <%= session.getAttribute("msg3") %>
</body>
</html>
<!--
[출력 화면]
page 영역의 msg1 = 봄
request 영역의 msg2 = 여름
session 영역의 msg3 = 가을
 -->

 

 

 

 

s15_scopeB.jsp  (읽기 전용)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>JSP 4개 기본 객체와 영역</title>
</head>
<body>
page 영역의 msg1 = <%= pageContext.getAttribute("msg1") %><br>
request 영역의 msg2 = <%= request.getAttribute("msg2") %><br>
session 영역의 msg3 = <%= session.getAttribute("msg3") %>
</body>
</html>
<!--
[출력 화면]
page 영역의 msg1 = null
request 영역의 msg2 = null
session 영역의 msg3 = 가을
 -->

 

1) pageContext

호출하는 jsp 하나당 하나의 pageContext 가 있음

그래서 A가 A의 pageContext 에 msg1을 생성하고 접근해서 호출할 수 있지만

B는 A의 pageContext 에 접근 자체를 하지 못하기 때문에 호출이 불가능함

 

2) request

pageContext와 동일하게 A와 B의 request가 따로 있음 (공유 범위가 1:1 대응 방식)

그러나 pageContext보다는 forward / include 액션 태그 등을 사용해서 request를 확장시킬 수 있음

 

3) session

A 호출 시 container에서 session이 만들어짐 / A -> 데이터전송 -> session

B 또한 A가 쓰고있는 session을 공유할 수 있음

그러나 브라우저가 열려있는 동안만 공유 가능함 (닫히면 세션 공유 불가능)

세션 = 브라우저 / 클라이언트를 식별하기 위한 것

브라우저가 닫히면 또 새로운 세션이 만들어짐

 

++ 새로운 세션 만드는 법

위에서 말했듯이 브라우저가 닫히면 새로운 세션이 만들어지기 때문에

s14 실행 후 창 닫고 s15를 실행하면 session 영역도 msg3의 가을이 아닌 null값이 나옴

 

기존 세션을 사용하고 싶다면 창을 끄지 마시오

 


 

 

application: 하나의 웹 어플리케이션과 관련된 영역

브라우저를 켜든 끄든 상관없이 호출됨

 

 

ch03-nestedObject

s16_setApplication.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Application에 데이터 저장</title>
</head>
<body>
<%
	String name = "userId";
	String value = "dragon";
	//application에 데이터 저장
							//속성명 속성값
	application.setAttribute(name, value);
%>
application 기본 객체의 속성 설정 : <%= name %> = <%= value %>
</body>
</html>

 

 

 

 

 

s17_getApplication.jsp (읽기 전용)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.util.Enumeration" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>application에 저장된 데이터 읽기</title>
</head>
<body>
<%
	Enumeration<String> attrEnum = application.getAttributeNames();
	while(attrEnum.hasMoreElements()){
		String name = attrEnum.nextElement();
		Object value = application.getAttribute(name);
%>
	application 속성 : <b><%= name %></b> = <%= value %><br>
<%
	}
%>
</body>
</html>

 

위 객체들과는 다른 점

디렉티브에 enumeration import (반환하는 타입이 numeration이라서 import)  

                   page import = "java.util.Enumeration"

 

 

application의 모든 속성을 다 읽어오려고 배열로 넣었음

브라우저를 꺼도 속성이 사라지진 않는데 지우고 싶다면 removeattribute를 쓰거나 아예 서버를 껐다 켜면 됨

 

 

공유범위가 넓기 때문에 application에 정보를 저장하게 된다면 보안상의 문제가 발생

클라이언트를 인식하는건 세션

application은 모든 클라이언트가 이 application을 공유함 (a client가 저장한걸 b client가 수정할 수도 있다는 것)

 

그래서 데이터를 보관하는건 주로 세션에 저장하고 (타 클라이언트의 변경/ 삭제/ 가져가기 제지)

어플리케이션은 설정 정보를 관리하는 편

 

 


 

 

request 실습

s18_orderForm.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>음식 배송</title>
<style type="text/css">
h2{
	text-align:center;
}
table{
	border-collapse:collapse; /*테이블 줄 하나로 만드는 거*/
	border:1px solid gray;
	width:500px;
	margin:0 auto;
}
td{
	height:30px;
	border:1px solid gray;
}
td.title{
	width:100px;
	text-align:center;
	background-color:ivory;
	font-weight:bold;
	color:#ff6600;
	padding:0 10px;
}
input[type="number"]{
	text-align:right;
	width:50px;
	height:19px;
}
ul{
	list-style:none;
	padding:0 10px;
	margin:5px;
}
li{
	display:inline;
}

</style>
</head>
<body>
<%--
[실습]
짜장면 4,000원, 짬뽕 5,000원, 볶음밥 6,000원

[출력 예시]
짜장면 2개
짬뽕 1개
총 지불 금액 : 13,000원

0으로 전달된 것은 표시x
 --%>
<h2>주문서</h2>
<form action="s19_order.jsp" method="post">
	<table>
		<tr>
			<td class="title">식사류</td>
			<td>
				<ul>
					<li>
						<label for="c0">짜장면</label>
						<input type="number" name="food_c0" id="c0" min="0" max="99" value="0">
					</li>
					<li>
						<label for="c1">짬뽕</label>
						<input type="number" name="food_c1" id="c1" min="0" max="99" value="0">
					</li>
					<li>
						<label for="c2">볶음밥</label>
						<input type="number" name="food_c2" id="c2" min="0" max="99" value="0">
					</li>
				</ul>
			</td>
		</tr>
		<tr align="center">
			<td colspan="2">
				<input type="submit" value="전송">
			</td>
		</tr>
	</table>
</form>
</body>
</html>

 

 

 

 

 

s19_order.jsp 작성

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>주문 내역</title>
</head>
<body>
<%
	int[] orderArray = {4000,5000,6000};
	int total = 0;
	String orderName = ""; //주문내역
	
	//전송된 데이터 인코딩 처리
	request.setCharacterEncoding("utf-8");
	
	//전송된 데이터 반환
	int food_c0 = Integer.parseInt(request.getParameter("food_c0")); //짜장면
	int food_c1 = Integer.parseInt(request.getParameter("food_c1")); //짬뽕
	int food_c2 = Integer.parseInt(request.getParameter("food_c2")); //볶음밥
	
	//조건체크
	if(food_c0 > 0){
		total += orderArray[0] * food_c0;
		orderName += "짜장면 " + food_c0 + "개<br>";
	}
	if(food_c1 > 0){
		total += orderArray[1] * food_c1;
		orderName += "짬뽕 " + food_c1 + "개<br>";
	}
	if(food_c2 > 0){
		total += orderArray[2] * food_c2;
		orderName += "볶음밥 " + food_c2 + "개<br>";
	}
%>
<%= orderName %>
총 지불 금액 : <%= String.format("%,d원", total) %>

</body>
</html>

 

내가 놓친 부분 -> input type="number" 의 값을 수 그자체로 읽어서 처리..!

그래서 읽어올 때도 하나하나 읽어와서 계산했음 Integer.parseInt 처리하고 orderArray[n] * food_cn 해서 가격 계산

 

 

 

 

form 자바스크립트 유효성 체크 기능 추가

1) 적어도 하나는 주문해서 넘길 수 있도록 수정

 

2) input number 안에 기본값인 0이 아닌 숫자를 완전히 지울 수 있는데

그런 빈 문자열을 전송했을 시에 수량 입력하라는 메시지 띄우기

 

<script type="text/javascript">
window.onload = function(){
	//submit이 form 하위니까 form에 접근 (접근할 수 있도록 form에 id 지정)
	let myForm = document.getElementById('myForm');
	//이벤트 연결
	myForm.onsubmit = function(){
		let items = document.querySelectorAll('input[type="number"]');
		
		for(let i=0; i<items.length;i++){
			if(items[i].value==''){ //'' -> 기본 value인 0 자체를 지운 것
				let label = document.querySelector('label[for="'+items[i].id+'"]');
				alert(label.textContent + '의 수량을 입력하세요.');
				items[i].value = 0;
				items[i].focus();
				return false;
			}
		}
		if(items[0].value==0 && items[1].value==0 && items[2].value==0){
			alert('세가지 음식 중 하나는 꼭 주문해야 합니다.');
			return false;
		}
	};
};
</script>

 

 

 

 


 

 

 

include 디렉티브

: jsp 페이지 내에 또다른 jsp 페이지를 삽입할 수 있음 (공통적으로 사용하는 내용)

선언부에서 함수/ 메서드를 만들면 공유가 안돼서 재사용성이 낮은데 include 디렉티브를 사용하면 공유 가능

 

 

ch04-include

include.jspf (확장자명 jspf / 변수를 공유하는 게 목적인 확장자)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
String img_path = "../images";
String file_path = "../files";
%>

 

내용이 필요가 없기 때문에 다 지우고 공유할 내용만 명시

 

 

 

ch04-include

main01.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="include.jspf" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>include 디렉티브</title>
</head>
<body>
<%--
include 디렉티브를 이용하면 JSP 페이지에 또다른 JSP를 삽입할 수 있음
변수 공유를 목적으로 사용함
 --%>
이미지 경로 : <%= img_path %><br>
파일 경로 : <%= file_path %>
</body>
</html>
<%--
[출력 화면]
이미지 경로 : ../images
파일 경로 : ../files
 --%>

 

<%@ include file = "include.jspf" %> 삽입 후 공유

 

 

하나의 파일이 아닌 여러 파일에 삽입해서 사용 가능

ch04-include

main02.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="include.jspf" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>include 디렉티브</title>
</head>
<body>
이미지 표시 : <%= img_path %>/Koala.jpg  <br>
파일 표시 : <%= file_path %>/Penguins.jpg
</body>
</html>
<%--
[출력화면]
이미지 표시 : ../images/Koala.jpg
파일 표시 : ../files/Penguins.jpg
--%>

 

 

 


 

 

<jsp:include> 액션 태그 : 다른 jsp 페이지의 '실행' 결과를 현재 위치에 삽입

include와는 달리 jsp 안에 jsp를 삽입하는데 html의 태그를 공유 (변수 공유 불가능) / top, left, bottom 기억!

 

 

include와의 차이점

비교항목 <jsp:include/> include 디렉티브
처리시간 요청 시간에 처리 JSP 파일을 자바 소스로 변환할 때 처리
기능 별도의 파일로 요청 처리 흐름을 이동 현재 파일에 삽입시킴
데이터 전달 방법 request 기본 객체나 <jsp:param>을 이용한 파라미터 전달 페이지 내의 변수를 선언한 후, 변수에 값 지정
용도 화면의 레이아웃의 일부분을 모듈화할 때 주로 사용된다. 다수의 JSP 페이지에서 공통으로 사용되는 변수를 지정하는 코드나 저작권과 같은 문장을 포함

 

 

 

ch05-actionTag(folder)

module(folder)

top.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	String company = request.getParameter("company");
%>    
<!-- 상단 시작 -->
<b><%= company %></b>
상단 메뉴 : 
<a href="#">HOME</a>
<a href="#">INFO</a>
<a href="#">SERVICE</a>
<!-- 상단 끝 -->

 

String company = request.getParameter("company"); 를 넣어서 값이 <%=company%> 부분에 들어가게 함

 

 

 

 

module

left.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!-- 좌측 메뉴 시작 -->
좌측 메뉴<br>
<a href="#">회사소개</a><br>
<a href="#">제품소개</a><br>
<a href="#">상담실</a><br>
<!-- 좌측 메뉴 끝 -->

 

 

 

module

bottom.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!-- 하단 시작 -->
 &copy; 코리아 홈쇼핑
<!-- 하단 끝 -->

 

 

 

 

ch05-actoinTag

layout.jsp (module 밖)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	//전송된 데이터 인코딩 처리
	request.setCharacterEncoding("utf-8");
%>    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>페이지 모듈화</title>
<style type="text/css">
table{
	border-collapse:collapse;
	border:1px solid #000000;
	width:500px;
	margin:0 auto;
}
td{
	border:1px solid #000000;
	text-align:center;
	vertical-align:middle;
	height:40px;
}
td.td-middle{
	text-align:left;
	vertical-align:top;
	height:200px;
}
td.td-width{
	width:100px;
}
</style>
</head>
<body>
<table>
	<tr>
		<td colspan="2">
		    <%-- include 태그의 내용으로 html 주석, JSP 주석 전부 사용 불가  --%>
			<jsp:include page="/ch05-actionTag/module/top.jsp">
				<jsp:param value="코리아 홈쇼핑" name="company"/>
			</jsp:include>
		</td>
	</tr>
	<tr>
		<td class="td-middle td-width">
			<jsp:include page="/ch05-actionTag/module/left.jsp"/>
		</td>
		<td class="td-middle">
			<!-- 내용 시작 -->
			레이아웃1
			<!-- 내용 끝 -->
		</td>
	</tr>
	<tr>
		<td colspan="2">
			<jsp:include page="/ch05-actionTag/module/bottom.jsp"/>
		</td>
	</tr>
</table>
</body>
</html>

 

다 들어가 있는 모습 확인 가능

include 기법을 사용할 때에는 하나의 request를 공유함 그래서 layout.jsp에 include한 top / left / bottom 3개의 jsp가 하나의 request에 있고, 그걸 뽑아쓰는거임

 

 


 

 

<jsp: forward> 액션 태그 (같은 서버에서만 가능)

 

redirect 와 비슷해보이지만 많이 다름 

메서드 특징
forward

<jsp:forward />
같은 웹서버, 같은 웹 애플리케이션 디렉토리에 속하는 웹 자원만 호출 가능
request 내장 객체를 통해 데이터를 전달
redirect
response.sendRedirect()
다른 웹 서버에 있는 웹 자원도 호출할 수 있음
호출할 JSP페이지의 URL 뒤에 데이터를 붙여서 전달

 

**encoding은 처음 액세스하기 전 보내야함

 

 

 

ch05-actionTag

forwardA.jsp

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>포워드 테스트</title>
</head>
<body>
forwardA.jsp 페이지. 보여지지 않습니다.
</body>
</html>
<%
	//전송된 데이터 인코딩
	request.setCharacterEncoding("utf-8");
%>
<jsp:forward page="forwardB.jsp">
	<jsp:param value="오렌지" name="color"/>
</jsp:forward>

 

 

 

 

forwardB.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>forwardB.jsp</title>
</head>
<body>
forwardB.jsp 페이지<br>
request에 파라미터로 전송된 데이터 = <%= request.getParameter("color") %>
</body>
</html>

 

 

출력결과

forwardA 주소 + forwardB 내용 

 

 


 

 

jsp는자바의 에러와는 달리 돌발적으로 동작이 멈춰도 기본적으로 container가 만들어준 페이지를 전송함

그때 에러 페이지가 만들어지는데 생성할 수 있음

 

에러 페이지 생성하는 방법 (우선순위 순)

1) 페이지 내 직접 지정 (page errorPage)

2) 예외타입 별 지정 (exception-type)

3) 응답상태 코드 별 지정 (404, 500 ,...)

4) 지정X (container 기본 페이지)

 

2,3 번은 xml 에 추가하기 때문에 restart 해야함 (window-showview-other-server-우클릭-restart)

 

 

 

 

 

1. 직접 지정

 

ch06-errorPage 

readParameter.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%-- 에러가 발생할 때 보여질 페이지 지정 --%>
<%@ page errorPage="/ch06-errorPage/error/viewErrorMessage.jsp" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>파라미터 출력</title>
</head>
<body>
name 파라미터 값 : <%= request.getParameter("name").toUpperCase() %>
</body>
</html>
<%-- request안에 name값이 없어서 에러가 날 수밖에 없는 페이지 --%>

에러 페이지 지정: <%@ page errorPage = "예외발생시보여질JSP지정" %>

 

 

 

error

viewErrorMessage.jsp (페이지 안에 직접 지정하는 방식)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%-- isErrorPage="true" 이면 동작하는 페이지임 (에러가 발생했을 때 보여지는 페이지) --%>
<%@ page isErrorPage="true" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>에러 발생</title>
</head>
<body>
요청 처리 과정에서 예외가 발생했습니다.<br>
빠른 시간 내에 문제를 해결하도록 하겠습니다.
<p>
에러 타입 : <%= exception.getClass().getName() %><br>
에러 메시지 : <%= exception.getMessage() %>
</p>
</body>
</html>

에러 페이지 작성 : <%@ page isErrorPage = "true" %>

번거롭기 때문에 이 방법은 권장하진 않음

 


 

ch05-errorPage(folder)

readParameter2.jsp

error를 발생시킬 페이지 먼저 작성 (500에러 + url 주소 뒤에 /+아무렇게나 타이핑 -> 404 에러)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>파라미터 출력</title>
</head>
<body>
name 파라미터 값 : <%= request.getParameter("name").toUpperCase() %> <%--null pointer exception 500 발생 --%>
</body>
</html>

 

 


 

2) 에러 타입별 지정 (web.xml 에서 설정)

더보기

<문법>

<error-page>
                   <exception-type>예외클래스명</exception-type>
                   <location>에러페이지의 URI</location>
</error-page>

 

 

 

web-inf

web.xml     source

<error-page>
	<exception-type>java.lang.NullPointerException</exception-type>
    <location>/ch06-errorPage/error/errorNullPointer.jsp</location>
</error-page>

*html -> ui 관리 / xml -> 데이터 관리 // html 주석과 xml 주석은 같음

restart

 

 

 

 

error

errorNullPointer.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>NULL 에러 발생</title>
</head>
<body>
<h1>NULL</h1>
<b>서비스 처리 과정에서 NULL 예외가 발생했습니다.</b>
</body>
</html>

 

 

 

readParameter2.jsp 실행하면 errorNullPointer.jsp 가 뜸


 

 

3) 응답상태 코드 별 에러 페이지 지정

 

<주요 HTTP Status Code 표>

HTTP Status Code 메시지
200 OK, 에러 없이 전송이 성공 (정상)
403 Forbidden(금지) 서버가 허용하지 않는 웹 페이지나 미디어를 사용자가 요청할 때
404 Not Found, 문서를 찾을 수 없음. 이 에러는 클라이언트가 요청한 문서를 찾지 못한 경우에 발생. URL을 다시 잘 보고 주소가 올바로 입력되었는지를 확인.
500 Internal Server Error(서버 내부 오류). 이 에러는 웹 서버가 요청사항을 수행할 수 없을 경우에 발생.

 

 

web-inf

web.xml

<!-- 응답 상태 코드별 에러 페이지 지정 시작 -->
<error-page>
	<error-code>404</error-code>
    <location>/ch06-errorPage/error/error404.jsp</location>
</error-page>
<error-page>
	<error-code>500</error-code>
    <location>/ch06-errorPage/error/error500.jsp</location>
</error-page>
<!-- 응답 상태 코드별 에러 페이지 지정 끝 -->

restart

 

 

 

error404.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>404 에러 발생</title>
</head>
<body>
<h1>404</h1>
<b>요청한 페이지는 존재하지 않습니다.</b><br><br>
주소를 올바르게 입력했는지 확인해보시기 바랍니다.
</body>
</html>

 

 

 

 

error500.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>500 에러 발생</title>
</head>
<body>
<h1>500</h1>
<b>페이지 호출 시 오류가 발생했습니다.</b><br>
잠시 후에 다시 사용하시기 바랍니다.
</body>
</html>

 

 

 

readParameter2.jsp 실행하면 각 에러 코드에 맞춰서 jsp 에러 파일 보임

 

exception-type

error-code 제외하고 똑같음

 

 


 

 

쿠키 : 웹 브라우저가 보관하고 있는 데이터

웹 서버(생성) -> 클라이언트(저장) -> 웹 서버 (계속 주거니 받거니 함)

쿠키는 서버에서 만들고 웹 브라우저로 전송하는 것

 

서버가 생성하긴 하는데 클라이언트 정보를 얻고 클라이언트 쪽에 보관 및 저장하는 역할을 함
pc를 꺼도 정보가 남아있음 (쿠키의 유효기간을 설정하면 그 기간동안 pc를 꺼도 살아있음)

 

 

웹 스토리지와 비슷하지만 차이점이 있음
웹 스토리지: 서버를 호출하지만 서버와는 무관하게 클라이언트 영역에 있는 것
쿠키: 보관은 클라이언트에 있지만 서버에 제공을 함 사용하는 것도 서버임

 

쿠키

 

 

 

구성요소

  • 이름 - 각각의 쿠키를 구별하는 데 사용되는 이름
  • 값 - 쿠키의 이름과 관련된 값
  • 유효시간 - 쿠키의 유지 시간
  • 도메인 - 쿠키를 전송할 도메인
  • 경로 - 쿠키를 전송할 요청 경로

 

 

쿠키 객체 생성

ch07-cookie(folder)

makeCookie.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.net.URLEncoder" %> <%-- 한글일 경우에는 깨지기 때문에 encoding을 해야함 --%>
<%
	Cookie cookie = new Cookie("name",URLEncoder.encode("홍길동", "UTF-8")); //cookie는 name:value의 쌍으로 만듦/ encode("값,encode형식")
	//쿠키 유효시간 지정(단위:초)
	//쿠키 유효시간을 지정하면 클라이언트 영역에 파일을 생성해서 쿠키 정보를 보관함
	//쿠키 유효시간을 지정하지 않으면 메모리에 쿠키 정보를 보관
	//cookie.setMaxAge(30*60);
	//cookie.setMaxAge(-1); //메모리에 쿠키 정보 보관 (끄면 사라짐)
	
	//생성한 쿠키를 클라이언트로 전송
	response.addCookie(cookie);
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>쿠키 생성</title>
</head>
<body>
 <%--		쿠키명						쿠키값 --%>
<%= cookie.getName() %> = <%= cookie.getValue() %>
</body>
</html>

영어 객체는 상관없는데 한글 객체를 생성하고 싶으면 인코딩을 해야함

 

 

 

쿠키 읽기

ch07-cookie

viewCookies.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page.import = "java.net.URLDecoder" %> <%-- 아까 인코딩해서 쿠키를 저장했으니 디코딩을 해야함 --%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>쿠키 목록</title>
</head>
<body>
쿠키 목록<br>
<%
	//클라이언트로부터 전송된 쿠키 정보를 반환
	Cookie[] cookies = request.getCookies(); //쿠키가 session에서 만든 것까지 2개라서 배열로 처리
    if(cookies!=null && cookies.length>0){
    	for(int i=0; i<cookies.length; i++){
%>
					<%-- 쿠키는 key:value형태라서 getName, getValue로 정보를 읽음 --%>
		<%= cookies[i].getName() %> = <%= URLDecoder.decode(cookies[i].getValue(), "UTF-8") %><br>

<%			
		}
	}else{
%>
쿠키가 존재하지 않습니다.
<%		
	}
%>
</body>
</html>
<%--
브라우저가 열려있는 상태에서 해야 쿠키가 저장됨 (유효시간을 안줘서)

[출력]
쿠키 목록
name = 홍길동
JSESSIONID = AF0D2E238F0BE87DE5F5CE4B2AA9F7F2 / << session에서 만든거
--%>

 

 

 

쿠키값 변경

modifyCookie.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.net.URLEncoder" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>쿠키 값 변경</title>
</head>
<body>
<%
	//클라이언트로부터 전송된 쿠키 정보를 반환
	Cookie[] cookies = request.getCookies();
	if(cookies!=null && cookies.length>0){ //쿠키 정보가 존재함
		for(int i=0; i<cookies.length; i++){
			//쿠키명이 name인 쿠키를 검색해서 존재하면 쿠키 값을 변경
			if(cookies[i].getName().equals("name")){ //문자열을 비교하기 때문에 equals 사용
				Cookie cookie = new Cookie("name", URLEncoder.encode("JSP프로그래밍","UTF-8")); // 같은 이름으로 덮어씌워서 변경
				//생성한 쿠키를 클라이언트에 전송
				response.addCookie(cookie);
				
				out.println("name 쿠키의 값을 변경했습니다.");
			}
		}
	}else{
		out.println("쿠키가 존재하지 않습니다.");
	}
%>
</body>
</html>
<%--
쿠키 변경 순서

1) 클라이언트로부터 전송된 쿠키 정보 반환
2) if문으로 쿠키 값 있는지 확인
3) 쿠키 배열 돌면서 getName().equals 로 값 찾기
4) 있다면 덮어씌우는 방식으로 값 변경
5) 클라이언트로 덮어씌운 쿠키 전송

makeCookie 실행시키고 브라우저 안 끈 상태로 이거 실행해보기
그러면  out.println("name 쿠키의 값을 변경했습니다.");
viewCookie 다시 실행하면 바뀐 값으로 나옴
--%>

 

 

 

쿠키 삭제

deleteCookie.jsp

modify랑 거의 유사 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>쿠키 삭제</title>
</head>
<body>
<%
	//클라이언트로부터 전송된 쿠키 정보를 반환
	Cookie[] cookies = request.getCookies();
	if(cookies!=null && cookies.length>0){ //쿠키 정보가 존재함
		for(int i=0; i<cookies.length; i++){
			//쿠키명이 name인 쿠키를 검색해서 존재하면 쿠키 삭제
			if(cookies[i].getName().equals("name")){ //문자열을 비교하기 때문에 equals 사용
				Cookie cookie = new Cookie("name",""); // 어차피 삭제할거라서 값은 명시x
				cookie.setMaxAge(0); //쿠키를 삭제하기 위해 유효시간 0으로 수정 (쿠키 정보 제거)
				//생성된 쿠키를 클라이언트에 전송
				response.addCookie(cookie);
				
				out.println("name 쿠키를 삭제합니다");
			}
		}
	}else{
		out.println("쿠키가 존재하지 않습니다.");
	}
%>
</body>
</html>
<%--
remove cookie이런 게 있는 게 아니라 그냥 유효시간을 만료시켜서 쿠키를 삭제함
--%>

 

 

* 쿠키는 클라이언트에 저장되기 때문에 개인정보 같은건 쿠키에 안 넣는게 좋다..!

 

728x90
반응형