본문 바로가기

Programming/국비학원

220928 - 서블릿 - 쿠키, 세션

쿠키
  • 쿠키로 팝업창 제한 (24시간)
  • popupTest.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>쿠키 이용한 팝업 제한 실습</title>
<script type="text/javascript">
	window.onload = function(){ //html 모두 업로드 후 실행
		
		let notShowPopup=getCookieValue();
	
		if (notShowPopup != "true"){ //맨 처음에는 false 값 받아와 팝업 뜨게 함 //true면 open X
			window.open("popup.html","popup","width=400, height=500");
			
		}
		
	}
	
	function getCookieValue(){ //onload 시 호출됨
		
		let result = "false";
	
		if (document.cookie != ""){ //쿠키가 있으면
			
			let cookie = document.cookie.split(";");
//popup.html => document.cookie="notShowPop=true;path=/;expires=expireDate.toGMTString()"; 
			
			for (let i=0;i<cookie.length;i++){
				let element = cookie[i].split("=");
				let value = element[0];
				value = value.replace(/^\s*/,""); //정규표현식 //^, 공백, * 없애기
				if (value=="notShowPop"){
					result = element[1]; //true 대입
				}
			}
		
		}
		
		return result;
		
	}
	
	function deleteCookie(){ //input 클릭 시 호출됨
		
		document.cookie="notShowPop=false;path=/;expires=-1";
		
	}
</script>
</head>
<body>
	<h1>팝업창 제한하는 실습</h1>
	<input type="button" value="쿠키 삭제" onclick="deleteCookie()">
</body>
</html>

 

 

 

  • popup.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>공지사항</title>
<script>
	function setPopup(obj){ //닫기 버튼 누르면 실행
		if (obj.checked==true){
        		//유효기간 변수 설정(오늘 일자 + 하루)
			let expireDate = new Date();
			let days=1;
			expireDate.setDate(expireDate.getDate()+days); 
			
			document.cookie="notShowPop=true;path=/;expires=expireDate.toGMTString()"; 
			//쿠키 정보에 변수, 값 넣음
			//notShowPop: 사용자지정변수 path=/ : 모든 경로에서 쿠키 설정 expires: 유효일자 지정
			window.close(); //창 닫기
		}
	}
</script>
</head>
<body>
	<h2>공지사항</h2>
	<p>코로나 조심</p>
	<p>다음주 월요일까지 휴무, 화요일에 서버 프로그램 구현 평가 있음</p>
	<p>회원가입, 목록보기 - 데이터베이스 연결 (오라클)</p>
	<p>로그인 수업 (수,목)과 관련</p>
	<br><br>
	<input type="checkbox" onclick="setPopup(this)">오늘 팝업창 띄우지 않기 <!-- this => html의 정보 보냄 -->
</body>
</html>

 

 

 

 

세션
  • 특징

서버의 메모리에 정보 저장
세션 쿠키를 이용해 브라우저의 세션 연동 
쿠키보다 보안에 유리
서버 부하에 영향
브라우저(사용자) 당 한 개의 세션(세션 id) 생성
유효 시간 있음 (기본 30분)
로그인 유지 / 장바구니 기능에 주로 사용

 

 

 

 

  • 과정

클라이언트가 브라우저로 사이트 접속
서버 => 접속한 브라우저에 대한 세션 객체를 생성, 세션id를 클라이언트 브라우저에 응답
브라우저 => 서버로부터 받은 세션id를 브라우저가 사용하는 메모리의 세션 쿠키에 저장 (쿠키 이름 jsessionId)
브라우저 재접속 => 브라우저는 세션 쿠키에 저장된 세션 id를 서버에 전달
서버 => 전송된 세션 id를 이용해 해당 세션에 접근, 작업 수행

 

 

 

 

  • HttpServletRequest 클래스 getSession() 메소드

=> HttpSession 클래스 객체 반환/생성

getSession()
: 기존 세션 객체(HttpSession 클래스 객체)가 존재하면 반환하고, 없으면 새로 생성

getSession(true)
: 기존 세션 객체가 존재하면 반환하고, 없으면 새로 생성

getSession(false)
: 기존 세션 객체가 존재하면 반환하고, 없으면 null 반환

 

 

 

 

 

  • HttpSession 클래스 메소드

Object getAttribute(String name)
: 속성 이름이 name인 속성 값을 Object 타입으로 반환

해당되는 속성 이름이 없을 경우 null 값 반환

Enumeration getAttributeNames()
: 세션 속성 이름들을 Enumeration 객체 타입으로 반환

long getCreationTime()
: 현재 세션이 생성된 시간 계산하여 1/1000초 값으로 반환

long getLastAccessedTime()
: 웹 브라우저가 가장 마지막에 세션에 접근한 시간 계산해 1/1000초 값으로 반환

String getId()
: 세션에 할당된 고유 식별자를 String 타입으로 반환

int getMaxInactiveInterval()
: 현재 세션 유지 시간을 int 타입으로 반환

void invalidate()
: 현재 생성된 세션을 소멸

boolean isNew()
: 최초로 생성된 세션인지 기존에 생성되어 있었던 세션인지 판별

void removeAttribute(String name)
: 세션 속성 이름이 name인 속성을 제거

setAttribute(String name, Object value)
: 세션 속성 이름이 name인 속성에 속성 값으로 value를 할당

void setMaxInactiveInterval(int interval)
: 세션 유지 시간을 초 단위로 설정

 

 

 

 

  • 세션 객체 생성
  • SessionTest
@WebServlet("/session")
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.print("세션 아이디 : " + session.getId() + "<br>");
		out.print("최초 세션 생성 시각 : " + new Date(session.getCreationTime()) + "<br>");
		out.print("최근 세션 접근 시각 : " + new Date(session.getLastAccessedTime()) + "<br>");
		out.print("세션 유효 시간 : " + session.getMaxInactiveInterval() + "<br>");
		
		if (session.isNew()) { //최초 생성된 세션인지 확인
			out.print("새로운 세션 생성 완료");
		}
	}

}

//
세션 아이디 : 86DB95516231CA65FB030777CE9EEE02
최초 세션 생성 시각 : Wed Sep 28 17:40:42 KST 2022
최근 세션 접근 시각 : Wed Sep 28 17:40:42 KST 2022
세션 유효 시간 : 1800
새로운 세션 생성 완료

//재접속시
세션 아이디 : 86DB95516231CA65FB030777CE9EEE02
최초 세션 생성 시각 : Wed Sep 28 17:40:42 KST 2022
최근 세션 접근 시각 : Wed Sep 28 17:41:43 KST 2022
세션 유효 시간 : 1800

 

 

 

 

  • 세션 유효시간 설정
  • SessionTest2
@WebServlet("/session2")
public class SessionTest2 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.print("세션 아이디 : " + session.getId() + "<br>");
		out.print("최초 세션 생성 시각 : " + new Date(session.getCreationTime()) + "<br>");
		out.print("최근 세션 접근 시각 : " + new Date(session.getLastAccessedTime()) + "<br>");
		session.setMaxInactiveInterval(5); //유효시간 1초로 세팅
		out.print("세션 유효 시간 : " + session.getMaxInactiveInterval() + "<br>");
		
		if (session.isNew()) { 
			out.print("새로운 세션 생성 완료");
		}
	}

}

 

※ 기본 유효시간 변경
Server - web.xml - <session-config><session-timeout> 태그
숫자 수정 시 기본 유효 시간 변경됨

 

 

 

 

  • 세션 삭제
  • SessionTest3
@WebServlet("/session3")
public class SessionTest3 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.print("세션 아이디 : " + session.getId() + "<br>");
		out.print("최초 세션 생성 시각 : " + new Date(session.getCreationTime()) + "<br>");
		out.print("최근 세션 접근 시각 : " + new Date(session.getLastAccessedTime()) + "<br>");
		out.print("세션 유효 시간 : " + session.getMaxInactiveInterval() + "<br>");
		
		if (session.isNew()) { 
			out.print("새로운 세션 생성 완료");
		}
		session.invalidate(); ////
	}

}

 

 

=> 브라우저 접속할 때마다 새로운 세션 생성, 바로 삭제됨

 

 

 

 

세션 바인딩

getSession() 으로 세션(한 명의 사용자) 확인 -> 객체를 세션에 바인딩해 사용자 정보 유지

 

 

 

  • 로그인 (세션 바인딩)
  • Server/context.xml

<Manager pathname="" /> 추가

 

 

 

  • login2.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>로그인 창</title>
</head>
<body>
	<form action="logins" method="post" name="formLogin">
		<label for="user_id">아이디 : </label>
		<input type="text" id="user_id" name="user_id"><br>
		<label for="user_pw">비밀번호 : </label>
		<input type="text" id="user_pw" name="user_pw"><br>
		<input type="hidden" name="phone" value="010-1111-2222"><br>
		<input type="hidden" name="address" value="서울시 종로구">
		<input type="submit" value="로그인">
		<input type="reset" value="다시 입력">
	</form>
</body>
</html>

 

 

 

  • LoginSessionTest
@WebServlet("/logins")
public class LoginSessionTest 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 id = request.getParameter("user_id");
		String pw = request.getParameter("user_pw");
		
		if (session.isNew()) {
			
			if (id != null && id.length() != 0) { //id 입력 시
				session.setAttribute("_id", id); //hashmap으로 저장
				out.print("<a href='logins'>로그인 상태 확인</a>");
			} else { //id 미입력 시
				out.print("<a href='login2.html'>다시 로그인 하세요</a>");
				session.invalidate(); //세션 강제 삭제
			}
			
		} else { //새로 생성된 세션이 아니면
			
			id = (String)session.getAttribute("_id"); //기존 세션 값 가져옴
			if (id != null && id.length() != 0) {
				out.print("안녕하세요 " + id + "님!");
			} else { //로그인하지 않고 바로 /logins 방문 시
				out.print("<a href='login2.html'>다시 로그인 하세요</a>");
				session.invalidate();
			}
			
		}
	}

}

 

login2.html 에서 로그인 정보 입력 
-> /logins 로 이동, 로그인 상태 확인 클릭 
-> 안녕하세요 a님!

 

 

+ 처음에 id 입력 여부 판단하는 if문 조건으로 id != null 하나만 추가했었는데

이때 id칸을 비우고 제출해도 null이 아닌 것으로 인식됐는지 else문으로 안 넘어가 결국 length 관련 조건도 추가했다

미입력했을 때 length=0 이지만 null은 아닌 공백으로 인식된 것 같다

 

 

 

 

  • 로그인 (세션 바인딩 + db 연결)
  • login3.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>로그인 창</title>
</head>
<body>
	<form action="logindb" method="post" name="formLogin">
		<label for="user_id">아이디 : </label>
		<input type="text" id="user_id" name="user_id"><br>
		<label for="user_pw">비밀번호 : </label>
		<input type="text" id="user_pw" name="user_pw"><br>
		<input type="hidden" name="phone" value="010-1111-2222"><br>
		<input type="hidden" name="address" value="서울시 종로구">
		<input type="submit" value="로그인">
		<input type="reset" value="다시 입력">
	</form>
</body>
</html>

 

 

 

  • MemberVO 재사용

 

 

https://all-record.tistory.com/104 (DB 연동 재참고)

  • MemberDAO
public class MemberDAO {

	private Connection con; 
	private PreparedStatement pstmt; 
	private DataSource dataFactory;
	
	public MemberDAO() { 
		try {
			Context ctx = new InitialContext();
			Context envContext = (Context)ctx.lookup("java:/comp/env");
			dataFactory = (DataSource) envContext.lookup("jdbc/oracle");
		} catch(Exception e) {
			System.out.println("DB 연결 실패");
		}
	}
	
	//회원정보 목록
	public List<MemberVO> listMembers(){
		
		List<MemberVO> list = new ArrayList<MemberVO>();
		try {
			con = dataFactory.getConnection(); //서버 통해 db 연결
			String query = "select * from member_list";
			pstmt = con.prepareStatement(query);
			ResultSet rs = pstmt.executeQuery(); //쿼리 실행
			while(rs.next()) { //쿼리 결과값 한 행씩
				String id = rs.getString("id");
				String pwd = rs.getString("pwd");
				String name = rs.getString("name");
				String email = rs.getString("email");
				Date joinDate = rs.getDate("joindate");
				
				MemberVO vo = new MemberVO();
				vo.setId(id);
				vo.setPwd(pwd);
				vo.setName(name);
				vo.setEmail(email);
				vo.setJoindate(joinDate);
				
				list.add(vo);
			}
			rs.close();
			pstmt.close();
			con.close();
		} catch(Exception e) {
			System.out.println("자료 처리 중 에러 발생");
		}
		return list;
		
	}
	
	public void addMember(MemberVO memberVO) {
		try {
			con = dataFactory.getConnection();
			
			String id = memberVO.getId();
			String pwd = memberVO.getPwd();
			String name = memberVO.getName();
			String email = memberVO.getEmail();
			
			String query = "insert into member_list(id, pwd, name, email) values(?,?,?,?)";
			pstmt = con.prepareStatement(query);
			pstmt.setString(1, id);
			pstmt.setString(2, pwd);
			pstmt.setString(3, name);
			pstmt.setString(4, email);
			pstmt.executeUpdate();
			pstmt.close();
		} catch(Exception e) {
			System.out.println("회원 추가 중 에러 발생");
		}
	}
	
	public void delMember(String id) {
		try {
			con = dataFactory.getConnection();
			String query = "delete from member_list where id=?";
			pstmt = con.prepareStatement(query);
			pstmt.setString(1,id);
			pstmt.executeUpdate();
			pstmt.close();
		} catch(Exception e) {
			System.out.println("삭제 중 에러 발생");
		}
	}
	
	//로그인 정보 확인
	public boolean exists(MemberVO memberVO) {
		boolean result=false;
		
		String id = memberVO.getId();
		String pwd = memberVO.getPwd();
		
		try {
			con = dataFactory.getConnection();
			String query = "select decode(count(*),1,'true','false') as result"
					+ " from member_list where id=? and pwd=?";
			//decode(식, 조건, 참일 때, 거짓일 때)
			pstmt = con.prepareStatement(query);
			pstmt.setString(1, id);
			pstmt.setString(2, pwd);
			ResultSet rs = pstmt.executeQuery(); //쿼리문 실행, 커서 집합 변수에 전달
			rs.next(); //하나의 값 가져옴 (result=true/false)
			result = Boolean.parseBoolean(rs.getString("result")); //true나 false 변수에 전달
			pstmt.close();
		} catch(Exception e){
			System.out.println("DB 처리 중 에러");
		}
		
		return result;
	}
	
}

 

 

 

  • LoginDBServlet (미완)
@WebServlet("/loginDBServlet")
public class LoginDBServlet 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();
		
		//db는 서버 context에서 이미 연결
		
		//브라우저에서 아이디, 비밀번호 받아 MemberVO에 세팅
		String id = request.getParameter("user_id");
		String pwd = request.getParameter("user_pw");
		MemberVO memberVO = new MemberVO();
		memberVO.setId(id);
		memberVO.setPwd(pwd);
		
		//회원정보 DB에 memberVO 회원 있는지 확인
		MemberDAO dao = new MemberDAO();
		boolean result = dao.exists(memberVO);
		if (result) {
			HttpSession session = request.getSession();
			session.setAttribute("loggedIn", true); //로그인 여부 정보 추가
			session.setAttribute("login_id", id); //아이디 정보
			session.setAttribute("login_pwd", pwd); //비밀번호 정보
			
			out.print("<html><body>");
		} else {
			out.print("");
		}
		
	}
	
}