web.xml
에서 일괄적으로 지정하는 것이 권장됨ch08-session
생성하고 새 JSP 파일 s01_sessionInfo.jsp
생성<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.util.Date" %>
<%@ page import="java.text.SimpleDateFormat" %>
<%
Date time = new Date();
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>세션 정보</title>
</head>
<body>
세션 ID : <%= session.getId() %><br>
세션 생성 시간 : <%= session.getCreationTime() %><br> <%-- getCreationTime() 메서드는 1970년 1월 1일부터 세션 생성 시간까지의 경과 시간을 밀리초 단위, long 자료형의 값으로 반환 --%>
<%
// long 자료형의 시간을 Date 객체가 표시하는 연, 월, 일, 시, 분, 초로 변환
time.setTime(session.getCreationTime());
%>
세션 생성 시간 : <%= sf.format(time) %><br>
최근 접근 시간 : <%= session.getLastAccessedTime() %><br> <%-- getLastAccessedTime() 메서드는 1970년 1월 1일부터 세션 생성 시간까지의 경과 시간을 밀리초 단위, long 자료형의 값으로 반환 --%>
<%
time.setTime(session.getLastAccessedTime());
%>
최근 접근 시간 : <%= sf.format(time) %><br>
세션 유지 시간 변경하기(기본값: 30분)<br>
<%
// JSP 페이지 내에서 지정한 값은 web.xml에서 지정한 값보다 우선하며, 서버를 재시작하지 않아도 바로 적용됨
session.setMaxInactiveInterval(60*20); // 초 단위로 지정
%>
세션 유지 시간 : <%= session.getMaxInactiveInterval() %>초
</body>
</html>
WEB-INF
폴더의 web.xml
를 열고, 왼쪽 하단의 Source
탭 선택 후 <web-app>
태그 사이에 다음의 내용을 추가 <!-- 세션 유지 시간 지정 시작 -->
<session-config>
<session-timeout>50</session-timeout> <!-- 분 단위로 지정 -->
</session-config>
<!-- 세션 유지 시간 지정 끝 -->
s02_loginForm.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>
<form action="s03_login.jsp" method="post">
아이디 <input type="text" name="id" size="10"><br>
비밀번호 <input type="password" name="password" size="10"><br>
<input type="submit" value="로그인">
</form>
</body>
</html>
s03_login.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.setCharacterEncoding("UTF-8");
String id = request.getParameter("id");
String password = request.getParameter("password");
// 테스트용으로 ID와 비밀번호가 서로 같으면 로그인 처리
if(id.equals(password)) { // 로그인 성공
session.setAttribute("user_id", id);
%>
<%= id %>님이 로그인했습니다.<br>
<input type="button" value="로그인 여부 체크" onclick="location.href='s04_loginCheck.jsp'">
<input type="button" value="로그아웃" onclick="location.href='s05_logout.jsp'">
<%
}
else { // 로그인 실패
%>
<script type="text/javascript">
alert('로그인에 실패했습니다!');
history.go(-1);
</script>
<%
}
%>
</body>
</html>
s04_loginCheck.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>
<%
String user_id = (String)session.getAttribute("user_id"); // getAttribute() 메서드는 속성 값을 Object 자료형으로 반환하므로 다운캐스팅 필요
if(user_id!=null) { // 로그인된 경우
%>
아이디 [ <%= user_id %> ]로 로그인한 상태!<br>
<input type="button" value="로그아웃" onclick="location.href='s05_logout.jsp'">
<%
}
else { // 로그인되지 않은 경우
%>
로그인하지 않은 상태<br>
<input type="button" value="로그인" onclick="location.href='s02_loginForm.jsp'">
<%
}
%>
</body>
</html>
s05_logout.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>
<%
// 세션의 모든 속성을 제거해서 세션을 갱신
session.invalidate();
%>
로그아웃했습니다.<br>
<input type="button" value="로그인" onclick="location.href='s02_loginForm.jsp'">
<input type="button" value="로그인 여부 체크" onclick="location.href='s04_loginCheck.jsp'">
</body>
</html>
cos-20.08.zip
선택lib
폴더의 cos.jar
를 C:\javaWork\workspace_jsp\jspMain\src\main\webapp\WEB-INF\lib
로 이동webapp
폴더 오른쪽 클릭 후 새 폴더 upload
생성ch09-fileupload
생성하고 새 JSP 파일 s01_fileForm.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>
<form action="s02_fileUpload.jsp" method="post" enctype="multipart/form-data"> <!-- 파일 업로드시 method를 post로 지정하지 않으면 파일의 경로와 이름만 전송되고 내용은 전송되지 않으며, enctype을 multipart/form-data로 지정하지 않으면 파일을 업로드해도 인식하지 못함 -->
작성자 <input type="text" name="user"><br>
제목 <input type="text" name="title"><br>
파일명 <input type="file" name="uploadFile"><br>
<input type="submit" value="파일 전송">
</form>
</body>
</html>
s02_fileUpload.jsp
생성<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="com.oreilly.servlet.MultipartRequest" %>
<%@ page import="com.oreilly.servlet.multipart.DefaultFileRenamePolicy" %>
<%@ page import="java.io.File" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>파일 업로드 처리</title>
</head>
<body>
<%
// 파일 업로드 경로
String saveFolder = "/upload";
// 인코딩 타입
String encType = "UTF-8";
// 파일의 최대 업로드 사이즈
int maxSize = 5*1024*1024; // 바이트 단위
// 파일 업로드 절대 경로 구하기
String realFolder = application.getRealPath(saveFolder); // 다이나믹 웹 프로젝트에서는 이클립스가 publish하는 경로를 반환; C:/javaWork/workspace_jsp/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/jspMain/upload
out.println("파일 업로드 절대 경로 : " + realFolder + "<br>");
out.println("--------<br>");
// 파일 업로드 작업을 위해서 MultipartRequest 객체 생성
MultipartRequest multi = new MultipartRequest(request, // 파일 정보 제공
realFolder, // 절대 경로
maxSize, // 전송 전에 파일의 최대 업로드 사이즈를 초과하지 않는지 확인
encType, // 인코딩 타입
new DefaultFileRenamePolicy()); // 이미 업로드된 파일명과 동일한 파일명을 업로드하는 경우 덮어씌우지 않도록 파일명을 교체
out.println("작성자 : " + multi.getParameter("user") + "<br>"); // enctype="multipart/form-data"으로 전송시 request 객체에서는 파라미터 값을 얻을 수 없음
out.println("제목 : " + multi.getParameter("title") + "<br>");
out.println("--------<br>");
// 파일 정보 처리
// 전송된 원래의 파일명
String original = multi.getOriginalFileName("uploadFile"); // 파라미터명(<input type="file"> 태그의 name 속성 값)을 전달
// 서버에 저장된 파일명
String filename = multi.getFilesystemName("uploadFile");
// 전송된 파일의 컨텐트 타입
String type = multi.getContentType("uploadFile");
out.println("전송 전 원래의 파일명 : " + original + "<br>");
out.println("서버에 저장된 파일명 : " + filename + "<br>");
out.println("컨텐트 타입 : " + type + "<br>");
// 파일의 용량 구하기
File file = multi.getFile("uploadFile");
out.println("파일의 용량 : " + file.length() + " bytes");
%>
</body>
</html>
s03_fileMultiForm.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>
<form action="s04_fileMultiUpload.jsp" method="post" enctype="multipart/form-data">
이름 <input type="text" name="name"><br>
제목 <input type="text" name="title"><br>
이미지1 <input type="file" name="uploadFile1" accept="image/gif,image/png,image/jpeg"><br>
이미지2 <input type="file" name="uploadFile2" accept="image/gif,image/png,image/jpeg"><br>
<input type="submit" value="전송">
</form>
</body>
</html>
s04_fileMultiUpload.jsp
생성<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="com.oreilly.servlet.MultipartRequest" %>
<%@ page import="com.oreilly.servlet.multipart.DefaultFileRenamePolicy" %>
<%@ page import="java.net.URLEncoder" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>파일 다중 업로드 처리</title>
</head>
<body>
<%
String saveFolder = "/upload"; // 파일 업로드 경로
String encType = "UTF-8"; // 인코딩 타입
int maxSize = 5*1024*1024; // 최대 업로드 파일 크기
// upload의 절대 경로
String realFolder = application.getRealPath(saveFolder);
// 파일 업로드를 하기 위해 MultipartRequest 객체 생성
MultipartRequest multi = new MultipartRequest(request, realFolder, maxSize, encType, new DefaultFileRenamePolicy());
out.println("이름 : " + multi.getParameter("name") + "<br>");
out.println("제목 : " + multi.getParameter("title") + "<br>");
out.println("--------<br>");
String img1 = multi.getFilesystemName("uploadFile1");
String img2 = multi.getFilesystemName("uploadFile2");
%>
<%-- 파일명에 괄호, 공백 등 특수문자가 사용된 경우 퍼센트 인코딩해야 서버에서 파일을 불러올 수 있음; URLEncoder의 경우 공백을 +로 변환하므로 %20으로 일괄 치환 필요 --%>
<img src="/jspMain/upload/<%= URLEncoder.encode(img1, "UTF-8").replace("+", "%20") %>"><br>
<img src="/jspMain/upload/<%= URLEncoder.encode(img2, "UTF-8").replace("+", "%20") %>"><br>
</body>
</html>
s05_profileForm.jsp
생성<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>프로필 사진 업로드 폼</title>
<script type="text/javascript">
window.onload = function() {
var file = document.getElementById('file');
// 파일을 선택할 때 이벤트 연결
file.onchange = function() {
if(file.files && file.files[0]) { // 파일이 선택되어 files 배열의 인덱스 0에 File 객체가 저장되어 있는 경우
var reader = new FileReader();
// 이미지 파일 읽기
reader.readAsDataURL(file.files[0]);
// 이미지 파일을 모두 읽어들이면 이벤트 발생
reader.onload = function() {
var image = document.getElementById('image');
var submit_btn = document.getElementById('submit_btn');
// 이미지 미리 보기 처리
image.src = reader.result;
image.style.display = '';
submit_btn.style.display = '';
};
}
};
};
</script>
</head>
<body>
<h2>프로필 사진 업로드하기</h2>
<img id="image" width="100" height="100" alt="Image Preview" style="display: none;">
<form action="s06_profile.jsp" method="post" enctype="multipart/form-data">
<input type="file" name="file" id="file" accept="image/png,image/jpeg,image/gif">
<input type="submit" value="전송" style="display: none;" id="submit_btn">
</form>
</body>
</html>
s06_profile.jsp
생성<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="com.oreilly.servlet.MultipartRequest" %>
<%@ page import="com.oreilly.servlet.multipart.DefaultFileRenamePolicy" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>프로필 사진 업로드 처리</title>
</head>
<body>
<h2>저장된 프로필 사진</h2>
<%
String saveFolder = "/upload"; // 파일 업로드 경로
String encType = "UTF-8"; // 인코딩 타입
int maxSize = 5*1024*1024; // 최대 업로드 파일 크기
// upload 절대 경로
String realFolder = application.getRealPath(saveFolder);
// 파일 업로드를 처리하기 위해 MultipartRequest 객체 생성
MultipartRequest multi = new MultipartRequest(request, realFolder, maxSize, encType, new DefaultFileRenamePolicy());
String file = multi.getFilesystemName("file");
%>
<img src="/jspMain/upload/<%= file %>">
</body>
</html>
C:\javaWork\apps
에서 ojdbc8.jar
를 복사하여 C:\javaWork\workspace_jsp\jspMain\src\main\webapp\WEB-INF\lib
에 붙여넣기ch10-jdbc
생성하고 새 JSP 파일 connectionTest.jsp
생성<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.sql.DriverManager" %>
<%@ page import="java.sql.Connection" %>
<%@ page import="java.sql.SQLException" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>연동 테스트</title>
</head>
<body>
<%
String driverName = "oracle.jdbc.OracleDriver";
String jdbcUrl = "jdbc:oracle:thin:@localhost:1521:xe";
String dbId = "scott";
String dbPass = "tiger";
Connection conn = null;
try {
// JDBC 수행 1단계 : 드라이버 로드
Class.forName(driverName);
// JDBC 수행 2단계 : Connection 객체 생성
conn = DriverManager.getConnection(jdbcUrl, dbId, dbPass);
out.println("정상적으로 연결되었습니다.");
}
catch(Exception e) {
e.printStackTrace();
}
finally {
// 자원 정리
if(conn!=null) try {conn.close();} catch(SQLException e) {}
}
%>
</body>
</html>
dbinfo.jspf
생성<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String driverName = "oracle.jdbc.OracleDriver";
String jdbcUrl = "jdbc:oracle:thin:@localhost:1521:xe";
String dbId = "scott";
String dbPass = "tiger";
%>
table.sql
생성CREATE TABLE tboard(
num NUMBER PRIMARY KEY,
name VARCHAR2(30) NOT NULL,
title VARCHAR2(150) NOT NULL,
passwd VARCHAR2(10) NOT NULL,
content VARCHAR2(4000) NOT NULL,
reg_date DATE NOT NULL
);
CREATE SEQUENCE tboard_seq;
style.css
생성@charset "UTF-8";
body {
padding: 0;
margin: 0;
}
.page-main {
width: 800px;
margin: 0 auto; /* 중앙 정렬 */
}
.result-display {
width: 400px;
height: 200px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border: 1px solid #000;
display: flex; /* 하위 요소를 수직으로 쌓을 수 있는 공간을 만듦 */
align-items: center; /* 세로 정렬 */
justify-content: center; /* 가로 정렬 */
}
.align-center {
text-align: center;
}
.align-right {
text-align: right;
}
/* 등록, 수정 폼 */
form {
width: 500px;
margin: 0 auto;
border: 1px solid #000;
padding: 10px 10px 10px 30px;
}
ul {
list-style: none;
}
label {
width: 100px;
float: left;
}
insertTestForm.jsp
생성<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>게시판 글 등록</title>
<link rel="stylesheet" href="style.css">
<script type="text/javascript">
window.onload = function() {
var myForm = document.getElementById('myForm');
// 이벤트 연결
myForm.onsubmit = function() {
var name = document.getElementById('name');
if(name.value.trim()=='') {
alert('이름을 입력하세요!');
name.focus();
name.value = '';
return false;
}
var title = document.getElementById('title');
if(title.value.trim()=='') {
alert('이름을 입력하세요!');
title.focus();
title.value = '';
return false;
}
var passwd = document.getElementById('passwd');
if(passwd.value.trim()=='') {
alert('이름을 입력하세요!');
passwd.focus();
passwd.value = '';
return false;
}
var content = document.getElementById('content');
if(content.value.trim()=='') {
alert('이름을 입력하세요!');
content.focus();
content.value = '';
return false;
}
/*
list = document.getElementsByTagName('li');
for(let i=0;i<list.length;i++) {
let input = list[i].querySelector('input,textarea');
if(input.value.trim()=='') {
alert(list[i].querySelector('label').innerHTML + '을/를 입력하세요!');
input.focus();
input.value = '';
return false;
}
}
*/
};
};
</script>
</head>
<body>
<div class="page-main">
<h2>글쓰기</h2>
<form id="myForm" action="insertTest.jsp" method="post">
<ul>
<li>
<label for="name">이름</label>
<input type="text" name="name" id="name" size="20" maxlength="10"> <!-- 관리하기 편하게 식별자를 SQL 테이블의 컬럼명과 통일시킴 -->
</li>
<li>
<label for="title">제목</label>
<input type="text" name="title" id="title" size="30" maxlength="50">
</li>
<li>
<label for="passwd">비밀번호</label>
<input type="password" name="passwd" id="passwd" size="20" maxlength="10">
</li>
<li>
<label for="content">내용</label>
<textarea rows="5" cols="40" name="content" id="content"></textarea>
</li>
</ul>
<div class="align-center">
<input type="submit" value="전송">
<input type="button" value="목록" onclick="location.href='selectTest.jsp'">
</div>
</form>
</div>
</body>
</html>
insertTest.jsp
생성<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.sql.DriverManager" %>
<%@ page import="java.sql.Connection" %>
<%@ page import="java.sql.PreparedStatement" %>
<%@ page import="java.sql.SQLException" %>
<%@ include file="dbinfo.jspf" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>글 등록 처리</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<%
// 전송된 데이터 인코딩 처리
request.setCharacterEncoding("UTF-8");
// 전송된 데이터 반환
String name = request.getParameter("name");
String title = request.getParameter("title");
String passwd = request.getParameter("passwd");
String content = request.getParameter("content");
// DB 연동
Connection conn = null;
PreparedStatement pstmt = null;
String sql = null;
try {
// JDBC 수행 1단계 : 드라이버 로드
Class.forName(driverName);
// JDBC 수행 2단계 : Connection 객체 생성
conn = DriverManager.getConnection(jdbcUrl, dbId, dbPass);
// SQL문 작성
sql = "INSERT INTO tboard (num, name, title, passwd, content, reg_date) "
+ "VALUES (tboard_seq.NEXTVAL, ?, ?, ?, ?, SYSDATE)";
// JDBC 수행 3단계 : PreparedStatement 객체 생성
pstmt = conn.prepareStatement(sql);
// ?에 데이터를 바인딩
pstmt.setString(1, name);
pstmt.setString(2, title);
pstmt.setString(3, passwd);
pstmt.setString(4, content);
// JDBC 수행 4단계 : SQL문 실행
pstmt.executeUpdate();
%>
<div class="result-display">
<div class="align-center">
글 등록 성공<br>
<input type="button" value="목록 보기" onclick="location.href='selectTest.jsp'">
</div>
</div>
<%
}
catch(Exception e) {
e.printStackTrace();
%>
<div class="result-display">
<div class="align-center">
오류 발생! 글 등록 실패!<br>
<input type="button" value="글쓰기" onclick="location.href='insertTestForm.jsp'">
</div>
</div>
<%
}
finally {
// 자원 정리
if(pstmt!=null) try {pstmt.close();} catch(SQLException e) {}
if(conn!=null) try {conn.close();} catch(SQLException e) {}
}
%>
</body>
</html>