멀티캠퍼스 백엔드 과정 32일차[7월 17일] -쿠키, 애플리케이션, 페이지

GoldenDusk·2023년 7월 18일
0

기본개념

1. 웹 환경 구축

  • 톰캣(웹 서버 + Servlet 컨테이너) : WAS
  • IDE : 통합 개발 환경 - 이클립스 : J2EE
  • 웹 브라우저(HTTP 서비스)
  • DBMS(ORACLE, MySQl 선택)
  • DBMS(ORACLE, MYSQL 선택)
  • Junit, lombok

2. HTTP란 HTTP의 동작원리

  • POST, GET

3. JSP(Java Server Page) _ jspServer()

  • 내장 객체
내장 객체타입설명
Requestjavax.servlet.http. HttpServletRequest클라이언트의 요청 정보를 저장
Responsejavax.servlet.http. HttpServletResponse클라이언트의 요청에 대 응답 정보를 저장
Outjavax.servlet.jsp.JspWriterJSP 페이지에 출력 내용을 담는 출력 스트림
Sessionjavax.servlet.http.HttpSession웹 브라우저 정보를 유지하기 위한 세션 정보를 저장
Applicationjavax.servlet.ServletContext웹 애플리케이션 관련 컨텍스트 정보를 저장
pageContextjavax.servlet.jsp.PageContextJSP 페이지에 대한 정보를 저장
Pagejava.lang.ObjectJSP 페이지를 구현한 자바 클래스의 스턴스
Configjavax.servlet.ServletConfigJSP 페이지에 대 설정 정보를 저장
exceptionjava.lang.Throwable예외가 발생한 경우에 사용

4. 페이지를 이동하는 방법 2가지

  • request : forward(request, reponses)
  • response : sendRedirect()

5.. 내장 객체 중 4가지

  • request, response, page, session
  • 저장공간을 가지고 있는 서버 객체
  • 각 영역에 저장된 데이터가 공유되는 범위가 서로 다르다.
  • 내장 객체의 유효 기간(공유되는 범위)
  • 4가지 객체에 데이터를 저장하고 공유하는 방법

6. 자바웹의 동작원리

  • 웹에서는 페이지(page)들이 모여서 하나의 요청(request)를 처리하며, 요청(request)가 모여 하나의 세션(session) 구성
  • 다시 세션들이 모여 하나의 웹 어플리케이션(application)을 이룬다.
  • page ⇒ request ⇒ session ⇒ application
  • 브라우저 1개 당 세션 1개

내장 객체의 영역

1. 내장 객체의 영역이란?

내장 객체의 영역은 각 개체가 저장되는 메모리의 유효기간

  • page 영역 : 동일한 페이지에서만 공유됩니다. 페이지를 벗어나면 소멸
  • request 영역 : 하나의 요청에 의해 호출된 페이지와 포워드(요청 전달)된 페이지까지 공유
  • session 영역 : 클라이언트가 처음 접속한 후 웹 브라우저를 닫을 때까지 공유
  • application 영역 : 1번 저장되면 웹 애플리케이션이 종료될 때까지 유지
  • page ⇒ request ⇒ session ⇒ application : 메모리의 유효기간 이해하자!
  • 자바 프로그램 코드 - 지역 변수(메소드)

2. 데이터 전송 객체(DTO) 준비

  • 데이터 전송 객체(Data Transfer Object, DTO)
    • 데이터를 저장하거나 전송하는 데 쓰이는 객체로, 다른 로직 없이 순수하게 데이터만을 담고
      있으며, 값 객체(Value Object)라고도 함
    • 자바빈즈(Java Beans) 규약에 따라 작성
    1. 자바빈즈는 기본(default) 패키지 이외의 패키지에 속해야 함
    2. 멤버 변수(속성)의 접근 지정자는 private으로 선언
    3. 기본 생성자가 있어야 함
    4. 멤버 변수에 접근할 수 있는 게터(getter)/세터(setter) 메서드가 필요
    5. 게터/세터 메서드의 접근 지정자는 public으로 선언
  • Person 이름의 DTO 작성
    • 프로젝트 탐색기 ① Java Resources → ② src에서 마우스 우클릭 → ③ [New] →④ [Class]를
      클릭
    • ① 패키지명을 “common”, ② 클래스명을 “Person”으로 입력한 후 ③ [Finish] 버튼을 클릭Person 클래스가 생성

  • String 타입의 이름(name)과 int 타입의 나이(age) 멤버 변수를 private으로 선언

  • 기본 생성자 정의

  • String 클래스 [인스턴스해서 재사용이 가능하기 때문에 쓰는 것]

    package common;
    
    public class Person {
    
    		private String name;
    		private int age;
    		
    		public Person() {}
    		
    		public Person(String name, int age) {
    			super();
    			this.name=name;
    			this.age=age;
    		}
    		
    		public void setName(String name) {
    			this.name=name; //이름 저장
    		}
    		
    		public String getName() {
    			return name;
    		}
    
    		public int getAge() {
    			return age;
    		}
    
    		public void setAge(int age) {
    			this.age = age;
    		}
    		
    		// Person 객체의 빈(Bean) 생성 => DTO(Data Transfer Object)
    		
    		
    		
    }

3. page 영역

  • 동일한 페이지에서만 공유, 페이지를 벗어나면 소멸

- pageContentMain

<%@ page import = "common.Person" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<%
	// 데이터 저장
	pageContext.setAttribute("pageInteger", 10); // 10은 Object 타입으로 업캐스팅
	pageContext.setAttribute("pageString", "페이지 영역 문자열");
	pageContext.setAttribute("pagePerson", new Person("홍길동", 20));
%>
<html>
<head>
<meta charset="UTF-8">
<title>Page Context 영역</title>
</head>
<body>
	<h2>page에 저장된 속성값(데이터) 읽기</h2>
	<% 
	Object pInteger = pageContext.getAttribute("pageInteger");
	Integer pInteger1 = (Integer)(pageContext.getAttribute("pageInteger"));
	//String pStr = pageContext.getAttribute("pageString").toString();
	Person pPerson = (Person)(pageContext.getAttribute("pagePerson"));
	%>
	<ul>
		<li><%= pInteger %></li>
		<li></li>
		<li><%= pPerson.getName() %>, <%= pPerson.getAge() %></li>
	</ul>
	<h2>include 된 파일에서 page영역 읽어오기</h2>
	<%@ include file = "PageInclude.jsp" %>
	
	<a href="PageLocation.jsp">PageLocation.jsp 바로가기</a>
</body>
</html>

- pageInclude

<%@ page import = "common.Person" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<%
  Integer pInteger2 =(Integer) (pageContext.getAttribute("pageInteger"));
  //String  pStr2 =   pageContext.getAttribute("pageString").toString();
  Person pPerson2 = (Person)(pageContext.getAttribute("pagePerson"));
%>
<meta charset="UTF-8">
<title>PageInclude.jsp</title>
</head>
<body>
    <ul>
       <li><%= pInteger2 %> </li>
       <li> </li>
       <li><%= pPerson2.getName()%> , <%= pPerson2.getAge() %> </li>
    </ul>

</body>
</html>

- PageLocation.jsp

<%@ page import = "common.Person" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<%
  Integer pInteger =(Integer) (pageContext.getAttribute("pageInteger"));
  //String  pStr =   pageContext.getAttribute("pageString").toString();
  Person pPerson = (Person)(pageContext.getAttribute("pagePerson"));
%>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

       Integer 객체: <%= (pInteger == null)? "값없음" :(Integer)pInteger %> 
       String 객체: <%-- <%= (pStr == null)? "값없음" : pStr.toString()   %> --%>
       Person 객체: <%= (pPerson == null)? "값없음" : ((Person)pPerson).getName() %>  
    

</body>
</html>

4. request 영역

  • 값을 유지한 채 보내줘 의 의미
<% request.getRequestDispatcher("RequestForward.jsp").forward(request, response); %>
  • 클라이언트가 요청할 때마다 새로운 request가 생성되고 같은 요청을 처리하는데 사용되는 모든 jsp가 공유된다.

  • 하나의 요청에 의해 호출된 페이지와 포워드(요청 전달)된 페이지까지 공유. 새로운 페이지를요청(페이지 이동)하면 소멸

  • Main

<%@ page import = "common.Person" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<%
	request.setAttribute("requestString", "requst영역 문자열입니다.");
	request.setAttribute("requestPerson", new Person("김나나", 25));
%>

<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%= request.getAttribute("requestString") %>
<%
	//복원
	Person reqPerson =(Person)request.getAttribute("requestPerson");
	
%>
<%= reqPerson.getName() %>
<%= reqPerson.getAge() %>

<h2>포워드된 페이지에서 request영역에 저장된 속성값 읽기</h2>
<% request.getRequestDispatcher("RequestForward.jsp").forward(request, response); %>
</body>
</html>

- RequestForward.jsp

<%@ page import = "common.Person" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>

<head>
<meta charset="UTF-8">
<title>Request 영역</title>
</head>
<body>
<%
	request.setCharacterEncoding("UTF-8");
	Person forPerson = (Person)request.getAttribute("requestPerson");
	String str1 = request.getAttribute("requestString").toString();
%>

<h2>포워드된 페이지에서 request영역에 저장된 속성값 읽기</h2>
<%= forPerson.getName() %>
<%= forPerson.getAge() %>
<%= str1%></body> 
</html>

4. session 영역

세션 영역

  • 클라이언트가 서버에 접속해 있는 상태 혹은 단위, 주로 회원 인증 후 로그인 상태를 유지하는 처리에 사용
  • 여러 개의 request가 모여 세션을 이룬다.
  • 클라이언트가 처음 접속한 후 웹 브라우저를 닫을 때까지 공유. 포워드나 페이지 이동 시에도 영역은 소멸되지 않음
  • sessionMain
<%@page import="java.util.ArrayList" %> 
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<%
	ArrayList<String> lists = new ArrayList<String>();
	lists.add("리스트");
	lists.add("컬렉션");
	session.setAttribute("lists", lists);
	session.removeAttribute("lists");
%>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2>페이지 이동 후 session 영역의 속성 읽기</h2>
<a href="sessionLocation.jsp"> sessionLocation.jsp 이동</a>
</body>
</html>

- sessionLocation.

<%@ page import = "java.util.ArrayList" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>session 영역 읽기</title>
</head>
<body>
<%
	ArrayList<String> lists = (ArrayList<String>)session.getAttribute("lists");
	for(String str:lists)
		out.println(str+"<br/>");
%>
</body>
</html>

5. application

application

  • 웹 어플리케이션 webstudy는 단 하나의 application 객체만 생성
  • 클라이언트가 요청하는 모든 페이지가 application 객체를 공유
  • application 객체는 서버 시작 시 한 번 생성…유지.. 서버 종료 시 소멸되는 객체
  • 웹 브라우저를 종료하더라도 새롭게 접속해도 삭제되지 않는다.
  • 한 번 저장되면 웹 애플리케이션이 종료될 때까지 유지. 즉, 서버가 셧다운되지 않는다면 언제까지든 공유되는 영역
  • 어플리케이션에 저장하면 어디서든 꺼내쓸 수 있다.

- applicationMain.jsp

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

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>application 영역</title>
</head>
<body>
<!-- 자료 저장이기 때문에 내용이 보이지는 않음 -->
<%
	Map<String, Person> maps = new HashMap<String, Person>();
	maps.put("act1", new Person("한수지", 20));
	maps.put("act2", new Person("김진영", 25));
	maps.put("act3", new Person("이효진", 25));
	application.setAttribute("acts", maps);
	
%>

application영역의 배우들 자료 저장

</body>
</html>
  • ResponseWelcome.jsp
<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %>
<%@ page import="common.Person" %>
<%@ page import="java.util.Set" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
로그인 성공!
<% 
	Map<String, Person> acts = (Map<String, Person>)application.getAttribute("acts");
	Set<String> keys = acts.keySet();
	for(String key : keys){
		Person p = (Person)acts.get(key);
		out.print(String.format("이름:%s", "나이:%d<br/>", p.getName(), p.getAge()));
	}
%>
</body>
</html>
  • 내장 객체 영역별 수명 주기

알아두기!

쿠키(Cookie)

쿠키란?

쿠키

  • 쿠키(Cookie)는 클라이언트의 상태 정보를 유지하기 위한 기술
  • 상태 정보를 클라이언트(주로 웹 브라우저)에 키와 값 형태로 저장했다가 다음 요청 시
    저장된 쿠키를 함께 전송
  • 웹 서버는 브라우저가 전송한 쿠키로부터 필요 데이터를 읽어 들임
  • 쿠키로 저장한 수 있는 최대 용량은 대략 1.2MB. 모든 브라우저가 표준을 그대로 따르지는 않으며, 대부분 이보다 적은 수만 지원

기본 동작 확인

클라이언트는 서버에 처음 방문시 요청을 한다. 그 후 서버는 응답을 해서 클라이언트로 쿠키를 전송하고 클라이언트는 쿠키를 저장하고 클라이언트는 재방문과동시에 쿠키 전송하며 요청함 서버는 쿠키를 읽어 작업 수행

속성과 API

  • 쿠키를 구성하는 속성
    • 이름(name): 쿠키를 구별하는 이름
    • 값(value): 쿠키에 저장한 실제 데이터
    • 도메인(domain): 쿠키를 적용한 도메인
    • 경로(path): 쿠키를 적용한 경로
    • 유지 기간(max age): 쿠키를 유지한 기간
  • 설정 메서드
    • void setValue(String value): 쿠키의 값을 설정
    • void setDomain(String domain): 쿠키에 적용할 도메인을 설정
    • void setPath(String path): 쿠키가 적용될 경로를 지정
    • void setMaxAge(int expire_seconds): 쿠키가 유지될 기간을 초 단위로 설정
  • 쿠키의 이름은 생성자를 통해 설정
    • new Cookie(String name, String value): 이름과 값을 받아 새로운 쿠키를 생성
  • 쿠키 정보를 읽는 메서드
    • String getName( ): 쿠키의 이름을 반환
    • String getValue( ): 쿠키의 값을 반환
    • String getDomain( ): 쿠키가 적용되는 도메인을 반환
    • String getPath( ): 쿠키의 적용 경로를 반환. 단, setPath( )로 설정한 적이 없다면 null을 반환
    • int getMaxAge( ): 쿠키의 유지 기간을 반환. 단, setMaxAge( )로 설정한 적이 없다면 -1을 반

실습

  • 첫 방문 시[브라우저를 달리하면 다시 첫 방문 페이지 같은 브라우저이어야 뜸]

  • 두 번째 방문 시

- Main코드

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>쿠키</title>
</head>
<body>
<h2>1. 쿠키 설정</h2>
<%
Cookie 	cookie = new Cookie("myCookie","JMT"); // 쿠키 생성
cookie.setPath(request.getContextPath()); // 경로설정
cookie.setMaxAge(180);   //쿠키의 유지 기간 예)초 단위이므로 60초 3분 설정
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>

팝업창 실습

  • main
<%@ 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.getName();
			if(cookieName.equals("PopupClose")){
				popupMode = "off";
			}
		}
	}
	
	
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>쿠키를 이용한 팝업 관리 ver1.0</title>
<style> <!--css로 레이어 팝업창의 위치 결정 -->
    div#popup {
        position: absolute; top:100px; left:50px; color:yellow;  
        width:270px; height:100px; background-color:gray;
    }
    div#popup>div {
        position: relative; background-color:#ffffff; top:0px;
        border:1px solid gray; padding:10px; color:black;
    }
</style>
<script scr="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
// $ 달러 기호를 이용한 템플릿 스트링 표기 방법
	$(function()){ //자바스크립트 정의하겠습니다.
		$('#closeBtn').click(function(){ //닫기 버튼(id=closeBtn)을 누르면 파업창(id=popup)을 숨김처림
			$('#popup').hide();
			let chkVal = $("input:checkbox[id=inactiveToday]:checked").val();
			
			//jQuery의 ajax()함수로 데이터 비동기 처리
			$.ajax({
				url : './PopupCookie_p.jsp', //결과값을 보내라
				type : 'get', //'get' or 'post' HTTP메소드 선텍
				data : {inactiveToday : chkVal}, //서버로 보낼 데이터
				datatype : "text", //서버로 보낼 응답데이터 타입
				success : function(resData){ //요청 성공시 실행할 콜백함수
					if(resData != '') location.reload(); //다시 불어들여라
				}
				
			});
			
		});
	});
</script>

</head>
<body>
<%
	out.print("현재 팝업창은 "+popupMode+"상태입니다.<br/>");
	if(popupMode.equals("on")){ //off상태일 때는 모이지 않게 함
%>
<h2>팝업 메인 페이지(ver1.0)</h2>
<div id="popup">
<h2 align="center">공지사항 팝업입니다.</h2>
<div align="right">
	<from name="popForm">
	<input type="checkbox" id="inactiveToday" value="1"/>
	하루동안 열지 않음
	<input type="button" value="닫기" id="closeBtn">
	</form>
</div>
<% }%>
</div>
</body>
</html>
  • PopupCookie_p
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
String chkVal = request.getParameter("inactiveToday");

if(chkVal !=null && chkVal.equals("1")){
	Cookie cookie = new Cookie("PopupClose","off"); //쿠키 생성
	cookie.setPath(request.getContextPath()); // 쿠키 경로 설정
	cookie.setMaxAge(60); //쿠키 유지기간 설정 1분
	response.addCookie(cookie); //쿠키를 응답객체(헤더) 추가
}
%>

로그인 아이디 저장

클래스 만들기

  • JSFunctionjava
**package utils;
//자바스크립트의 메세지 알림창 띄우기, 앞으로 가기, 뒤로가기 기능
import javax.servlet.jsp.JspWriter;

public class JSFunction {
	//메세지 알림창을 띄운 후 지정한 url로 이동
	public static void alertLocation(String msg, String url, JspWriter out) {
		try {
			String script =""
									+"<script>"
									+"alter('"+msg+"');"
									+ "location.href='"+url+"'; " 
									+"</script>";
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

// 이전 페이지 이동
public static void alterBack(String msg, JspWriter out) {
	try {
		String script =""
								+"<script>"
								+"alter('"+msg+"');"
								+ "history.back()'; " //뒤로 가기 기능
								+"</script>";
	} catch (Exception e) {
		e.printStackTrace();
	}
}**
  • CookieManager.java
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 res, String cName, String cValue, int cTime) {
		Cookie cookie = new Cookie(cName, cValue);
		cookie.setPath("/");
		cookie.setMaxAge(cTime);
		res.addCookie(cookie);
	}
	
	//쿠키의 이름으로 쿠키의 값을 찾아 반환하는 기능 구현
	public static String readCookie(HttpServletRequest req, String cName) {
		String cookieValue =""; //반환값 
		Cookie[] cookies = req.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 res, String cName) {
		makeCookie(res, cName,"", 0);
	}
	}

회고

다시 월요일이다.. 주말에 슬랙 자료 같이 공유해서 따봉 받았다. 남과 같이 공유하면서 소통하는 게 좋다. 그래서 개발이 더 좋은 걸 수도

profile
내 지식을 기록하여, 다른 사람들과 공유하여 함께 발전하는 사람이 되고 싶다. 참고로 워드프레스는 아직 수정중

1개의 댓글

comment-user-thumbnail
2023년 7월 19일

잘 봤습니다. 좋은 글 감사합니다.

답글 달기