모도리는 공부중

21.01.13. JSP&Servlet - Session 정보 지우기, 방문자수 올리기 본문

K-디지털 빅데이터 분석서비스 개발자과정 20.11.02~21.04.12/JAVA

21.01.13. JSP&Servlet - Session 정보 지우기, 방문자수 올리기

공부하는 모도리 2021. 1. 14. 09:04
728x90
반응형

- 저번시간 복습 -

 

Session 특징

  1. 서버에 저장(Session)
  2. 값을 저장시 Object로 저장
  3. 브라우저당 1개씩 발급
  4. 보안에 강력하다.
  5. 많은 양의 데이터 저장

금융사이트는 5분, 보통 사이트는 30분이 지나면 로그아웃되는 모습을 봤을 것이다. 이게 바로 Session이 용량 최적화를 위해 하는 행동이자 보안을 지키는 방법.

 

어제 진행했던 코드를 다시 가져와서 설명을 이어가보도록 하자. 주석을 모두 제거하고 코드만 깔끔하게 가져와봤다.

package com;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@WebServlet("/MakeSession")
public class MakeSession extends HttpServlet {

	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		String name = "모도리";
		
		HttpSession session = request.getSession();
        
		session.setAttribute("name", name);
		
	}

}

코드를 먼저 전체보기.

 

아래는 위 코드를 하나씩 뜯어서 설명.

HttpSession session = request.getSession();

request객체를 통해 session을 가져와서 HttpSession session에 저장.

session.setAttribute("name", name);

session.setAttribute을 이용해 session에 값을 넣어주는데 이름(name)은 String, 값(value)은 object로 넣어준다.

 

 

이렇게 회원정보를 session에 저장해줬으니 우리는 session에서 getAttribute를 이용해 값을 가져와줄 수 있다.

<%@page import="com.MemberDTO"%>
<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
</head>
<body>
<%
	MemberDTO dto1 = (MemberDTO)session.getAttribute("Info");
%>
이름 : <%= dto1.getName() %>
<br>
나이 : <%= dto1.getAge() %>
<br>
전화번호 : <%= dto1.getPhone() %>
</body>
</html>

일단 코드(view.jsp)는 다시 똑같이 가져오고, 이를 상세하게 풀어서 보자.

 

값을 가져오면,

MemberDTO dto1 = session.getAttribute("Info");

session.getAttribute("info");에 빨간줄이 생겼을 것이다. 왜? 값의 자료형은 object이고 우리가 넣어주고자 하는 변수의 자료형이 바로 MemberDTO이기 때문. 강제형변환을 통해 맞춰주면 빨간줄 없이 잘 선언되는 것을 볼 수 있다.

 

 


 

오늘의 진도를 나가봅시다.

view.jsp 파일에서 body속 전화번호 아랫줄에 다음의 코드를 추가해줍시다.

<a href="Remove"> <!-- url맵핑값을 가진 servlet으로 이동 -->
	<button>정보지우기</button>
</a>

session에 남아있는 정보를 지울 수 있도록 Remove코드를 만들어보겠습니다.

 

Remove.java

package com;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@WebServlet("/Remove")
public class Remove extends HttpServlet {

	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		HttpSession session = request.getSession();
		
//		세션을 만료하는 방법은 2가지가 존재한다.
//		1. client의 세션을 전체 삭제하는 방법
//		session.invalidate();
//		세션에 넣어진 이름이 몇개가 되든 상관없이 전부 삭제하는 코드 : invalidate()
		
//		2. client의 원하는 이름만 찾아서 삭제하는 방법
		session.removeAttribute("Info");
//		원하는 하나만 지울 때 removeAttribute(name) 사용. name값에 지우고픈 이름을 넣어주면 된다.
//		우리는 위에 있는 두가지 방법 중 하나만 찾아서 삭제하는  remove를 사용할 것이므로 invalidate는 주석처리해주도록 한다.
		
		response.sendRedirect("start.html");
	}

}

코드 주석처리한 것에도 나와있듯이 세션을 만료하는 방법에는 2가지가 있다.

  1. client의 세션을 전체 삭제
    • session.invalidate()
      • 여기에서 invalidate가 세션에 있는 정보가 몇개든지 상관없이 전부 삭제해주는 역할을 한다.
  2. client의 세션에서 원하는 이름만 찾아서 삭제
    • session.removeAttribute(name)
      • 원하는 하나의 이름만 찾아서 지우고자 할 때 사용하는 removeAttribute.
      • name 자리에 지워줄 세션 이름을 적어주면 해당 이름 세션에 저장된 내용만 깔끔히 지워주며, 다른 이름은 건드리지 않는다.

이렇게 session을 지워주고 나서 다시 start.html을 실행해서 '정보보기'버튼을 누르면 해당 세션이 삭제되어 500 error페이지를 띄우게 된다. 이때 발생하는 문제는 무엇일까?

  • 코드 어느 부분에서 문제가 발생했는지 상세하게 알려준다.

이게 단순히 학습하는 입장에서는 어느 부분에서 어떤 익셉션오류가 발생했는지 보여지기 때문에 좋을 수 있지만, 내가 이 페이지를 서비스하는 입장이 된다면 프로그래밍 언어를 아는 사람에게 떡하니 내 코드를 보여주는 문제가 발생된다. 그렇게 되면 "기다리고 있었습니다.. 해킹해보시지요..^^" 하는 것과 같은 행위.

 

이런 문제가 발생하지 않도록 삭제가 되고 나면 정보보기 버튼을 눌렀을 때 다음 페이지로 넘어가지 않게끔 if else처리를 해주는 것이 좋다.

<%
if(dto1 == null){
	response.sendRedirect("start.html");
}else{
%>
<!-- 정보 표시란 -->
<% } %>

 

이렇게 해주면 이제 '정보보기'를 눌렀을 때 해당 세션이 삭제됨으로 인해서 사용자에게 어떤 에러인지 보여주는 500error페이지로 넘어가지 않고 첫화면에서 그대로 머물러있게 된다.

 

Info.java로 돌아옵시다. 세션에 나이를 줘볼까요?

일단 info.java 전체코드

package com;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@WebServlet("/Info")
public class Info extends HttpServlet {

	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
//		이름, 나이, 전화번호 세션에 저장
//		우리가 지금까지 부른 vo를 웹에서는 dto라고 부른다. 이제부터는 dto라고 부르도록 하자.
		MemberDTO dto1 = new MemberDTO("모도리", 30, "010-2580-2580");
//		dto1내 정보를 session에 info라는 이름으로 저장하시오
		
		HttpSession session = request.getSession();
		session.setAttribute("info", dto1);
		
		response.sendRedirect("view.jsp");
	}

}

HttpSession session = request.getSession(); 여기 다음줄에 나이를 주는 코드를 추가.

session.setMaxInactiveInterval(10);

10초가 지난 후 새로고침을 하면 세션이 만료되어 세션에 저장되어있던 정보를 다시 불러올 수 없게 될 것이다.

 

 

(지금까지의 수업 중에서 info, Info 대문자 소문자 관련한 코드 오류가 있는 것 같으니 이 부분을 찾아서 전체적으로 수정 후 노트도 다시 수정해야할 것 같다.)

 

 


 

JSP 내장 기본 객체 영역

 

  • Scope : 웹 서버 일정 영역

 

  • page - 하나의 JSP 페이지를 처리할 때 사용되는 영역  
  • request - 하나의 요청을 처리할 때 사용되는 영역
  • session - 하나의 브라우저와 관련된 영역
  • application - 하나의 웹 애플리케이션과 관련된 영역

 

내장객체 메소드
  • setAttribute(name, value) : 이름(name)에 값(value)을 설정함.
  • getAttribute(name) : 매개 변수로 준 이름에 설정된 값을 얻어냄.
  • removeAttribute(name) : 매개 변수로 준 이름에 설정된 값을 제거함.

 

 


 

새로운 다이나믹 웹 프로젝트를 만들어봅시다. → Scope

 

WebContent폴더에 page1.jsp 생성.

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
</head>
<body>
	<h1>Page1 입니다.</h1>
	
	<%
		pageContext.setAttribute("page", "페이지 값 존재"); // 하나의 JSP 페이지를 처리할 때 사용되는 영역
		request.setAttribute("request", "리퀘스트 값 존재"); // 하나의 요청을 처리할 때 사용되는 영역
		session.setAttribute("session", "세션 값 존재"); // 하나의 브라우저와 관련된 영역
		application.setAttribute("application", "어플리케이션 값 존재"); // 하나의 프로젝트와 관련된 영역
	%>
	
	<%
		String pageValue = (String) pageContext.getAttribute("page");
		String requestValue = (String) request.getAttribute("request");
	//	페이지 간에 데이터를 옮길 때는 parameter, 세션을 통해 값을 옮길 때는 Attribute
	//	getParameter()는 client가 요청한 값을 꺼낼때는 get&post 상관 없이 가지고 오는 것
	//	getAttribute()는 내가 서버 리퀘스트 서버 객체 안에 넣은 것을 꺼낼 때 사용.
		String sessionValue = (String) session.getAttribute("session");
		String applicationValue = (String) application.getAttribute("application");
	%>
	
	page 값 : <%= pageValue %><br>
	request 값 : <%= requestValue %><br>
	session 값 : <%= sessionValue %><br>
	application 값 : <%= applicationValue %>
	
</body>
</html>

결과 :

 

page1코드를 그대로 복사해서 page2에 붙여넣고 몇 부분만 수정해봅시다.

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
</head>
<body>
	<h1>Page2 입니다.</h1>
	
	<%
		String pageValue = (String) pageContext.getAttribute("page");
		String requestValue = (String) request.getAttribute("request");
		String sessionValue = (String) session.getAttribute("session");
		String applicationValue = (String) application.getAttribute("application");
	%>
	
	page 값 : <%= pageValue %><br>
	request 값 : <%= requestValue %><br>
	session 값 : <%= sessionValue %><br>
	application 값 : <%= applicationValue %>
	
</body>
</html>

세팅하는 부분 코드를 삭제하고 page1코드에는 하단에 다음과 같은 코드 한 줄을 삽입한다.

<% response.sendRedirect("page2.jsp"); %>

그리고 결과를 보면?

response.sendRedirect 부분 때문에 page2.jsp로 넘어가서 해당 코드가 실행된 것을 볼 수 있다.

page2에서는 값을 넣는 코드를 지우고 꺼내는 부분만 남겨뒀는데 session값과 application값만 존재한다.

 

이유가 무엇일까?

  • page는 해당 page에서만 존재한다.
  • request는 요청이 있어야만 값이 넘어온다.
  • session은 브라우저가 꺼지지 않는 한 값이 남아있다.
  • applicataion은 세션보다 큰 값으로 서버가 살아있는 한 값이 남아있게 된다.

 

페이지를 이동하는 방식은 2가지가 있다.

Redirect방식과 Forword방식

 

page1에서 response.sendRedirect 코드를 주석처리하고 다음과 같이 코드를 추가해주자.

<%-- <% response.sendRedirect("page2.jsp"); %> --%>
<!-- forword 방식 -->
<%
	// 경로설정
	RequestDispatcher dis = request.getRequestDispatcher("page2.jsp");
	// 페이지 이동
	dis.forward(request, response);
	//forward(request, response)를 통해 페이지를 이동할 때 현재 안에 있는 request와 response를 보내줄 수 있다.
%>

 

forword방식은 데이터 손실 없이 그대로 옮겨야할 때 사용하는 것이 좋고,

전체 홈페이지 안에서 값을 계속 써야한다면 session을 쓰는 것이 좋다.

forword방식을 구분해서 사용하는 것이 어렵다면 session을 쓰시오!

 

forword방식은 url이 바뀌지 않고 확장하는 방식이기 때문에 리퀘스트를 그대로 받아서 넘겨주게 된다.

 

session을 쓰면 안되는 부분? - 싸이월드의 방문자수!

방문자수 올리는 부분을 실습해봅시다.

 

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
</head>
<body>
	<%
		/* 방문자수는 다같이 올라가야하므로 application에 넣어야한다.
		session에 넣으면 각자 방문자수가 다르게 올라가므로 application 사용! */
		application.setAttribute("today", "1");
		
		// 값을 꺼내서 String타입 today에 저장.
		String today = (String) application.getAttribute("today");
	%>
	오늘 방문자 수 : <%= today %>
</body>
</html>

 

새로고침을 누를때마다 방문자수가 오르는 것은 숙제!

728x90
반응형
Comments