<%@ include file="포함할 파일" %>
ch04-include
생성하고 새 JSP 파일 main.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 %><br> <%-- include한 jspf 코드는 같은 파일 내에 있는 코드로 인식되기 때문에, jspf에서 만든 변수를 직접 읽어올 수 있음 --%>
파일 경로 : <%= file_path %>
</body>
</html>
include.jspf
생성
jsp
여도 다른 JSP 파일에 include될 수 있지만, 확장자를 jspf
로 지정하면 해당 파일이 단독으로 사용되지 않음을 나타냄<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%> <%-- 한글로 주석 작성하는 경우, jspf 파일 내에서도 page 디렉티브로 인코딩 방식을 (include되는 JSP 파일과 동일하게) 설정해야 함 --%>
<%
String img_path = "/image";
String file_path = "/file";
%>
<jsp:include>
액션 태그<jsp:include>
액션 태그로 처리하면 디자인이나 내용 변경시 하나의 파일만 변경하면 되므로 유지보수하기 좋음jsp:
접두사를 붙여 구별하며, jsp:
접두사가 붙은 태그는 서블릿으로 변환됨<jsp:include> |
include 디렉티브 | |
---|---|---|
처리 시간 | 요청 시간에 처리 | JSP 파일을 자바 소스로 변환할 때 처리 |
변수 공유 | 불가능 | 가능 |
기능 | 별도의 파일로 요청 처리 흐름을 이동 | 현재 파일에 삽입시킴 |
데이터 전달 방법 | request 기본 객체나 <jsp:param/> 을 이용한 파라미터 전달 |
페이지 내에 변수를 선언한 후, 변수 값 지정 |
용도 | 화면 레이아웃의 일부분을 모듈화할 때 주로 사용 | 다수의 JSP 페이지에서 공통으로 사용되는 변수를 지정하는 코드나 저작권과 같은 문장을 포함 |
ch05-actionTag
생성하고 하위 폴더로 module
생성 후 module
폴더에 새 JSP 파일 top.jsp
생성<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%> <%-- 한글이 포함되면 반드시 page 디렉티브로 인코딩 방식을 설정해야 함 --%>
<%-- 다른 페이지에 삽입될 것이므로 전체적인 <HTML> 구조는 중복되지 않게 삭제해야 함 --%>
<% String company = request.getParameter("company"); %>
<b><%= company %></b>
상단 메뉴 :
<a href="#">HOME</a>
<a href="#">INFO</a>
module
폴더에 새 JSP 파일 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
폴더에 새 JSP 파일 bottom.jsp
생성<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
하단 메뉴 : 소개 | 도움말 | 약관 | 사이트맵
ch05-actionTag
폴더에 새 JSP 파일 s01_layout.jsp
생성<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<% request.setCharacterEncoding("UTF-8"); %> <%-- <jsp:param/>으로 파라미터 전송시, request에 처음 액세스하는 것은 include된 JSP 파일이 아니라 include하는 JSP 파일이므로 인코딩 방식 설정도 include하는 JSP 파일에서 해야 전송되는 파라미터 값이 깨지지 않음 --%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>페이지 모듈화</title>
<style type="text/css">
table {
border:solid 1px #000;
border-collapse: collapse;
width: 500px;
margin: 0 auto;
}
td {
border: solid 1px #000;
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">
<%-- <jsp: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="module/left.jsp"/>
</td>
<td class="td-middle">
<!-- 내용 부분 : 시작 -->
레이아웃 1
<!-- 내용 부분 : 끝 -->
</td>
</tr>
<tr>
<td colspan="2">
<jsp:include page="module/bottom.jsp"/>
</td>
</tr>
</table>
</body>
</html>
<jsp:forward>
액션 태그<jsp:forward> |
response.sendRedirect() |
|
---|---|---|
호출 대상 | 같은 웹 서버, 같은 웹 애플리케이션 디렉토리에 속하는 웹 자원만 호출 가능 | 다른 서버에 있는 웹 자원도 호출 가능 |
전달 방식 | request 내장 객체를 통해 데이터를 전달 | 호출할 JSP 페이지의 URL 뒤에 데이터를 붙여서 전달 |
ch05-actionTag
폴더에 새 JSP 파일 s02_forwardA.jsp
생성<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
// 전송된 데이터 인코딩 처리; <jsp:param/>으로 파라미터 전송시, request에 처음 액세스하는 것은 forward된 JSP 파일이 아니라 forward하는 JSP 파일이므로 인코딩 방식 설정도 forward하는 JSP 파일에서 해야 전송되는 파라미터 값이 깨지지 않음
request.setCharacterEncoding("UTF-8");
%>
<%-- 포워드시 생략 가능한 영역 시작 --%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>포워드 테스트</title>
</head>
<body>
forwardA.jsp 페이지! 화면은 보여지지 않습니다.
</body>
</html>
<%-- 포워드시 생략 가능한 영역 끝 --%>
<jsp:forward page="s03_forwardB.jsp">
<jsp:param value="오렌지" name="color"/>
</jsp:forward>
ch05-actionTag
폴더에 새 JSP 파일 s03_forwardB.jsp
생성<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>s03_forwardB.jsp</title>
</head>
<body>
forwardB.jsp 페이지<br>
request에 파라미터로 전송된 데이터 = <%= request.getParameter("color") %>
</body>
</html>
web.xml
에 <error-page>
를 명시하는 방식이 권장됨ch06-errorPage
생성하고 하위 폴더로 error
생성 후 error
폴더에 새 JSP 파일 viewErrorMessage.jsp
생성<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page isErrorPage="true" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>예외 발생</title>
</head>
<body>
요청 처리 과정에서 예외가 발생했습니다.<br>
빠른 시간 내에 문제를 해결하도록 하겠습니다.
<p> <!-- 단독 <p> 태그는 <br><br>과 같음 -->
에러 타입 : <%= exception.getClass().getName() %><br> <%-- exception 객체는 에러 페이지(isErrorPage="true")에서만 호출 가능 --%>
에러 메시지 : <b><%= exception.getMessage() %></b>
</body>
</html>
ch06-errorPage
폴더에 새 JSP 파일 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() %> <%-- 없는 파라미터를 호출하면 null이 반환되는데, null에서 메서드를 호출하여 NPE를 발생시킴 --%>
</body>
</html>
web.xml
에서 설정
web.xml
설정 변경시 서버를 재시작해야 적용됨HTTP Status Code
Code | Status | |
---|---|---|
200 | OK | 에러 없이 전송 성공 |
403 | Forbidden | 서버가 허용하지 않는 웹 페이지나 미디어를 사용자가 요청할 때 |
404 | Not Found | 클라이언트가 요청한 문서를 찾지 못했을 때 |
500 | Internal Server Error | 웹 서버가 요청 사항을 수행할 수 없을 때 |
error
폴더에 새 JSP 파일 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>
<strong>요청한 페이지는 존재하지 않습니다.</strong>
<br><br>
주소를 올바르게 입력했는지 확인해보시기 바랍니다.
</body>
</html>
error
폴더에 새 JSP 파일 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>
<strong>페이지 호출시 오류가 발생했습니다.</strong>
<br><br>
잠시 후에 다시 사용하시기 바랍니다.
</body>
</html>
WEB-INF
폴더의 web.xml
를 열고, 왼쪽 하단의 Source
탭 선택 후 <web-app>
태그 사이에 다음의 내용을 추가 <!-- 응답 상태 코드별 에러 페이지 지정 시작 -->
<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>
<!-- 응답 상태 코드별 에러 페이지 지정 끝 -->
ch06-errorPage
폴더에 새 JSP 파일 readParameter2.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>
파라미터 출력 : <%= request.getParameter("name").toUpperCase() %>
</body>
</html>
web.xml
에서 설정error
폴더에 새 JSP 파일 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>
<strong>서비스 처리 과정에서 NULL 예외가 발생했습니다.</strong>
<br><br>
잠시 후에 다시 사용하시기 바랍니다.
</body>
</html>
WEB-INF
폴더의 web.xml
를 열고, 왼쪽 하단의 Source
탭 선택 후 <web-app>
태그 사이에 다음의 내용을 추가 <!-- 예외 타입별 에러 페이지 지정 시작 -->
<error-page>
<exception-type>java.lang.NullPointerException</exception-type>
<location>/ch06-errorPage/error/errorNullPointer.jsp</location>
</error-page>
<!-- 예외 타입별 에러 페이지 지정 끝 -->
web.xml
에서 <exception-type>
이 발생한 예외 타입과 일치하는 에러 페이지web.xml
에서 <error-code>
가 발생한 응답 상태 코드와 일치하는 에러 페이지ch07-cookie
생성하고 새 JSP 파일 s01_makeCookie.jsp
생성<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.net.URLEncoder" %>
<%
// 쿠키 생성; Cookie 클래스는 서블릿에 포함되어 있어 별도로 import할 필요 없음
Cookie cookie = new Cookie("name", URLEncoder.encode("너굴", "UTF-8")); // 생성자의 첫 번째 인자는 쿠키명, 두 번째 인자는 쿠키 값이며 한글 포함시 깨지지 않게 인코딩해서 인자로 전달해야 함
// 쿠키 유효 시간 지정(단위: 초)
// cookie.setMaxAge(30*60); // 쿠키 유효 시간을 지정하면 클라이언트 영역에 파일을 생성해서 쿠키 정보 보관
// cookie.setMaxAge(-1); // 쿠키 유효 시간을 지정하지 않거나 -1로 지정시 메모리에 쿠키 정보 보관(=브라우저 종료시 쿠키 만료)
// 생성된 쿠키를 클라이언트에 전송
response.addCookie(cookie);
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>쿠키 생성</title>
</head>
<body>
<%= cookie.getName() %> 쿠키의 값은 <%= cookie.getValue() %>
</body>
</html>
s02_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>
<h1>쿠키 목록</h1>
<%
// 클라이언트로부터 전송된 쿠키 정보를 반환
Cookie[] cookies = request.getCookies();
if(cookies!=null && cookies.length>0) {
for(int i=0;i<cookies.length;i++) {
%>
<%= cookies[i].getName() %> =
<%= URLDecoder.decode(cookies[i].getValue(), "UTF-8") %><br>
<%
}
}
else {
%>
쿠키가 존재하지 않습니다.
<%
}
%>
</body>
</html>
s03_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++) {
// 쿠키 값을 변경할 쿠키가 존재하는지 확인
if(cookies[i].getName().equals("name")) { // 쿠키명이 name인 쿠키 검색
// 동일한 이름으로 쿠키 생성
Cookie cookie = new Cookie("name", URLEncoder.encode("JSP 프로그래밍", "UTF-8"));
// 생성한 쿠키를 클라이언트에 전송
response.addCookie(cookie);
out.println("name 쿠키의 값을 변경합니다.");
}
}
}
else {
out.println("쿠키가 존재하지 않습니다.");
}
%>
</body>
</html>
s04_deleteCookie.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>
<%
// 쿠키 읽기
Cookie[] cookies = request.getCookies();
// 쿠키 존재 여부 확인
if(cookies!=null && cookies.length>0) {
for(int i=0;i<cookies.length;i++) {
// 삭제할 쿠키가 있는지 확인
if(cookies[i].getName().equals("name")) {
// 삭제할 쿠키와 동일한 이름의 쿠키를 생성
Cookie cookie = new Cookie("name", ""); // 삭제할 것이므로 value는 어떤 값이든 무관
cookie.setMaxAge(0); // 쿠키 정보 제거
// 생성된 쿠키를 클라이언트로 전송
response.addCookie(cookie);
out.println("name 쿠키를 삭제하였습니다.");
}
}
}
else {
out.println("쿠키가 존재하지 않습니다"); // 쿠키 배열이 만들어지지 않았거나, 쿠키 배열이 만들어졌지만 배열 안에 쿠키가 없는 경우
}
%>
</body>
</html>
ch03-nestedObject
폴더에 새 JSP 파일 s20_orderForm2.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">
table {
border-collapse: collapse;
border: 1px solid gray;
}
td {
border: 1px solid gray;
height: 30px;
}
td.title {
text-align: right;
background-color: ivory;
font-weight: bold;
color: #f60;
padding: 0 10px;
}
input[type="number"] {
text-align: right;
width: 50px;
height: 19px;
}
ul {
list-style: none;
padding: 0 10px;
margin: 5px;
}
ul li {
display: inline;
}
</style>
</head>
<body>
<h2>주문서</h2>
<form action="s21_order2.jsp" method="post" id="myForm">
<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>
<td colspan="2" align="center">
<input type="submit" value="전송">
</td>
</tr>
</table>
</form>
<script type="text/javascript">
document.getElementById('myForm').onsubmit = function() {
let c0 = document.getElementById('c0');
if(c0.value=='') { // number 필드는 숫자 및 공백 입력 가능; 사용자가 기본값 0을 지우고 공백만 입력한 경우
alert('짜장면의 수량을 입력하세요!');
c0.focus();
c0.value = 0;
return false;
}
let c1 = document.getElementById('c1');
if(c1.value=='') {
alert('짬뽕의 수량을 입력하세요!');
c1.focus();
c1.value = 0;
return false;
}
let c2 = document.getElementById('c2');
if(c2.value=='') {
alert('볶음밥의 수량을 입력하세요!');
c2.focus();
c2.value = 0;
return false;
}
if(c0.value==0 && c1.value==0 && c2.value==0) { // 아무것도 주문하지 않는 경우
alert('세 가지 음식 중 하나는 꼭 주문해야 합니다!');
return false;
}
/*
let nums = document.querySelectorAll('input[type="number"]');
let count = 0;
for(let i=0;i<nums.length;i++) {
if(!nums[i].value.trim()) { // 아무것도 입력하지 않거나 공백만 입력한 경우
nums[i].value = 0; // 입력된 값을 0으로 변경하여 JSP에서 NumberFormatException 발생을 방지
}
count += Number(nums[i].value); // HTML의 <input> 요소에서 입력받는 값은 문자열로 인식되며, type="number"는 사용자가 입력할 수 있는 값을 제한할 뿐 입력된 값의 자료형을 변경하지 않음; 즉, <input type="number">의 value 속성은 string을 반환하므로, 연산하기 위해서는 숫자로 변환해야 함
}
if(count===0) {
alert('1개 이상 주문해주세요!')
return false;
}
*/
};
</script>
</body>
</html>
s21_order2.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>
<!--
[실습 문제] 짜장면 4,000원, 짬뽕 5,000원, 볶음밥 6,000원
[출력 예시]
[주문 음식]
짜장면 2개
짬뽕 1개
총 지불 금액 : 13,000원
-->
<h2>주문서 확인</h2>
<%
// 전송된 데이터 인코딩 처리
request.setCharacterEncoding("UTF-8");
int[] orderArray = {4000, 5000, 6000};
int total = 0;
String orderName = "";
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>";
}
%>
[주문 음식]<br>
<%= orderName %>
총 지불 금액 : <%= String.format("%,d원", total) %>
<%--
<%
String[] food = {"짜장면", "짬뽕", "볶음밥"};
int[] price = {4000, 5000, 6000};
int[] count = new int[food.length];
for(int i=0;i<count.length;i++) {
count[i] = Integer.parseInt(request.getParameter("food_c" + i));
}
%>
[주문 음식]<br>
<%
int sum = 0;
for(int i=0;i<count.length;i++) {
if(count[i]>0) {
%>
<%= food[i] %> <%= count[i] %>개<br>
<%
}
sum += price[i] * count[i];
}
%>
총 지불 금액 : <%= String.format("%,d원", sum) %>
--%>
</body>
</html>