Preface
이번 장에선 쿠키를 생성하고 사용하는 방법을 공부했다.
나는 지금껏 서버에서 자체적으로 쿠키를 생성하여 저장한 후 클라이언트에 따라 정보를 제공하는 것으로 알고 있었다.
서버는 클라이언트의 요청에 따라 쿠키를 생성하며, 클라이언트가 재접속하여 HTTP 요청 헤더를 통해 쿠키 정보를 제공하지 않으면 서버에서 쿠키를 읽을 수 없다는 것이 이번 장의 키 포인트인 것 같다.
1. 쿠키란?
- 쿠키(Cookie): 클라이언트의 상태 정보를 유지하기 위한 기술
→ 상태 정보를 클라이언트에 키와 값 형태로 저장했다가 다음 요청 시 저장된 쿠키를 함께 전송한다.
- 쿠키 표준
1) 3000개까지 만들 수 있다.
2) 쿠키 하나의 최대 크기는 4096바이트이다.
3) 하나의 호스트나 도메인에서 최대 50개까지 만들 수 있다.
2. 기본 동작 확인
- 쿠키의 동작 메커니즘
→ 쿠키는 요청/응답에 부가적으로 실려 전달되는 데이터이다.
1) 클라이언트가 서버에 요청을 보낸다.
2) 서버가 쿠키를 생성하여 HTTP 응답 헤더에 실어 클라이언트에 전송한다.
3) 클라이언트가 쿠키를 받아 저장해둔다.
4) 클라이언트는 다음 요청 시 저장해둔 쿠키를 HTTP 요청 헤더에 실어 보낸다.
5) 서버는 쿠키의 정보를 읽어 필요한 작업을 수행한다.
- 쿠키가 처음 생성된 시점에선 서버가 쿠키를 읽을 수 없다.
- 쿠키를 구성하는 속성
1) 이름(name): 쿠키를 구별하는 이름
2) 값(value): 쿠키에 저장할 실제 데이터
3) 도메인(domain): 쿠키를 적용할 도메인
4) 경로(path): 쿠키를 적용할 경로
5) 유지 기간(max age): 쿠키를 유지할 기간
- 쿠키의 이름은 생성자를 통해 설정하고, 생성 후에는 이름을 변경할 수 없다.
new Cookie(String name, String value)
- 설정 메서드
1. void setValue(String value): 쿠키의 값을 설정한다.
→ 쉼표나 세미콜론같은 문자는 포함할 수 없다.
2. void setDomain(String domain): 쿠키에 적용할 도메인을 설정한다.
1) 주 도메인만 적용할 땐 "도메인" 형태로 기술한다.
2) 서브 도메인에도 적용하고 싶다면 ".도메인" 형태로 기술한다.
3. void setPath(String path): 쿠키가 적용될 경로를 지정한다.
→ 지정한 경로와 그 하위 경로에까지 적용된다.
4. void setMaxAge(int expire_seconds): 쿠키가 유지될 기간을 초 단위로 설정한다.
→ 기간을 설정하지 않으면 웹 브라우저가 닫힐 때 쿠키도 같이 삭제된다.
- 정보를 읽는 메서드
1. String getName( ): 쿠키의 이름을 반환한다.
2. String getValue( ): 쿠키의 값을 반환한다.
3. String getDomain( ): 쿠키가 적용되는 도메인을 반환한다.
4. String getPath( ): 쿠키의 적용 경로를 반환한다.
→ 설정하지 않았으면 null을 반환한다.
5. int getMaxAge( ): 쿠키의 유지 기간을 반환한다.
→ 설정하지 않았으면 -1을 반환한다.
- 이클립스에선 프로젝트명이 컨텍스트 루트로 사용된다.
- JSESSIONID: 톰캣 컨테이너에서 세션을 유지하기 위해 발급하는 키로, 새로운 웹 브라우저를 열면 자동으로 생성된다.
- 쿠키를 생성하고 사용하는 코드
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Cookie</title>
</head>
<body>
<h2>1. 쿠키 설정</h2>
<%
Cookie cookie = new Cookie("myCookie", "쿠키맛나요");
cookie.setPath(request.getContextPath());
cookie.setMaxAge(3600);
response.addCookie(cookie);
%>
<h2>2. 쿠키 설정 직후 쿠키값 확인하기</h2>
<%
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie c : cookies) {
String cookieName = c.getName();
String cookieValue = c.getValue();
out.println(String.format("%s : %s<br/>", cookieName, cookieValue));
}
}
%>
<h2>3. 페이지 이동 후 쿠키값 확인하기</h2>
<a href="CookieResult.jsp">다음 페이지에서 쿠키값 확인하기</a>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Cookiersult.jsp</title>
</head>
<body>
<h2>쿠키값 확인하기(쿠키가 생성된 이후의 페이지)</h2>
<%
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (int i = 0; i < cookies.length; i++) {
String cookieName = cookies[i].getName();
String cookieValue = cookies[i].getValue();
out.println(String.format("쿠키명 : %s - 쿠키값 : %s<br/>", cookieName, cookieValue));
}
}
%>
</body>
</html>
- 쿠키 삭제 방법: 쿠키를 빈 값으로 설정하고 유지 기간을 0으로 부여한다.
3. 레이어 팝업창 제어
- 레이어 팝업창: 웹페이지의 다른 콘텐츠 위에 겹쳐서 나타나는 창
- 쿠키를 이용해 팝업창의 상태 정보를 유지하는 코드
→ jQuery Ajax에 관한 내용: https://k-mozzi.tistory.com/304
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String popupMode = "on";
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie c : cookies) {
String cookieName = c.getName();
String cookieValue = c.getValue();
if (cookieName.equals("PopupClose")) {
popupMode = cookieValue;
}
}
}
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>쿠키를 이용한 팝업 관리 ver 0.1</title>
<style>
#popup {
position: absolute;
top: 100px;
left: 50px;
color: yellow;
width: 270px;
height: 100px;
background-color: gray;
}
#popup>div {
position: relative;
background-color: #ffffff;
top: 0px;
border: 1px solid gray;
padding: 10px;
color: black;
}
</style>
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
$(function() {
$('#closeBtn').click(function() {
$('#popup').hide();
var chkVal = $("input:checkbox[id=inactiveToday]:checked").val();
$.ajax({
url : 'PopupCookie.jsp',
type : 'get',
data : {
inactiveToday : chkVal
},
dataType : "text",
success : function(resData) {
if (resData != '') {
location.reload();
}
}
});
});
});
</script>
</head>
<body>
<h2>팝업 메인 페이지(ver0.1)</h2>
<%
for (int i = 1; i <= 10; i++) {
out.print("현재 팝업창은 " + popupMode + " 상태입니다.<br/>");
}
if (popupMode.equals("on")) {
%>
<div id="popup">
<h2 align="center">공지사항 팝업입니다.</h2>
<div align="right">
<form name="popFrm">
<input type="checkbox" id="inactiveToday" value="1" /> 하루 동안 열지 않음
<input type="button" value="닫기" id="closeBtn" />
</form>
</div>
</div>
<%
}
%>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" trimDirectiveWhitespaces="true"%>
<%
String chkVal = request.getParameter("inactiveToday");
if (chkVal != null && chkVal.equals("1")) {
Cookie cookie = new Cookie("PopupClose", "off");
cookie.setPath(request.getContextPath());
cookie.setMaxAge(60 * 60 * 24);
response.addCookie(cookie);
out.println("쿠키 : 하루 동안 열지 않음");
}
%>
4. 로그인 아이디 저장
- 알림창을 띄운 후 특정 페이지로 이동하는 자바스크립트 코드를 담은 자바 클래스
1) 기본 내장 객체인 out은 JspWriter 타입이다.
2) 내장 객체를 클래스에서 사용하려면 매개변수로 받아서 사용해야 한다.
package utils;
import javax.servlet.jsp.JspWriter;
public class JSFunction {
public static void alaertLocation(String msg, String url, JspWriter out) {
try {
String script = "" + "<script>" + " alert('" + msg + "');" + " location.href='" + url + "';" + "</script>";
out.println(script);
} catch (Exception e) {
}
}
public static void alertBack(String msg, JspWriter out) {
try {
String script = "" + "<script>" + " alert('" + msg + "');" + " history.back();" + "</script>";
out.println(script);
} catch (Exception e) {
}
}
}
- 쿠키를 생성하는 자바 클래스
package utils;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class CookieManager {
public static void makeCookie(HttpServletResponse response, String cName, String cValue, int cTime) {
Cookie cookie = new Cookie(cName, cValue);
cookie.setPath("/");
cookie.setMaxAge(cTime);
response.addCookie(cookie);
}
public static String readCookie(HttpServletRequest request, String cName) {
String cookieValue = "";
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie c : cookies) {
String cookieName = c.getName();
if (cookieName.equals(cName)) {
cookieValue = c.getValue();
}
}
}
return cookieValue;
}
public static void deleteCookie(HttpServletResponse response, String cName) {
makeCookie(response, cName, "", 0);
}
}
- 경로를 "/"으로 설정하면 웹 애플리케이션 전체를 포함한다.
- 로그인 창에서 쿠키를 이용해 아이디를 저장하는 코드
1)checkbox는 checked 속성을 부여하면 자동으로 체크되어있다.
2) checked 상태이면 이름과 값을 서버로 전송한다.
<%@ page import="utils.CookieManager" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String loginId = CookieManager.readCookie(request, "loginId");
String cookieCheck = "";
if(!loginId.equals("")){
cookieCheck = "checked";
}
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Cookie - 아이디 저장하기</title>
</head>
<body>
<h2>로그인 페이지</h2>
<form action="IdSaveProcess.jsp" method="post">
아이디 : <input type="text" name="user_id" value="<%= loginId %>" />
<input type="checkbox" name="save_check" value="Y" <%= cookieCheck %> />
아이디 저장하기
<br />
패스워드 : <input type="text" name="user_pw" />
<br />
<input type="submit" value="로그인하기" />
</form>
</body>
</html>
<%@ page import="utils.CookieManager"%>
<%@ page import="utils.JSFunction"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String user_id = request.getParameter("user_id");
String user_pw = request.getParameter("user_pw");
String save_check = request.getParameter("save_check");
if("must".equals(user_id) && "1234".equals(user_pw)){
if(save_check != null && save_check.equals("Y")) {
CookieManager.makeCookie(response, "loginId", user_id, 86400);
} else {
CookieManager.deleteCookie(response, "loginId");
}
JSFunction.alaertLocation("로그인에 성공했습니다.", "IdSaveMain.jsp", out);
} else {
JSFunction.alertBack("로그인에 실패했습니다.", out);
}
%>
'JSP > 성낙현의 JSP 자바 웹 프로그래밍' 카테고리의 다른 글
세션(Session) (2) | 2023.06.08 |
---|---|
데이터베이스(DB) (2) | 2023.06.07 |
내장 객체의 영역(Scope) (0) | 2023.05.30 |
내장 객체(Implicit Object) (0) | 2023.05.29 |
JSP 기본 (0) | 2023.05.27 |
댓글