본문 바로가기
백엔드/JSP & Servlet

JSP - 4 (세션 + 네트워크)

by study_yeon 2023. 6. 19.

2023.06.13  수업


● 네트워크 TCP/IP 4단계

* 네트워크 사이의 중개매체 : 허브, 스위치, 라우터

* 컴퓨터끼리 연결하기 위해 네트워크가 생기고 네트워크 집합을 연결하기 위해 인터넷이 생김

* 웹브라우저 HTML요청하고 다운로드 받는 것과
웹브라우저가 HTML 실행하여 화면에 보여주는 것은 다른 세션

 

* 웹브라우저(실체), 웹프로토콜(가상)

 

◎ TCP/IP 4단계 : 응용, 전송, 인터넷, 네트워크 액세스


○ 응용계층
- 데이터 생성
응용프로그램(애플리케이션 ex. 크롬)이 데이터를 생성하는 주체
웹 브라우저(애플리케이션)은 화면에 필요한 데이터를 요청하기 위해 HTTP 데이터를 생성

 

 전송계층
- 생성된 데이터를 필요한 곳으로 전송(송·수신)
- 패킷이 전송가능한지 확인하고 전송된 데이터를 일렬로 정리하여 보여줌
- 응용프로그램(ex. 크롬)이 페이지 요청을 위해 HTTP를 운영체제(ex. 윈도우)에 보냄
- 운영체제는 네트워크 통신을 원하는 응용프로그램에게 포트번호를 할당과 관리 
- 윈도우가 포트번호를 확인하여 크롬의 PID(프로세스 아이디)에게 HTTP 전달 
- 컴퓨터는 운영체제를 통하여 주소(포트번호)를 확인 가능

- 포트번호 캡슐화
- 크롬이 윈도우에게 HTTP를 전달하고 운영체제가 포트번호를 확인하여 HTTP를 애플리케이션에 전달 


 인터넷 계층
- 인터넷에서 목적지 주소를 찾기위한 단계

- IP주소의 캡슐화
- 운영체제가 담당
* 인터넷 : 네트워크와 네트워크의 연결 
* IP주소  : 인터넷에서 특정 주소를 의미하는 단어, 주소를 구분하고 찾기 위해 사용


 네트워크 계층

- NIC(network interface controller) : 컴퓨터의 고유한 주소를 표기하기 위한 장치
: 네트워크와 컴퓨터를 이어주는 인터페이스의 역할
- 이더넷 프로토콜은 주소를 표시하기 위해MAC(media access control)주소를 사용

: 유선이 연결되는 NIC나 무선와이파이를 송·수신할 수 있는 와이파이 모듈과 같은 장치를 구분하는 주소

- MAC주소를 통해 데이터가 도달 할 명확한 위치 확인 가능(NIC의 역할)

 

-> 데이터가 최종 목적지로 전송되기 위한 포트번호(1차주소), IP주소(2차주소), MAC(3차주소)가 필요

 

※ cmd ( netstat - ano 검색) 
* 상태
- LISTENING : 서버모드, 외부에서 들어올 수 있음

-> 보안을 위해 LISTENING된 포트번호를 확인해보기
(참고)135는 윈도우가 여는 포트, 모든 네트워크가 공유

* PID 확인
ctrl + alt + del > 작업관리자 > 자세히 > PID 확인가능


● jsp

* 쿠키 : 웹브라우저와 관계를 유지하는 수단

 

◎ 세션 
- 서버와의 관계를 유지하기 위한 수단
- 클라이언트에 값을 저장하는 것이 아니라 서버상에서 객체로 존재
- 서버에서만 접근이 가능
- 보안이 좋고 저장할 수 있는 데이터의 한계가 없음

 

○ 메소드 
- setAttribute() : 세션에 데이터 저장(값 설정), 
자바에서 사용하는 세션클래스 이용하기에 객체 직렬화를 하는 오브젝트방식으로 저장
- getAttribute() : 세션에서 데이터 얻기(값 읽기)
- getAttributeNames() : 세션에 저장되어 있는 모든 데이터의 이름(유니크한 키 값)을 얻음
- getId() : 세션의 유니크한 아이디 얻기
- isNew() : 세션이 최초 생성되었는지 이전에 생성된 세션인지 구분
- getMaxInactionInterval() : 세션의 유효시간을 얻음
- removeAttribute() : 세션에서 특정 데이터를 제거
- invalidate() : 세션의 모든 데이터를 삭제

▶ 실습 - 세션
-> 서버쪽 쿠키가 만들어졌다는 것 확인 


▷ 다이나믹웹프로젝트 만들기

- 2023.06.13.session

jsp 파일 만들기 

1. sessionSet.jsp - 세션 생성

1) session.setAttribute으로 세션 정의(저장)

2) 비슷한 내용은 배열과 반복문 통해 정의

* 제이슨에서 키는 문자열 , 내부적으로 변수의 역할
- 배열로 루프를 돌리기 가능

3) a태그로 링크 이동

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	session.setAttribute("SessionName", "SessionValue");
	session.setAttribute("asdfg", 12345);
	
	String[] fruitName = {"fruit1", "fruit2", "fruit3"};
	String[] fruitValue = {"사과", "감", "참외"};
	
	for (int i = 0; i < fruitName.length; i++) {
		session.setAttribute(fruitName[i], fruitValue[i]);
	}
	
	session.setAttribute("UHDTV", 100_000_000L); // long형 데이터타입
	session.setAttribute("세탁기", 500000.50); // double형
%>    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<a href="sessionGet.jsp">Session Get</a>

	
</body>
</html>


2. sessionGet.jsp - 세션 확인

0) 한글이 깨질 수 있으므로 request.setCharacterEncoding("UTF-8") 설정하기

1) session.getAttribute으로 값 읽기

- Object 형으로 데이터가 반환됨

- 원하는 데이터형으로 저장하기 위해 다운캐스팅 하기

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.util.Enumeration" %>    
    
<%
	request.setCharacterEncoding("UTF-8");
	// 업캐스팅
	Object obj1 = session.getAttribute("SessionName");
	String sessionName = (String)obj1; // 다운캐스팅
	// sessionName 출력
	out.println(sessionName + "<br />");
	
	Object obj2 = session.getAttribute("asdfg");
	Integer asdfg = (Integer)obj2;
	out.println(asdfg + "<br />");
	out.println("************************************* <br />");
	
	
	Object objFruit1 = session.getAttribute("fruit1");
	String fruit1 = (String)objFruit1;
	out.println("fruit1 = " + fruit1 + "<br />");
	
	Object objFruit2 = session.getAttribute("fruit2");
	String fruit2 = (String)objFruit2;
	out.println("fruit2 = " + fruit2 + "<br />");
	
	Object objFruit3 = session.getAttribute("fruit3");
	String fruit3 = (String)objFruit3;
	out.println("fruit3 = " + fruit3 + "<br />");
	
	Object obj3 = session.getAttribute("UHDTV");
	Long uhdtv = (Long)obj3;  // Long이 대문자이면 객체임
	out.println("UHDTV = " + uhdtv + "<br />");
	
	Object obj4 = session.getAttribute("세탁기");
	Double washer = (Double)obj4;
	out.println("세탁기 = " + washer + "<br />");
	out.println("************************************* <br />");

	
%>    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

</body>
</html>

* 한글로 세션을 저장한다면(세탁기) 위험한 이유
- 문자코드 체계에 기반되기 때문에 앞에서 유니코드로 보내면 받는 곳에서도 유니코드로 받는 것이 좋음(문자코드가 일치해야함)
- 한글로 세션을 저장하면 오류가 발생할 수 있으니 명시적으로 유니코드로 지정해주어 양쪽이 같게 해야함
request.setCharacterEncoding("UTF-8");
-> 요청값을 무조건 UTF-8로 해독하도록 설정

 

* 출력물은 HTML이기 때문에 \n이 아닌 </br>를 사용

 

2) 세션 정보 얻기

※ 열거형 인터페이스(Enumeration ) 활용하여 저장된 값들을 직렬화로 저장하기 

* Enumeration 객체의 중요 메소드
㉮ hasMoreElements() : 남아있는 자료가 있는가
- 있으면 true, 없으면 false
㉯ nextElement() : 있는 내용 중 다음 요소를 하나 가져와라
- hasMoreElements()를 통해 다음 요소가 있으면 nextElement()함수로 다음 요소를 가져와 요소의 속성을 사용한다 

 

* enumeration : 반복이 허용되는 객체, 순환 인터페이스
- enumeration 객체는 컬렉션 인터페이스이므로 같은 형식의 자료이기에 반복이 가능하다
- 비슷한 타입을 하나의 객체로 관리함
ex) rs.next(), session

 세션의 모든 요소 얻기 : session.getAttributeNames()
Enumeration은 유틸 import 필요

* 반복문을 활용해 세션의 이름을 뽑아냄

- while(true)가 되어 반복실행

- sName과 sValue에 세션에 저장된 이름과 값을 저장

- getId()를 통해 ID값 출력 : 세션의 정보 얻기
- getMaxInactiveInterval()를 따로 설정하지 않으면 기본값(30분)으로 출력됨

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.util.Enumeration" %>    
    
<%
	request.setCharacterEncoding("UTF-8");
	동일
	
	/// Enumeration(열거형 클래스)를 사용하여 Session의 모든 요소에 반복문으로 접근하기
	String sName; // 세션 요소의 키 이름
	String sValue; // 세션 요소의 키 이름에 대한 값
	
	/// 세션의 모든 요소 얻기 : session.getAttributeNames()
	// Enumeration은 import 필요
	Enumeration enumeration = session.getAttributeNames();
	// enumeration 객체는 컬렉션 인터페이스이므로 같은 형식의 자료이기에 반복이 가능하다
	while(enumeration.hasMoreElements()) {
		// 세션요소의 키의 모음이므로 그 중 세션 키 이름 하나를 가져옴
		sName = enumeration.nextElement().toString();
		// 세션객체에서 키 값을 이용하여 실제 세션 값을 가져옴
		// 간략히 하려고 세션요소객체의 toString()메소드를 문자열로 출력
		// 오브젝트가 나와서 문자로 변환하기 위해 .toString()
		sValue = session.getAttribute(sName).toString();
		out.println("sName : " + sName + "<br />");
		out.println("sValue : " + sValue + "<br />");
	}
	out.println("#######################################<br />");
	
	/// 세션정보 얻기
	String sessionID = session.getId(); // 세션이 처음 만들어지면 자동으로 생기는 유일한 코드키
	out.println("SessionID : " + sessionID + "<br />");
	// 세션 만료시간 (단위 : 초)
	int sessionInterval = session.getMaxInactiveInterval();
	out.println("세션 만료 시간 : " + sessionInterval + "<br />");
	out.println("#######################################<br />");
	
	
%>    

동일

3)  세션의 요소 삭제하기(각각 삭제)

- session.removeAttribute("삭제할 키 이름")
㉮ SessionName, asdfg라는 이름을 가진 세션 삭제

㉯ 삭제된 세션 요소 확인

- 열거형인터페이스로 다시 세션의 이름을 불러와 출력

-> hasMoreElements() : 0이 될 것

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.util.Enumeration" %>    
    
<%
	request.setCharacterEncoding("UTF-8");
	동일
		
	/// 세션의 요소 삭제하기
	// session.removeAttribute("삭제할 키 이름") : 세션요소 삭제 메소드
	// 세션요소 'SessionName' 삭제
	session.removeAttribute("SessionName");
	// 세션요소 'asdfg' 삭제
	session.removeAttribute("asdfg");
	// 삭제된 세션요소 확인
	Enumeration enums = session.getAttributeNames();
	while(enums.hasMoreElements()) {
		sName = enums.nextElement().toString();
		sValue = session.getAttribute(sName).toString();
		out.println("sName : " + sName + "<br />");
		out.println("sValue : " + sValue + "<br />");
	}
	out.println("#######################################<br />");
	
	}
	
%>    

동일

4) 세션 무효화(= 초기화 =로그아웃)

* invalidate()를 통해 모든 세션이 삭제됨

-> 더이상의 요소가 없어서 아무런 세션도 출력되지 않음

- session.invalidate() 
-> 클라이언트 쿠키도 삭제가 됨

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.util.Enumeration" %>    
    
<%
	request.setCharacterEncoding("UTF-8");
	동일
	
	/// 세션 무효화(=로그아웃)
	session.invalidate(); // 세션 초기화 하는 명령
	// 확인 작업(현재 세션정보가 정당한가)
	if(request.isRequestedSessionIdValid()) {
		out.println("현재 세션이 살아있습니다.");
	} else {
		// 세션이 무효화된 경우 = 로그아웃 -> 새로 로그인해야함
		out.println("현재 세션이 초기화되었습니다.");
	}
	
%>    

동일


* 디버그 
중단점 

- 순서가 없이 저장 

* 비밀번호는 데이터베이스에서 확인 불가
- 비밀번호는 찾을 수 없고 초기화를 해야함

* 디버그 
중단점
* isValid를 확인하여 세션의 만료를 확인 가능 
false이면 만료

 


▶ 실습2 - 로그인 화면 만들기

▷ Enumeration 만들기
jsp 파일 : EnumsExample.jsp

<%@page import="java.util.*"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
<%
	// Enumeration 인터페이스 연습
	// ArrayList : 가변 배열
	ArrayList<String> text = new ArrayList<String>();

	text.add("apple");
	text.add("banana");
	text.add("melon");
	text.add("watermelon");

	// 열거형 객체를 이용해서 자동반복구현
	// ArrayList객체의 내용을 자바 자료구조들들 중에서 이뉴머레이션 자료형으로 변환한다
	// Collections : 자바로 표현 가능한 알고리즘형(ADT) 모두
	 
	Enumeration<String> textEnums = 
				Collections.enumeration(text);
	
	while(textEnums.hasMoreElements()) {
		// 새로운 자료 화면에 출력
		out.println(textEnums.nextElement() + "<br />");
	}
%>    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

</body>
</html>

 사용자 로그인 화면
jsp 파일 : 
* login_form.jsp 

- 로그인 양식

- 현재 공부중이니 value는 넣어두어 실행화면 점검할때 타이핑 하지 않아도 자동 로그인 효과 주기

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>사용자 로그인 화면</title>
</head>
<body>
	<form action="loginDo.jsp" method="post" />
		아이디 : 
			<input type="text" name="id" value="abcde" size="10"><br />
		비밀번호 : 
			<input type="password" name="pw" value="12345" size="10"><br />
		<input type="submit" value="로그인" />	
	</form>

</body>
</html>


* loginDo.jsp

- 로그인 확인용
-> 컨트롤러

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	// 요청정보 추출
	String id = request.getParameter("id");
	String pw = request.getParameter("pw");
	
	
	// 로그인 여부 디비에서 질의하여 판정
	// 로그인 성공
	if (id.equals("abcde")&& 
		pw.equals("12345")) {
		session.setAttribute("id", id);
		// 로그인 성공이므로 회원제 페이지로 자동이동 
		response.sendRedirect("home.jsp");
	} else {
		// 로그인 실패
		response.sendRedirect("login_form.jsp");
	}
		
%>    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

</body>
</html>


* home.jsp

- 로그인 성공 화면
->Enumeration 활용

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.util.*" %>
<% 
	Enumeration enums = session.getAttributeNames();
	while(enums.hasMoreElements()) {
		String sName = enums.nextElement().toString();
		String sValue = (String)session.getAttribute(sName);
		
		if (sValue.equals("abcde")) {
			out.println(sValue + "님 안녕하세요<br />");
		}
	} 
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<a href="logout.jsp">로그아웃</a>
</body>
</html>


* logout.jsp

- 로그아웃

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.util.*" %>    
<%
	Enumeration enums = session.getAttributeNames();
	
	while(enums.hasMoreElements()) {
		String sName = enums.nextElement().toString();
		String sValue = (String)session.getAttribute(sName); // 오브젝트라서 강제 형변환
	
		if (sValue.equals("abcde")) {
			session.removeAttribute(sName);
		}
	}
	
%>    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	세션의 항목을 살펴보며 세션 항목 중 id가 삭제되었는지 확인<br />
	<a href="sessionTest.jsp"> 세션 테스트 </a>
</body>
</html>

* sessionTest.jsp

-> 로그아웃 하면 세션 항목 중 id가 삭제되었는지 확인

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.util.*" %>

<%
	// 모든 세션의 정보를 가져옴
	Enumeration enums = session.getAttributeNames();
	
	int sessionCount = 0;
	
	// 남아있는 세션을 확인함
	while(enums.hasMoreElements()) {
		sessionCount++;
		
		String sName = enums.nextElement().toString();
		String sValue = (String)session.getAttribute(sName);
		
		out.println("sName : " + sName + "<br />");
		out.println("sValue : " + sValue + "<br />");
	}
	// sessionCount가 없으면 정상 삭제된 것 
	if (sessionCount == 0) {
		out.println("해당 세션요소가 삭제 되었습니다.");
	}
	

%>    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

</body>
</html>


* 디버그
login_form에서 가동

톰캣에 프로젝트를 여러개 구동시키면 같은 이름은 충돌하여 찾지 못하는 현상(버그, 오류) 발생
-> 현재 프로젝트만 등록하고 기존의 데이터 clean으로 삭제 



* 자바 math 메소드
floor() : 인수로 전달받은 값을 작은 정수로 반환(버림), 바닥함수
ceil()  : 인수로 전달받은 값 중 가장 큰 정수로 반환(올림), 천장함수
round() : 소수점 첫번째 자리에서 반올림
abs() : 절대값으로 변환 
pow(a,b) : a^b, 제곱근
sqrt(a) : a의 제곱근