1. 웹 페이지 연결 기능
웹 프로그램에서 사용되는 정보는 서블릿의 비즈니스 로직 처리 기능을 이용해 데이터베이스에서 가져온다.
그러나 동시 사용자 수가 많아지면 데이터베이스 연동 속도도 영향을 받게 되므로 정보의 종류에 따라 어떤 정보들은 클라이언트 PC나 서버의 메모리에 저장해두고 사용하면 좀 더 빠르게 프로그램을 실행시킬 수 있다.
세션 트래킹
HTTP 프로토콜은 서버-클라이언트 통신 시 stateless 방식으로 통신을 한다.
즉 브라우저에서 새 웹 페이지를 열면 기존의 웹 페이지나 서블릿에 관한 어떤 연결 정보도 새 웹 페이지에서는 알 수 없다
HTTP 프로토콜은 각 웹 페이지의 상태나 정보를 다른 페이지들과 공유하지 않는 stateless 방식으로 통신을 한다.
따라서 웹 페이지나 서블릿끼리 상태나 정보를 공유하기 위해서는 웹 페이지 연결 기능, 즉 세션 트래킹을 이용해야 한다.
웹페이지 연동하는 방법
- <hidden> 태그 : HTML의 <hidden> 태그를 이용해 웹 페이지들 사이의 정보를 공유함
- URL Rewriting : GET 방식으로 URL 뒤에 정보를 붙여 다른 페이지로 전송
- 쿠키 : 클라이언트의 PC의 Cookie 파일에 정보를 저장한 후 웹 페이지들이 공유함
- 세션 : 서버 메모리에 정보를 저장한 후 웹 페이지들이 공유함
2. <hidden> 태그와 URL Rewriting 이용해 웹 페이지 연동하기
2-1. <hidden> 태그를 이용한 세션 트래킹 실습
웹 프로그램에서 사용되는 정보는 서블릿의 비즈니스 로직 처리 기능을 이용해 데이터베이스에서 가져온다.
그러나 동시 사용자 수가 많아지면 데이터베이스 연동
<hidden> 태그 : 브라우저에는 표시되지 않지만 미리 저장된 정보를 서블릿으로 전송하는 기능
login.html
<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="다시 입력">
<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-1111-2222" />
</form>
</body>
LoginServlet.java
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html; charset=utf-8");
request.setCharacterEncoding("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);
}
2-2. URL Rewriting을 이용한 세션 트래킹 실습
이번에는 URL rewriting을 이용해 로그인창에서 입력받은 ID와 비밀번호를 다른 서블릿으로 전송하여 로그인 상태를 확인해본다.
LoginServlet.java
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html; charset=utf-8");
request.setCharacterEncoding("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);
}
user_address=URLEncoder.encode(user_address, "utf-8");
out.print("<a href='/pro09/second?user_id=" + user_id + "&user_pw=" +
"&user_address=" + user_address + "'>두번째 서블릿으로 보내기</a>");
data="</body></html>";
out.print(data);
}
public void destroy() {
System.out.println("destory 메소드 호출");
}
SecondServlet.java
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) {
// 첫 번째 서블릿의 ID 정보를 이용해 로그인 상태를 유지함
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'>로그인 창으로 이동하기</>");
}
}
<hidden> 태그와 GET 방식으로 웹 페이지들을 연동할 때의 단점
웹 페이지가 많아지면 일일이 로그인 상태를 확인하기 위해 로그인 정보를 다른 페이지로 전송
ID와 비밀번호를 GET 방식으로 전송하므로 브라우저에 노출
전송할 수 있는 데이터 용량 한계
따라서 이 방법들은 웹 페이지 사이에 간단한 정보 정도를 공유할 때만 사용하는 것이 좋다.
3. 쿠키를 이용한 웹 페이지 연동 기능
쿠키(Cookie)
웹 페이지들 사이의 공유 정보를 클라이언트 PC에 저장해놓고 필요할 때 여러 웹 페이지들이 공유해서 사용할 수 있도록 매개 역할을 하는 방법
쿠키의 특징
- 정보가 클라이언트 PC에 저장됨
- 저장 정보 용량에 제한(4kb)
- 보안이 취약
- 클라이언트 브라우저에서 사용 유무 설정이 가능
- 도메인당 쿠키가 만들어 짐(웹 사이트당 하나의 쿠키)
쿠키는 클라이언트 PC에 정보를 저장해서 사용하므로 보안에 취약하다.
따라서 이방법들은 보안과 무관한 경우에만 사용한다.
ex) 팝업창 : 오늘은 더이상 보지 않기 등
쿠키의 종류
속성 | Persistence 쿠키 | Session 쿠키 |
생성 위치 | 파일로 생성 | 브라우저 메모리에 생성 |
종료 시기 | 쿠키를 삭제하거나 쿠키 설정 값이 종료된 경우 | 브라우저를 종료한 경우 |
최초 접속 시 전송 여부 | 최초 접속 시 서버로 전송 | 최초 접속 시 서버로 전송되지 않음 |
용도 | 로그인 유무 또는 팝업창을 제한할 때 | 사이트 접속 시 Session 인증 정보를 유지할 때 |
Persistence 쿠키 : 클라이언트에 파일로 정보를 저장하는 기능
Session 쿠키 : 브라우저가 사용하는 메모리에 생성되는 쿠키
3-1. 쿠키 기능 실행 과정
1) 브라우저로 사이트에 접속
2) 서버는 정보를 저장한 쿠키를 생성
3) 생성된 쿠키를 브라우저로 전송
4) 브라우저는 서버로부터 받은 쿠키 정보를 쿠키 파일에 저장
5) 브라우저가 다시 접속해 서버가 브라우저에게 쿠키 전송 요청 시 브라우저는 쿠키 정보를 서버에 넘겨줌
6) 서버는 쿠키 정보를 이용해 작업함
3-2. 쿠키 API
쿠키는 Cookie 클래스 객체를 생성하여 정보를 저장한 후 서버에서 클라이언트로 전송해 파일로 저장
쿠키 관련 API의 특징
- javax.servlet.http.Cookie를 이용
- HttpServletResponse의 addCookie( ) 메서드를 이용, 클라이언트 브라우저에 쿠키를 전송한 후 저장
- HttpServletRequest의 getCookie( ) 메서드를 이용, 쿠키를 서버로 가져옴
쿠키 클래스의 여러 가지 메서드
메서드 | 설명 |
getComment( ) | 쿠키에 대한 설명을 가져옴 |
getDomain( ) | 쿠키의 유효한 도메인 정보를 가져옴 |
getMaxAge( ) | 쿠키 유효 기간을 가져옴 |
getName( ) | 쿠키 이름을 가져옴 |
getPath( ) | 쿠키의 디렉터리 정보를 가져옴 |
getValue( ) | 쿠키의 설정 값을 가져옴 |
setComment(String) | 쿠키에 대한 설명을 설정 |
setDomain(String) | 쿠키의 유효한 도메인을 설정 |
setMaxAge(int) | 쿠키 유효 기간을 설정 |
setValue(String) | 쿠키 값을 설정 |
setPath(String) | 쿠키의 디렉터리 정보를 설정 |
쿠키 생성 시 setMaxAge( ) 메서드 인자 값의 종류를 지정해서 파일에 저장하는 Persistence 쿠키를 만들거나 메모리에만 저장하는 Session 쿠키를 만들 수 있다. 즉, setMaxAge( ) 메서드를 이용한 쿠키 저장 방식은 다음 두 가지로 나눌 수 있다.
- 인자 값으로 음수나 setMaxAge( ) 메서드를 사용하지 않고 쿠키를 만들면 Session 쿠키로 저장
- 인자 값으로 양수를 지정 시 Persistence 쿠키로 저장
3-3. 서블릿에서 쿠키 사용하기
SetCookieValue.java
public class SetCookieValue extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html; charset=utf-8");
request.setCharacterEncoding("utf-8");
PrintWriter out = response.getWriter();
Date d = new Date();
//쿠키 객체를 생성한후 cookieTest이름으로 한글 정보를 인코딩해서 쿠키에 저장
Cookie c = new Cookie("cookieTest", URLEncoder.encode("JSP프로그래밍입니다.", "utf-8"));
//유효시간 설정
c.setMaxAge(24 * 60 * 60);
//생성된 쿠키를 브라우저로 전송
response.addCookie(c);
out.println("현재시간 : " + d);
out.println("<br> 문자열을 Cookie에 저장합니다");
}
}
GetCookieValue.java
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
// request의 getCookies()메서드를 호출해 브라우저에게 쿠키 정보를 요청한 후 쿠키 정보를 배열로 가저옴
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"));
}
}
}
3-4. 세션 쿠키 사용하기
쿠키를 파일에 저장하는 것이 아닌, 브라우저가 사용하는 메모리에 저장하는 Session쿠키를 만들어본다.
다음과 같이 Cookie의 setMaxAge( ) 메서드를 이용해 유효 시간을 -1로 설정하면 세션 쿠키가 생성된다.
SetCookieValue.java
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("JSP 프로그래밍입니다.","utf-8"));
// c.setMaxAge(24*60*60); // 주석 처리
c.setMaxAge(-1); // 유효 시간을 음수로 지정하여 Session 쿠키를 생성
response.addCookie(c);
out.println("현재시간 : " + d + "<br>");
out.println("문자열을 Cookie에 저장합니다.");
}
3-5. 쿠키 이용해 팝업창 제한하기
팝업창 제어는 서버에서 쿠키를 다루지 않고 자바스크립트를 이용해 쿠키에 직접 접근한다.
popUpTest.html
<script type="text/javascript">
//브라우저에서 웹 페이지가 로드될 떄 pageLoad()함수를 호출하여 실행
window.onload = pageLoad;
function pageLoad() {
//notShowPop의 쿠키 값을 getCookieValue()를 호출하여 얻음
notShowPop = getCookieValue();
//notShowPop의 값이 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";
if(document.cookie != "") {
//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*/,'');
//쿠키이름이 notShowPop이면 해당하는 쿠키값을 가져와 반환
if(value=="notShowPop") {
result=element[1];
}
}
}
return result;
}
function deleteCookie() {
document.cookie = "notShowPop=" + "false" + ";path=/; expires=-1";
}
</script>
</head>
<body>
<form>
<input type="button" value="쿠키삭제" onClick="deleteCookie()" >
</form>
</body>
popUp.html
<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>
popUptest로 실행을 시키면 팝업이 하나 뜨게 된다.
오늘 더 이상 팝업창 띄우지 않기를 누르면 setPopUpStart()함수를 호출해 notShowPop의 값을 true로 설정하여 재접속시 팝업을 나타내지 않도록 한다.
새로 고침을 눌러도 팝업창은 뜨지 않는다.
하지만 쿠키 삭제후 재요청을 하게되면 다시 팝업창이 나타나게 된다.
4. 세션을 이용한 웹 페이지 연동 기능
세션도 웹 페이지들 사이의 공유 정보를 서버에 저장해 두고 웹 페이지들을 매개해 주는 방법이라는 점은 쿠키와 같다.
하지만 쿠키는 사용 시 웹 페이지들의 정보가 클라이언트 PC에 저장되므로 정보가 쉽게 노출될 수 있다는 단점이 있는 반면, 세션은 서버의 메모리에 생성되어 정보를 저장한다.
따라서 웹 페이지에서 사용되는 정보 중 로그인 정보처럼 보안이 요구되는 정보는 대부분 세션을 사용한다.
세션은 각 브라우저당 한 개, 즉 사용자당 한 개가 생성된다. 사용자의 로그인 상태나 쇼핑몰의 장바구니 담기 기능 같은 정보를 해당 브라우저의 세션에 저장하고 사용하면 편리하다.
세션의 특징
- 정보가 서버의 메모리에 저장됨
- 브라우저의 세션 연동은 세션 쿠키를 이용함
- 쿠키보다 보안에 유리함
- 서버에 부하를 줄 수 있음
- 브라우저(사용자)당 한 개의 세션(세션 id)이 생성됨
- 세션은 유효 시간을 가짐(기본 유효 시간은 30분)
- 로그인 상태 유지 기능이나 쇼핑몰의 장바구니 담기 기능 등에 주로 사용됨
4-1. 세션 기능 실행 과정
1) 브라우저로 사이트에 접속
2) 서버는 접속한 브라우저에 대한 세션 객체를 생성
3) 서버는 생성된 세션 id를 클라이언트 브라우저에 응답
4) 브라우저는 서버로부터 받은 세션 id를 브라우저가 사용하는 메모리의 세션 쿠키에 저장(쿠키 이름은 jsessionId)
5) 브라우저가 재접속하면 브라우저는 세션 쿠키에 저장된 세션 id를 서버에 전달
6)서버는 전송된 세션 id를 이용해 해당 세션에 접근하여 작업을 수행
세션의 중요한 특징은 브라우저당 한 개씩 생성된다는 점이다.
그러므로 브라우저가 서버에 접속하여 브라우저에 저장된 세션 id를 전송하면 서버는 그 값을 이용해서 해당 브라우저에 대한 세션을 구분하고 각 브라우저에 대한 세션 작업을 수행한다.
4-2. 세션 기능 실행 과정
세션을 얻는 방법
서블릿에서 세션을 이용하기 위해 HttpSession 클래스 객체를 생성해서 사용함
HttpSession 객체는 HttpServletRequest의 getSession( ) 메서드를 호출해서 얻음
getSession( ) 메서드의 종류
getSession( ): 기존의 세션 객체가 존재하면 반환하고, 없으면 새로 생성
getSession(true): 기존의 세션 객체가 존재하면 반환하고, 없으면 새로 생성
getSession(false): 기존의 세션 객체가 존재하면 반환하고, 없으면 null을 반환
HttpSession 클래스의 여러 가지 메서드
반환 타입 | 메서드 | 설명 |
Object | getAttribute(String name) | 속성 이름이 name인 속성 값을 Object 타입으로 반환 해당되는 속성 이름이 없을 경우 null 값을 반환 |
Enumeration | getAttributeNames( ) | 세션 속성 이름들을 Enumeration 객체 타입으로 반환 |
long | getCreationTime( ) | 1970년 1월 1일 0시 0초를 기준으로 현재 세션이 생성된 시간까지 경과한 시간을 계산하여 1/1000초 값으로 반환 |
String | getId( ) | 세션에 할당된 고유 식별자를 String 타입으로 반환 |
int | getMaxInactiveInterval( ) | 현재 생성된 세션을 유지하기 위해 설정된 세션 유지 시간을 int 타입으로 반환 |
void | invalidate( ) | 현재 생성된 세션을 소멸시킴 |
boolean | isNew( ) | 최초로 생성된 세션인지 기존에 생성되어 있던 세션인지 판별함 |
void | removeAttribute(String name) | 세션 속성 이름이 name인 속성을 제거 |
void | setAttribute(String name, Object value) | 세션 속성 이름이 name인 속성에 속성 값으로 value를 할당함 |
void | setMaxInactiveInterval(int interval) | 세션을 유지하기 위한 세션 유지 시간을 초 단위로 설정함 |
참고자료 : 자바 웹을 다루는 기술
'💻 Web_Back end > Servlet' 카테고리의 다른 글
서블릿의 필터와 리스너 기능 (0) | 2023.04.26 |
---|---|
서블릿 API 사용하기 (0) | 2023.04.12 |
서블릿 비즈니스 로직 처리 (0) | 2023.04.07 |
서블릿 기초 2 (0) | 2023.04.06 |
서블릿의 기초1 (0) | 2023.04.05 |