stateless 방식의 서버-클라이언트 통신
각 웹 페이지의 상태나 정보를 다른 페이지들과 공유하지 않음
새 웹 페이지에서는 기존의 웹 페이지나 서블릿에 관한 정보를 알 수 없음
동시 사용자 수가 많으면 데이터베이스 연동 속도 저하
일부 정보들을 클라이언트 PC나 서버 메모리에 저장하여 해결
웹 페이지 사이의 상태나 정보를 공유하는 웹 페이지 연결 기능
<hidden> 태그: HTML 태그를 이용한 정보 공유<hidden> 태그브라우저 미표시
미리 저장된 정보를 서블릿으로 전송
pro09/WebContent/login.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>로그인창</title>
</head>
<body>
<form name="frmLogin" method="post" action="login" encType="UTF-8">
아이디 :<input type="text" name="user_id"><br>
비밀번호:<input type="password" name="user_pw"><br>
<input type="submit" value="로그인">
<input type="reset" value="다시 입력">
/* <hidden> */
<input type="hidden" name="user_address" value="서울시 성북구" />
<input type="hidden" name="user_email" value="test@gmail.com" />
<input type="hidden" name="user_hp" value="010-111-2222" />
</form>
</body>
</html>
pro09/src/sec01/ex01/LoginServlet.java
package sec01.ex01;
...
@WebServlet("/login")
public class LoginServlet extends HttpServlet{
public void init() {
System.out.println("init 메서드 호출");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
/* 값 가져오기 */
String user_id = request.getParameter("user_id");
String user_pw = request.getParameter("user_pw");
String user_address=request.getParameter("user_address");
String user_email=request.getParameter("user_email");
String user_hp=request.getParameter("user_hp");
/* 출력문 */
String data="안녕하세요!<br> 로그인하셨습니다.<br><br>";
data+="<html><body>";
data+="아이디 : "+user_id ;
data+="<br>";
data+="패스워드 : "+user_pw;
data+="<br>";
data+="주소 : "+user_address;
data+="<br>";
data+="email : "+user_email;
data+="<br>";
data+="휴대전화 : "+user_hp;
data+="</body></html>";
out.print(data);
}
public void destroy(){
System.out.println("destroy 메서드 호출");
}
}
GET 방식으로 한글 전송 시 인코딩 필요
pro09/src/sec01/ex02/LoginServlet.java
package sec01.ex02;
...
@WebServlet("/login")
public class LoginServlet extends HttpServlet{
public void init(){
System.out.println("init 메서드 호출");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
/* 값 가져오기 */
String user_id = request.getParameter("user_id");
String user_pw = request.getParameter("user_pw");
String user_address=request.getParameter("user_address");
String user_email=request.getParameter("user_email");
String user_hp=request.getParameter("user_hp");
/* 출력문 */
String data="안녕하세요!<br>로그인하셨습니다.<br><br>";
data+="<html><body>";
data+="아이디 : " +user_id ;
data+="<br>";
data+="패스워드 : " +user_pw;
data+="<br>";
data+="주소 : " +user_address;
data+="<br>";
data+="email : " +user_email;
data+="<br>";
data+="휴대전화 : " +user_hp;
data+="<br>";
out.print(data);
user_address=URLEncoder.encode(user_address,"utf-8"); //한글 인코딩
out.print("<a href='/pro09/second?user_id="+user_id+"&user_pw="+user_pw+"&user_address="+user_address+"'>두 번째 서블릿으로 보내기</a>"); //데이터 전송
data="</body></html>";
out.print(data);
}
public void destroy() {
System.out.println("destroy 메서드 호출");
}
}
pro09/src/sec01/ex02/SecondServlet.java
package sec01.ex02;
...
@WebServlet("/second")
public class SecondServlet extends HttpServlet{
public void init() {
System.out.println("init 메서드 호출");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
/* 값 가져오기 */
String user_id = request.getParameter("user_id");
String user_pw = request.getParameter("user_pw");
String user_address=request.getParameter("user_address");
/* 받아온 값으로 로그인 확인 */
out.println("<html><body>");
if(user_id!=null && user_id.length()!=0) {
out.println("이미 로그인 상태입니다!<br><br>");
out.println("첫 번째 서블릿에서 넘겨준 아이디: " + user_id +"<br>");
out.println("첫 번째 서블릿에서 넘겨준 비밀번호: "+user_pw +"<br>");
out.println("첫 번째 서블릿에서 넘겨준 주소: "+user_address +"<br>");
out.println("</body></html>");
} else {
out.println("로그인 하지 않았습니다.<br><br>");
out.println("다시 로그인하세요!!<br>");
out.println("<a href='/pro09/login.html'>로그인창으로 이동하기 </>");
}
}
public void destroy(){
System.out.println("destroy 메서드 호출");
}
}
웹 페이지 사이 공유 정보를 클라이언트 PC에 저장하여 사용할 수 있도록 하는 매개역할
클라이언트 PC에 정보 저장
저장 정보 용량 제한 존재
보안 취약
클라이언트 브라우저에서 사용 유무 설정 가능
도메인(웹 사이트) 당 쿠키 생성
javax.servlet.http.Cookie
getName(): 쿠키 이름
getComment(): 쿠키 설명
getDomain(): 유효 도메인 정보
getMaxAge(): 유효 기간(s)
getValue(): 설정 값
getPath(): 디렉토리 정보
setComment(String)
setDomain(String)
setMaxAge(int) - 음수 또는 미사용 시 session 쿠키
setValue(String)
setPath(String)
디버그창(F12) 상단 메뉴 바 Application
-> 왼쪽 메뉴 중 Cookies
-> http://localhost:8090
파일로 생성
저장 위치: C:\Users\사용자\AppData\Local\Google\Chrome\User Data\Default\Cache
쿠키 삭제 또는 설정값 종료 시 쿠키 종료
최초 접속 시 서버 전송
로그인 유무 또는 팝업창 제한에 사용
pro09/src/sec02/ex01/SetCookieValue.java
package sec02.ex01;
...
@WebServlet("/set")
public class SetCookieValue extends HttpServlet{
protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out=response.getWriter();
Date d = new Date();
Cookie c = new Cookie("cookieTest",URLEncoder.encode("persistence","utf-8")); //한글 정보 인코딩 쿠키 생성
c.setMaxAge(24*60*60); //유효 기간 24시간 설정
response.addCookie(c); //브라우저로 쿠키 전송
out.println("현재시간 : "+d);
out.println("문자열을 Cookie에 저장");
}
}
pro09/src/sec02/ex01/GetCookieValue.java
package sec02.ex01;
...
@WebServlet("/get")
public class GetCookieValue extends HttpServlet{
protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out=response.getWriter();
/* 쿠키 정보 요청 및 가져오기 */
Cookie[] allValues=request.getCookies();
for(int i=0; i<allValues.length;i++){
if(allValues[i].getName().equals("cookieTest")) {
out.println("<h2>Cookie 값 가져오기 : "+URLDecoder.decode(allValues[i].getValue(),"utf-8"));
}
}
}
}
브라우저 메모리에 생성
브라우저 종료 시 쿠키 종료
최초 접속 시 전송 없음
인증 정보 유지에 사용
pro09/src/sec02/ex01/SetCookieValue.java
package sec02.ex01;
...
@WebServlet("/set")
public class SetCookieValue extends HttpServlet{
protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out=response.getWriter();
Date d=new Date();
Cookie c = new Cookie("cookieTest",URLEncoder.encode("session 쿠키","utf-8")); //쿠키 생성
c.setMaxAge(-1); //음수 처리 -> session 쿠키
response.addCookie(c); //쿠키 전송
out.println("현재 시간 : "+d);
out.println("현재 시간을 Cookie로 저장합니다.");
}
}
pro09/WebContent/popupTest.html
<html>
<head>
<meta charset="UTF-8">
<title> 자바스크립트에서 쿠키 사용 </title>
<script type = "text/javascript">
window.onload = pageLoad; //브라우저에서 웹 페이지 로드 시 pageLoad 함수 호출
function pageLoad(){
notShowPop = getCookieValue(); //쿠키 값 얻어오기
/* 쿠키 값이 true인 경우, 팝업창 나타내기 */
if(notShowPop!="true"){
window.open("popUp.html","pop","width=400,height=500,history=no, resizable=no,status=no,scrollbars=yes,menubar=no");
}
}
function getCookieValue(){
var result="false";
/* 쿠키 정보 가져와서 문자열 분리
(쿠키이름1 = 쿠키값1; ... 쿠키이름n = 쿠키값n;) */
if(document.cookie != ""){
cookie = document.cookie.split(";");
for(var i=0; i<cookie.length;i++){
element=cookie[i].split("=");
value=element[0];
value=value.replace(/^\s*/,''); //정규식: 공백 제거
if(value=="notShowPop"){ result = element[1]; }
}
}
return result;
}
function deleteCookie(){
/* 쿠키 삭제 처리: "notShowPop=false; path=/; expires=-1" */
document.cookie = "notShowPop=" + "false" + ";path=/; expires=-1" ;
}
</script>
</head>
<body>
<form>
<!-- 쿠키 삭제 시 팝업 제한 쿠키 정보가 삭제되어 다시 팝업창 등장 -->
<input type=button value="쿠키삭제" onClick="deleteCookie()">
</form>
</body>
</html>
pro09/WebContent/popUp.html
<html>
<head>
<meta charset="UTF-8">
<script type="text/javascript">
function setPopUpStart(obj){
if(obj.checked==true){
/* 쿠키 유효 시간 설정: 하루 */
var expireDate = new Date(); var days = 1;
expireDate.setDate(expireDate.getDate() + days);
/* 팝업창 제한 선택 시 쿠키 값 설정 */
document.cookie ="notShowPop=" +"true" + ";path=/; expires=" + expireDate.toGMTString();
window.close();
}
}
</script>
</head>
<body>
알림 팝업창입니다.
<br><br><br><br><br><br><br>
<form>
<input type=checkbox onClick="setPopUpStart(this)">오늘 더 이상 팝업창 띄우지 않기
</form>
</body>
</html/>
웹 페이지 간 공유 정보를 서버에 저장해두고 매개해주는 방식
서버 메모리에 정보 저장
보안이 필요한 정보에 사용
브라우저(사용자) 당 한 개 세션 생성
세션 유효 시간 존재 (기본 30분)
브라우저 세션 연동 시 세션 쿠키 이용
서버 부하에 가세함
유효시간 경과 시 기존 세션 삭제
유효시간 경과 후 재요청 시 새 새션 생성
ex) 부동 시 세션 만료로 인한 자동 로그아웃
HttpSession 클래스 객체를 통해 사용 가능
생성 시 getSession() 메소드 사용
Object getAttribute(String name): name 속성 값 반환
Enumeration getAttributeNames(): 세션 속성 이름들 반환
long getCreationTime(): 1970.01.01.00:00:00 ~ 세션 생성 시간 반환
String getId(): 세션 할당 고유 식별자 반환
int getMaxInactiveInterval(): 세션 유지 시간 반환
void invalidate(): 세션 소멸
boolean isNew(): 최초/기존 생성 여부 판별
void removeAttribute(String name): name 속성 제거
void setAttribute(String name, Object value): name 속성 값으로 value 할당
void setMaxInactiveInterval(int interval): 세션 유지 시간(s) 설정
크롬 주소창에서 /sess 요청
pro09/src/sec03/ex01/SessionTest.java
package sec03.ex01;
...
@WebServlet("/sess")
public class SessionTest extends HttpServlet{
protected void doGet(HttpServletRequest request , HttpServletResponse response ) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
HttpSession session = request.getSession(); //세션 생성 또는 반환
/* 세션 정보 출력 */
out.println("세션 아이디: "+ session.getId()+"<br>");
out.println("최초 세션 생성 시각: "+ new Date(session.getCreationTime())+"<br>");
out.println("최근 세션 접근 시각 : "+ new Date(session.getLastAccessedTime())+"<br>");
/* 세션 유효시간 설정 */
out.println("기본 세션 유효 시간 : "+ session.getMaxInactiveInterval()+"<br>"); //재설정 전 유효시간
session.setMaxInactiveInterval(5); //유효시간 재설정: 5초
out.println("세션 유효 시간 : "+ session.getMaxInactiveInterval()+"<br>"); //재설정 후 유효시간
/* 최초/기존 생성 여부 판별 */
if(session.isNew()) {
out.print("새 세션이 만들어졌습니다.");
}
/* 세션 강제 삭제 */
//session.invalidate(); //주석 해제 시 세션 생성 직후 즉시 소멸, 재요청 시 항상 다른 세션 생성
}
}
HttpSession 바인딩
context.xml
...
<!-- 톰캣 종료 후 메모리에서 자동 세션 삭제 -->
<Manager pathname=”” /> <!-- 주석 해제 -->
...
pro09/WebContent/login2.html
<!DOCTYPE html>
<html>
<head>…</head>
<body>
<form name="frmLogin" method="post " action="login" encType="UTF-8">
아이디 :<input type="text" name="user_id"><br>
비밀번호:<input type="password" name="user_pw"><br>
<input type="submit" value="로그인">
<input type="reset" value="다시 입력">
</form>
</body>
</html>
pro09/src/sec03/ex04/SessionTest4.java
package sec03.ex04;
...
@WebServlet("/login")
public class SessionTest4 extends HttpServlet {
protected void doGet(HttpServletRequest request , HttpServletResponse response) throws ServletException, IOException {
doHandle(request, response);
}
protected void doPost(HttpServletRequest request , HttpServletResponse response) throws ServletException, IOException {
doHandle(request, response);
}
private void doHandle(HttpServletRequest request , HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
HttpSession session = request.getSession();
String user_id = request.getParameter("user_id");
String user_pw = request.getParameter("user_pw");
if (session.isNew()){
if(user_id != null){
session.setAttribute("user_id", user_id);
out.println("<a href='login'>로그인 상태 확인</a>");
} else {
out.print("<a href='login2.html'>다시 로그인 하세요!!</a>");
session.invalidate();
}
}
else {
user_id = (String) session.getAttribute("user_id");
if (user_id != null && user_id.length() != 0) {
out.print("안녕하세요 " + user_id + "님!!!");
} else {
out.print("<a href='login2.html'>다시 로그인 하세요!!</a>");
session.invalidate();
}
}
}
}
쿠키 기능 사용 불가 시 대체 가능
pro09/src/sec04/ex01/SessionTest5.java
package sec04.ex01;
...
@WebServlet("/login")
public class SessionTest5 extends HttpServlet{
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doHandle(request, response); }
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doHandle(request, response); }
private void doHandle(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
reponse.setContentType("text/html; charset=utf-8");
PrintWriter out = response.getWriter();
HttpSession session = request.getSession();
String user_id = request.getParameter("user_id");
String user_pw = request.getParameter("user_pw");
/* 4가지 상황 */
if(session.isNew()) {
if(user_id != null) { /* 새로운 세션 + 아이디 O: 새로 로그인을 시도하는 상황 */
// 세션에 아이디 저장 + 로그인된 상태로 현재 페이지 다시 이동
session.setAttribute("user_id", user_id);
String url = response.encodeURL("login");
out.println("<a href = "+url+">" + "login check" + "</a>");
} else { /* 새로운 새션 + 아이디 X: 로그인 중 아이디를 제출하지 않은 상황 */
// 로그인 페이지로 이동 + 세션 삭제
out.print("<a href = 'login2.html'> login again </a>");
session.invalidate();
}
} else {
user_id = (String) session.getAttribute("user_id");
/* 기존 세션 + 아이디 O: 이미 로그인이 되어있는 상태 */
if(user_id != null && user_id.length() != 0) { out.print("login success: "+user_id); } // 따로 아이디 제출을 하지 않음
/* 기존 세션 + 아이디 X: 로그인 세션이 만료된 상태 */
else { out.print("<a href = 'login2.html'> login again </a>"); session.invalidate(); } // 로그인 페이지 이동 + 세션 삭제
}
}
}
*자바 웹을 다루는 기술