쿠키란 무엇인가
HTTP 통신은 stateless하다.
즉 이번 요청-응답이 과거의 요청-응답에 영향을 받지않고 미래에 영향을 주지도 않는다.
그렇다면 아이디기억하기, 1주일간 공지사항 안 보기처럼
서버-클라이언트간 임시 데이터가 필요한 경우는 어떻게 할까?
바로 쿠키를 이용하면 된다.
쿠키란 하이퍼 텍스트의 기록서의 일종으로서 인터넷 사용자가 어떠한 웹사이트를
방문할 경우 그 사이트가 사용하고 있는 서버를 통해 인터넷 사용자의 컴퓨터(내 브라우저)에
설치되는 작은 기록 정보 파일을 일컫는다.쿠키(Cookie)는 웹 브라우저가 보관하는 데이터이다.
웹 브라우저는 웹 서버에 요청(request)를 보낼 때 쿠키를 함께 전송하며,
웹 서버는 웹 브라우저가 보낸 쿠키를 사용해서 필요한 데이터를 읽을 수 있다.
또 웹 서버는 쿠키를 생성해 응답(response)할 때 브라우저에 전달할 수 있다.
웹 브라우저는 전달받은 쿠키를 쿠키저장소에 저장한다.
쿠키는 브라우저,서버 둘 다 생성 할 수 있지만 보관은 브라우저만 한다.
여기서는 서버에서 생성하는 쿠키에 대해서만 실습해보겠다.
쿠키 동작방식
쿠키의 동작방식을 살펴보자.
- 쿠키 생성단계 : 쿠키를 사용하기 위해서는 먼저 쿠키를 생성해야 한다. JSP 프로그래밍에서 쿠키는 주로 웹 서버 측에서 생성된다. 생성된 쿠키는 응답 데이터와 함께 저장되어 전송된다.
- 쿠키 저장단계 : 웹 브라우저는 응답 데이터에 포함된 쿠키를 쿠키 저장소에 보관한다. 쿠키의 종류에 따라 메모리나 파일로 저장된다.
- 쿠키 전송단계 : 웹 브라우저는 한번 저장된 쿠키를 매번 요청이 있을 때마다 웹 서버에 전송한다.
웹 서버는 웹 브라우저가 전송한 쿠키를 사용해서 필요한 작업을 수행한다.
※모든 브라우저나 서버에서 그런건 아니지만
브라우저가 저장하고 있는 쿠키에는 이름,값, 도메인,유효시간,경로가 있는데
서버에 보낼 때는 이름,값만 설정된 쿠키를 서버에 보낸다.
쿠키 실습
쿠키의 구성요소는 다음과 같다.
- 이름 : 각 쿠키를 구별하는데 사용되는 이름
- 값 : 쿠키의 이름과 관련된 값
- 유효시간 : 쿠키의 유지시간
- 도메인 : 쿠키를 전송할 도메인
- 경로 : 쿠키를 전송할 요청 경로
각각의 구성요소는 실습을 통해 어떤 특징이있는지, 어떤식으로 사용하는지 알아보자
쿠키 생성
쿠키 생성그림을 잘 보자.
웹 서버에서 응답에 쿠키를 실어 보낸다. 즉, response가 뭔가 한다는 것을 알 수 있다.
01makeCookie.jsp
쿠키 생성은 이름과 값으로 한다.
브라우저는 전달받은 쿠키를 저장한다. 브라우저는 이름이 똑같은 쿠키가 온다면
기존의 쿠키와 이름이 같은 쿠키가 온다면 기존의 쿠키를 삭제하고 새로 저장한다.
<%@page import="java.net.URLEncoder"%>
<%@page import="java.net.URL"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
request.setCharacterEncoding("UTF-8");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<%@include file="/WEB-INF/inc/header.jsp"%>
<title>Insert title here</title>
</head>
<body>
<%@include file="/WEB-INF/inc/top.jsp"%>
<%
Cookie cookie=new Cookie("han",URLEncoder.encode("한창희","utf-8"));
response.addCookie(cookie);
%>
</body>
</html>
쿠키 보기
01viewCookie.jsp
쿠키는 기본적으로 request에 담겨서 오고 서버에서 request객체를 받아 활용한다.
기본적으로 Cookie[]로 주기때문에 아래처럼 출력할 수 있다.
01makeCookie.jsp를 실행하고 나서 01viewCookie.jsp를 실행해보자.
(JSESSIONID 쿠키는 기본적으로 브라우저에 존재하는 쿠키니 'han'쿠키의 값만 확인하면 된다.)
코드를 보면
'han'일 때만 출력하는 코드랑 모든 쿠키를 출력하는 코드가 섞여있다.
'han'만 출력하려고 할 때도 일단 for문을 쓴 후 if문을 써야하는 불편함이 있다.
<%@ page import = "java.net.URLDecoder" %>
<%@page import="java.net.URLEncoder"%>
<%@page import="java.net.URL"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
request.setCharacterEncoding("UTF-8");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<%@include file="/WEB-INF/inc/header.jsp"%>
<title>Insert title here</title>
</head>
<body>
<%@include file="/WEB-INF/inc/top.jsp"%>
<%
Cookie[] cookies=request.getCookies();
if(cookies!=null){
for(Cookie cookie : cookies){
if(cookie.getName().equals("han")){
out.print(cookie.getName()+" : "+
URLDecoder.decode(cookie.getValue(),"utf-8")+"<br>");
continue;
}
}
}
%>
</body>
</html>
쿠키 변경
쿠키는 해당 쿠키를 찾아 값을 바꾸거나 해당 쿠키의
이름으로 새로 만들어서 response에 담으면 값을 변경할 수 있다.
01modifyCookie.jsp
<%@ page contentType = "text/html; charset=utf-8" %>
<%@ page import = "java.net.URLEncoder" %>
<html>
<head><title>값 변경</title></head>
<body>
<%
//이름이 han인 쿠키가 있는지 없는지 검사해서
//없으면 아무것도안하고 있으면 그 쿠키의 값을 바꿔보세요
Cookie[] cookies=request.getCookies();
for(Cookie cookie : cookies){
if(cookie.getName().equals("han")){
cookie.setValue("modifiedvalue");
response.addCookie(cookie);
}
}
//또는
//Cookie cookie=new Cookie("han","modifiedValue");
//response.addCookie(cookie);
%>
</body>
</html>
01modifyCookie.jsp 실행 후 01viewCookie를 실행해보자.
쿠키 삭제
쿠키 delete메소드가 따로 없고 setMaxAge() 라는 메소드를 사용한다.
setMaxAge()는 쿠키의 지속시간을 설정하는 메소드로 0을 설정해 0초 후 삭제하라고
브라우저에 전달하면 된다.
삭제할 때는 경로가 무조건 같아야한다. 상위경로,하위경로 절대경로고 뭐고 없다.
밑의 CookieUtils.createCookie할 때 경로에 주의하자.
이름만 같아서는 브라우저는 같은 쿠키로 인식하지않는다.
01deleteCookie.jsp
<%@ page contentType = "text/html; charset=utf-8" %>
<%@ page import = "java.net.URLEncoder" %>
<html>
<head><title>쿠키 삭제</title></head>
<body>
<!-- 쿠키 delete메소드가 따로 없고
setMaxAge() 라는 메소드를 사용
삭제할 때는 경로가 무조건 같아야한다.
상위경로,하위경로 절대경로고 뭐고 없다 -->
<%
Cookie[] cookies=request.getCookies();
if(cookies!=null){
for(Cookie cookie : cookies){
if(cookie.getName().equals("han")){
cookie.setMaxAge(0);
response.addCookie(cookie);
}
}
}
%>
</body>
</html>
01deleteCookie.jsp를 실행 후 viewCookie를 실행해보자.
han 쿠키가 사라진 걸 확인할 수 있다.
쿠키 경로
경로를 확인하기 위해 path1,2 폴더를 만들고 01viewCookie.jsp를 복사해 넣어보자.
쿠키의 경로는 쿠키 생성 후 setPath()를 통해 경로를 지정해주면 된다.
02cookiePath.jsp
<%@ page contentType="text/html; charset=utf-8"%>
<%@ page import="java.net.URLEncoder"%>
<html>
<head>
<title>쿠키 경로 지정</title>
</head>
<body>
<%
Cookie cookiePath1
=new Cookie("path1","path1");
cookiePath1.setPath(request.getContextPath()+"/09cookie/path1");
response.addCookie(cookiePath1);
Cookie cookiePath2
=new Cookie("path2","path2");
cookiePath2.setPath(request.getContextPath()+"/09cookie/path2");
response.addCookie(cookiePath2);
//설정된 경로 및 하위경로
Cookie cookieBasic=new Cookie("basic","basic");
response.addCookie(cookieBasic);
//자기자신 및 하위경로
Cookie cookieAbsoulute=new Cookie("absolute","absolute");
cookieAbsoulute.setPath(request.getContextPath());
response.addCookie(cookieAbsoulute);
//서버전체에서 사용가능
%>
</body>
</html>
쿠키를 생성해 각각 path1폴더, path2, 경로지정x(현재폴더), '/'로 경로지정해 주었다.
path1쿠키는 path1폴더 및 하위폴더에서,
path2쿠키는 path2폴더 및 하위폴더에서,
basic은 09cookie폴더 및 하위폴더에서
absolute는 웹 애플리케이션 전체에서 쿠키를 볼 수 있다.
이제 각각의 폴더에서 01viewCookie.jsp를 실행해 어떤 쿠키들이 보이는지 확인해보자.
쿠키 유지시간
setMaxAge()메소드를 이용해 쿠키의 유지시간을 설정 할 수 있다.
단위는 초이다.
default 값은 -1로 기본 브라우저가 종료되면 쿠키도 사라진다.
setMaxAge()를 설정하면 부라우저가 종료되도 쿠키는 사라지지않으며
정해진 시간 뒤에 쿠키가 사라진다.
03cookieAge.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>
<%
Cookie cookie=new Cookie("han","1st");
cookie.setMaxAge(60);
response.addCookie(cookie);
%>
</body>
</html>
이 코드를 실행시킨 뒤 01viewCookie.jsp를 켜보자. (han이라는 쿠키만 지켜보자)
브라우저도 껏다 켜보자. 정확히 1분 뒤에 쿠키가 사라지는걸 확인할 수 있다.
쿠키를 이용해 로그인 구현하기
쿠키를 이용해서 기본 로그인 기능을 구현하진 않지만(세션을 이용한다 보통)
쿠키를 배운김에 쿠키만으로 로그인기능을 구현해보자.
https://drive.google.com/drive/folders/1uHumdQakO7YC89ZfQeIyGcoGufJGvhdj?hl=ko
1.jsp기초의 쿠키자료를 다운받자.
DB대신에 UserList.java에 있는 UserVO로 로그인 성공 여부를 판단해보자.
압축 파일을 풀어서 나온
login.jsp, loginCheck.jsp, logout.jsp를 설명에 맞춰 작성해보자.
UserList,UserVO는 알맞은 곳에 위치하도록 하자.
※가끔 논리적으론 다 맞는거 같지만
응답이 이미 커밋된 후에는 ,sendRedirect()를 호출할 수 없습니다. 같은 에러가 뜬다.
이는 jsp실행 중 sendRedirect()를 2번이상 썻기 때문이다.
브라우저는 sendRedirect()메소드가 2개 이상 있으면
어디로 redirect할지 모르기 때문에 에러가 난다.