본문 바로가기

SpringBoot

SpringBoot(8) - Cookie 예제(쿠키 저장/읽기/삭제, 방문 횟수 카운트), 추가 정리 사항

728x90
반응형

1) SpringBoot

   1-1) Cookie 예제

      1-1-1) 쿠키 저장/읽기/삭제

      1-1-2) 방문 횟수 카운트

   1-2) 추가 정리사항

 

 

 

 

 

1) SpringBoot

1-1) Cookie 예제

1-1-1) 쿠키 저장/읽기/삭제

(1) [src/main/resources] - [templates] 안에 home.html 파일 생성 후 아래와 같이 작성

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>web2</title>
</head>
<body>
	<h1>[ web2 ]</h1>
	<ol>
		<li>Lombok & Logger 사용
			<ul>
				<li>
					<a href="lom/lombok">Lombok 사용하기</a>
				</li>
				<li>
					<a href="lom/logger">Logger 사용하기</a>
				</li>
				<!--
				여기는 메인화면입니다. 위의 l은 소문자 L입니다.
				글꼴 때문에 꼬부라져 보이는 것입니다.
				-->
			</ul>
		</li>
		<li>서버로 데이터 보내기/받기
			<ul>
				<li>
					<a href="param/view1">GET 방식으로 보내기</a>
				</li>
				<li>
					<a href="param/view2">POST 방식으로 보내기</a>
				</li>
				<li>
					<a href="param/model">Model 객체 이용하기</a>
				</li>
			</ul>
		</li>
		<li> 예제
			<ul>
				<li>
					<a href="ex/calc1">계산기</a>
				</li>
				<li>
					<a href="ex/calc2">계산기2</a>
				</li>
				<li>
					<a href="ex/count">방문횟수 카운트</a>
				</li>
				<li>
					<a href="ex/count2">닉네임 설정 및 방문횟수 카운트</a>
				</li>
			</ul>
		</li>
		<li> 세션 사용
			<ul>
				<li>
					<a href="ss/session1">세션에 값 저장</a>
				</li>
				<li>
					<a href="ss/session2">세션에서 값 읽기</a>
				</li>
				<li>
					<a href="ss/session3">세션의 값 삭제</a>
				</li>
				
				<li>
					<a href="ss/login">로그인</a>
				</li>
				<li>
					<a href="ss/logout">로그아웃</a>
				</li>
				<li>
					<a href="ss/loginTest">로그인해야 들어갈 수 있는 메뉴</a>
				</li>
			</ul>
		</li>
		<li> 쿠키 사용
			<ul>
				<li>
					<a href="ck/cookie1">쿠키 저장</a>
				</li>
				<li>
					<a href="ck/cookie2">쿠키 읽기</a>
				</li>
				<li>
					<a href="ck/cookie3">쿠키 삭제</a>
				</li>
			</ul>
		</li>
	</ol>
</body>
</html>

 

 

(2) [src/main/java] - [net.datasa.web2.controller] 안에 CookieController.java 파일 생성 후 아래와 같이 작성

package net.datasa.web2.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;

@Controller
@RequestMapping("ck")
@Slf4j
public class CookieController {
		// 쿠키 저장
		@GetMapping("cookie1")
		public String cookie1(
				HttpServletRequest request,
				HttpServletResponse response
				) {
			// 같은 와이파이 사용. cmd >> ipconfig >> IP 주소 확인하고 접속
			log.debug(request.getRemoteAddr());
			
			// 쿠키 객체 생성
			Cookie a = new Cookie("str", "abcde");
			Cookie b = new Cookie("num", "123");
			
			// 쿠키의 유지 시간(현재는 아래와 같이 3개월로 지정함)
			a.setMaxAge(60 * 60 * 24 * 100); // setMaxAge() : 초 단위로 쿠키의 수명을 설정할 수 있음
			b.setMaxAge(60 * 60 * 24 * 100);
			
			// 쿠키의 경로 설정: Root 경로를 포함해 그 하위 경로에서 전부 사용할 수 있다는 의미이다!
			a.setPath("/");
			b.setPath("/");
			
			// 쿠키 내보내기
			response.addCookie(a);
			response.addCookie(b);
			
			log.debug("쿠키 저장됨");
			return "redirect:/";
		}
		
		// 쿠키 읽기
		@GetMapping("cookie2")
		public String cookie2(
				@CookieValue(name="num", defaultValue="0") int n,
				@CookieValue(name="str", defaultValue="없음") String s
				) {
			log.debug("num쿠키: {}", n);
			log.debug("str쿠키: {}", s);
			
			return "redirect:/";
		}
		
		// 쿠키 삭제
		@GetMapping("cookie3")
		public String cookie3(HttpServletResponse response) {
			// 같은 이름으로 쿠키 생성(값은 아무거나. 또는 null)
			// 유지시간을 0초로
			// 쿠키를 클라이언트(Client)로 보내서 저장
			
			Cookie a = new Cookie("str", null);
			Cookie b = new Cookie("num", "");
			
			a.setMaxAge(0);
			b.setMaxAge(0);
			
			a.setPath("/");
			b.setPath("/");
			
			response.addCookie(a);
			response.addCookie(b);
			
			log.debug("쿠키 삭제됨");
			return "redirect:/";
		}
}

 

 

(3)결과 화면 

첫 접속 화면

 

 

"쿠키 저장" 문구 클릭 시 화면

 

 

"쿠키 읽기" 문구 클릭 시 화면

 

 

"쿠키 삭제" 문구 클릭 시 화면

 

 

다시 "쿠키 읽기" 문구 클릭 시 화면

 

 

 

1-1-2) 방문 횟수 카운트

(1) [src/main/java] - [net.datasa.web2.controller] 안에 ExController.java 파일 생성 후 아래와 같이 작성

package net.datasa.web2.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import net.datasa.web2.domain.CalcDTO;
import net.datasa.web2.domain.CountDTO;
import net.datasa.web2.service.CalcService;

/**
 * 연습문제
 * 클래스에 대한 설명. 작성자. 작성일. 수정내역.
 * 연습문제 구현을 위해 필요한 클래스. 황상범. 2024/07/01. 각 메서드 추가.
 */
@Controller
@RequestMapping("ex")
@Slf4j
public class ExController {
	
	/**
	 * 계산기능 서비스
	 */
	// @Autowired : 데이터 타입을 보고 이 타입에 해당하는 객체(미리 정의한 클래스의 객체를 의미함)를 여기(Controller)로 불러와줌!
	@Autowired
	CalcService calcService;
	
	
	/**
 	[연습문제 1]
 	1. ex/calc1 경로로 요청
 	2. 입력 폼을 출력(입력란 2개, Select 1개, submit 버튼 1개 포함)
 	3. 숫자 2개를 입력하고 연산자를 고르고 submit 버튼 클릭
 	4. 숫자가 아닌 값을 입력하면 JavaScript로 확인하고 오류 메시지 출력
 	5. 숫자 2개를 정상적으로 입력하면 서버로 전송
 	6. Controller에서 값을 전달받아 계산
 	7. 계산한 결과를 Model에 저장하고 View로 이동
 	8. 화면에 계산한 결과 출력(새로운 Controller 정의, HTML 파일 2개 필요)
	*/
	
	/**
		계산기1 폼 화면으로 이동
	*/
	@GetMapping("calc1")
	public String calc1() {
		return "exView/calcForm1";
	}
	
	/**
	 * 
	 * @param dto : CalcDTO로부터 불러온 객체
	 * @param model : HTML로 값을 전달할 객체
	 * @return : 템플릿 HTML 페이지 경로
	 */
	@PostMapping("calc1")
	public String calcOutput1(
			@ModelAttribute CalcDTO dto,
			// @RequestParam("num1") int n1,
			Model model
			) {
		log.debug("객체값: {}", dto);
		
		int res = 0, n1, n2;
		
		try {
			switch (dto.getOp()) {
				case "+":
					res = dto.getNum1() + dto.getNum2();
					break;
				case "-":
					res = dto.getNum1() - dto.getNum2();
					break;
				case "*":
					res = dto.getNum1() * dto.getNum2();
					break;
				case "/":
					res = dto.getNum1() / dto.getNum2();
					break;
				default:
					throw new Exception("연산자 오류");
			}
		
			model.addAttribute("calc", dto);
			model.addAttribute("res", res);
		}
		catch (Exception e) {
			// e.printStackTrace(); : "Console"에 출력 메시지를 띄어주는 역할을 함
			e.printStackTrace();
			return "/exView/calcForm1"; // 예외 발생 시 계산 form으로 다시 이동
		}
		
		return "exView/calcOutput1";
	}
	
	
	/**
	계산기2 폼 화면으로 이동
	 */
	@GetMapping("calc2")
	public String calc2() {
		return "exView/calcForm2";
	}

	/**
	 * 
	 * @param dto : CalcDTO로부터 불러온 객체
	 * @param model : HTML로 값을 전달할 객체
	 * @return : 템플릿 HTML 페이지 경로
	 */
	@PostMapping("calc2")
	public String calcOutput2(
			@ModelAttribute CalcDTO dto,
			Model model
			) {
		
		// 서비스(Service)의 메서드 호출
		try {
			int res = calcService.calc(dto);
			model.addAttribute("calc", dto);
			model.addAttribute("res2", res);
			return "exView/calcOutput2";
		} catch (Exception e) {
			e.printStackTrace();
			return "exView/calcForm2"; // 예외 발생 시 계산폼으로 다시 이동
		}
	}
	
	/**
	 * 쿠키를 이용하여 방문 횟수 카운트
	 * @param count : 쿠키에서 읽은 이전 방문 횟수
	 * @param response : 응답 정보 객체
	 * @param model : HTML로 값을 전달할 객체
	 * @return : 템플릿 HTML 페이지 경로
	 */
	@GetMapping("count")
	public String count(
			@CookieValue(name="count", defaultValue="0") int count,
			HttpServletResponse response,
			Model model
			) {
		/*
			위의 링크를 클릭하면 Controller의 메서드 실행
			쿠키를 읽어서 없으면 숫자를 0으로 처리
			방문횟수를 1증가
			"첫 방문 환영합니다" 또는 "X번째 방문입니다" 메시지를 모델에 저장
			쿠키도 저장
			HTML로 포워딩해서 메시지 출력
		*/
		count++;
		
		if (count == 1) {
			model.addAttribute("message", "첫 방문 환영합니다");
		} else {
			model.addAttribute("message", count + "번째 방문입니다");
		}
		
		Cookie c = new Cookie("count", Integer.toString(count));
		
		c.setMaxAge(60 * 60 * 24 * 365);

		response.addCookie(c);
		
		return "exView/count";
	}
	
	@GetMapping("count2")
	public String count2(
			@ModelAttribute CountDTO dto,
			@CookieValue(name="nick", defaultValue="dto.getNick()") String nick,
			@CookieValue(name="count2", defaultValue="0") int count2,
			HttpServletResponse response,
			Model model
			) {
		if (count2 == 0) {
			return "exView/nickCountForm";
		} else {
			count2++;
			
			if (count2 == 1) {
				model.addAttribute("nickName", nick + "님,");
				model.addAttribute("message2", "첫 방문 환영합니다");
			} else {
				model.addAttribute("nickName", nick + "님,");
				model.addAttribute("message2", count2 + "번째 방문입니다");
			}
			
			Cookie nickName = new Cookie("nick", nick);
			Cookie c2 = new Cookie("count2", Integer.toString(count2));
			
			nickName.setMaxAge(60 * 60 * 24 * 365);
			c2.setMaxAge(60 * 60 * 24 * 365);

			response.addCookie(nickName);
			response.addCookie(c2);
			
			return "exView/count2";
		}
 	}
	
	@PostMapping("count2")
	public String nickNameForm(
			@ModelAttribute CountDTO dto,
			@CookieValue(name="nick", defaultValue="") String nick,
			@CookieValue(name="count2", defaultValue="0") int count2,
			HttpServletResponse response,
			Model model
			) {
		count2++;
		nick = dto.getNick();
		
		if (count2 == 1) {
			model.addAttribute("nickName", nick + "님,");
			model.addAttribute("message2", "첫 방문 환영합니다");
		} else {
			model.addAttribute("nickName", nick + "님,");
			model.addAttribute("message2", count2 + "번째 방문입니다");
		}
		
		Cookie nickName = new Cookie("nick", nick);
		Cookie c2 = new Cookie("count2", Integer.toString(count2));
		
		nickName.setMaxAge(60 * 60 * 24 * 365);
		c2.setMaxAge(60 * 60 * 24 * 365);

		response.addCookie(nickName);
		response.addCookie(c2);
		
		return "exView/count2";
	}
}

 

 

(2) [src/main/resources] - [templates.exView] 안에 count.html 파일 생성 후 아래와 같이 작성

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>방문횟수 카운트</title>
</head>
<body>
	<h1>방문횟수 카운트</h1>
	<h3>[[${message}]]</h3>
</body>
</html>

 

 

(3) 결과 화면

첫 접속 화면

 

 

"방문횟수 카운트" 문구 클릭 시 화면

 

 

다시 "방문횟수 카운트" 문구 클릭 후 접속 시 화면

 

 

 

 

 

1-2) 추가 정리사항

Session은 서버 측 메모리에 저장되고, 사용자마다 각각 따로 만들어진다.

“Session”은 사용자 측(front)에서 원천적으로 접근이 불가능하고, 그 내용을 확인할 수도 없다.

또한 “Session”은 사용 중인 브라우저를 한 번 껐다 켜면 “Session”의 내용이 사라진다(초기화된다).

쿠키(Cookie)는 사용자의 Web Browser에 쌓인다!

 

“/**” 입력 후 Enter 키 누르면 아래와 같이 자동 완성된다!

/**
	 * 쿠키를 이용하여 방문 횟수 카운트
	 * @param count : 쿠키에서 읽은 이전 방문 횟수
	 * @param response : 응답 정보 객체
	 * @param model : HTML로 값을 전달할 객체
	 * @return : 템플릿 HTML 페이지 경로
*/