본문 바로가기

SpringBoot

SpringBoot(9) - 쿠키 예제(닉네임 출력 및 방문 횟수 카운트), Local Storage, Session Storage 예제(값 저장/읽기/삭제), Thymeleaf 예제, 추가 정리 사항

728x90
반응형

1) SpringBoot

   1-1) 쿠키 예제(닉네임 출력 및 방문 횟수 카운트)

   1-2) Local Storage, Session Storage 예제

      1-2-1) 값 저장/읽기/삭제

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

   1-3) Thymeleaf 예제

   1-4) 추가 정리 사항

 

 

 

 

 

1) SpringBoot

[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>
		<li> localStorage와 sessionStorage의 사용
			<ul>
				<li>
					<a href="local/save">값 저장</a>
				</li>
				<li>
					<a href="local/read">값 읽기</a>
				</li>
				<li>
					<a href="local/delete">값 삭제</a>
				</li>
			</ul>
		</li>
		<li> Thymeleaf 문법
			<ul>
				<li>
					<a href="th/thymeleaf1">타임리프 연습1</a>
				</li>
				<li>
					<a href="th/thymeleaf2">타임리프 연습2</a>
				</li>
			</ul>
		</li>
	</ol>
</body>
</html>

 

 

 

1-1) 쿠키 예제(닉네임 출력 및 방문 횟수 카운트)

(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 org.springframework.web.bind.annotation.RequestParam;

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.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로 포워딩해서 메시지 출력
		*/
		
		//숫자가 저장된 쿠키를 읽고 없으면 0으로 처리
		//카운트 1 증가
		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);
		
		//html로 포워딩
		return "exView/count";
	}
	
	// 교수님 version
	/**
	 * 첫 방문자의 닉네임을 입력받아 쿠키에 저장
	 */
	@GetMapping("count2")
	public String count2(
			@CookieValue(name="name", defaultValue="") String name,
			@CookieValue(name="count2", defaultValue="0") int count2,
			HttpServletResponse response,
			Model model
			) {
		// isEmpty() : 문자열의 길이가 0인 경우에, true를 리턴
		if (name == null || name.isEmpty()) {
			return "exView/inputName";
		}
		
		count2++;
		model.addAttribute("count2", count2);
		model.addAttribute("name", name);
		
		Cookie ck = new Cookie("count2", Integer.toString(count2));
		ck.setMaxAge(60 * 60 * 24 * 365);
		response.addCookie(ck);
		
		return "exView/count2";
	}
	
	/**
	 * 첫 방문자에게 닉네임 입력받기
	 */
	@GetMapping("inputName")
	public String inputName() {
		return "exView/inputName";
	}
	
	/**
	 * 닉네임을 쿠키에 저장
	 */
	@PostMapping("inputName")
	public String inputName(
			@RequestParam("name") String name,
			HttpServletResponse response
			) {
		Cookie ck = new Cookie("name", name);
		ck.setMaxAge(60 * 60 * 24 * 365);
		response.addCookie(ck);
		return "redirect:count2";
	}
}

 

 

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

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>count2.html</title>
</head>
<body>
	<h1>[ 방문 횟수 카운트 예제 2 ]</h1>
	<p>[[${name}]]님 환영합니다.</p>
	<p>[[${count2}]]번째 방문입니다.</p>
</body>
</html>

 

 

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

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>inputName.html</title>
</head>
<body>
	<h1>[ 첫 방문을 환영합니다. ]</h1>
	<form action="inputName" method="post">
		닉네임 입력
		<input type="text" name="name" required>
		<input type="submit" value="저장">
	</form>
	<p></p>
</body>
</html>

 

 

(4) 결과 화면

첫 접속 화면

 

 

"닉네임 설정 및 방문횟수 카운트" 문구 클릭 시 화면

 

 

"닉네임 입력" 후 "저장" 버튼 클릭 시 화면

 

 

 

"닉네임 설정 및 방문횟수 카운트" 문구 다시 클릭 시 화면

 

 

 

 

1-2) Local Storage, Session Storage 예제

1-2-1) 값 저장/읽기/삭제

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

package net.datasa.web2.controller;

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

import lombok.extern.slf4j.Slf4j;

@Controller
@RequestMapping("local")
@Slf4j
public class LocalController {
	// 값 저장
	@GetMapping("save")
	public String save() {
		return "localView/save";
	}
		
	// 값 읽기
	@GetMapping("read")
	public String read() {
		return "localView/read";
	}
		
	// 값 삭제
	@GetMapping("delete")
	public String delete() {
		return "localView/delete";
	}
}

 

 

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

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>값 저장</title>
<script>
	function save() {
		let localInputValue = document.getElementById("localInput").value;
		let sessionInputValue = document.getElementById("sessionInput").value;
		
		console.log(localInputValue, sessionInputValue);
		
		localStorage.setItem('code', localInputValue);
		sessionStorage.setItem('code', sessionInputValue);
	}
</script>
</head>
<body>
	<h1>localStorage와 sessionStorage에 저장</h1>
	<p>
		localStorage
		<input type="text" id="localInput">
	</p>
	<p>
		sessionStorage
		<input type="text" id="sessionInput">
	</p>
	<p>
		<input type="button" onclick="save()" value="저장">
	</p>
</body>
</html>

 

 

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

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>값 읽기</title>
<script>
	window.onload = function() {
		let localCode = localStorage.getItem("code");
		let sessionCode = sessionStorage.getItem("code");
		
		let div1 = document.getElementById("div1");
		let div2 = document.getElementById("div2");
		
		div1.innerHTML = localCode;
		div2.innerHTML = sessionCode;
	}
</script>
</head>
<body>
	<h1>값 읽기</h1>
	<div id="div1"></div>
	<div id="div2"></div>
</body>
</html>

 

 

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

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>값 삭제</title>
<!-- static/js에 있는 jquery 파일 불러오기 -->
<script src="/js/jquery-3.7.1.min.js"></script>
<script>
	$(document).ready(function() {
		localStorage.removeItem("code");
		sessionStorage.removeItem("code");
	});
</script>
</head>
<body>
	<h1>삭제되었습니다.</h1>
	<!-- 
			jquery 파일을 불러온다.
			페이지가 로드되면 바로 실행되는 코드 작성
			LocalStorage와 SessionStorage 양쪽의 이름이 "code"인 값을 삭제한다.
	 -->
</body>
</html>

 

 

(5) 결과 화면

첫 접속 화면

 

 

"값 저장" 문구 클릭 시 화면 : input box 입력 후 저장

 

 

 

"값 읽기" 문구 클릭 시 화면

 

 

"값 삭제" 문구 클릭 시 화면

 

 

"값 삭제" 후 "값 읽기" 문구 클릭 시 화면

 

 

 

1-3) Thymeleaf 예제

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

package net.datasa.web2.controller;

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

import lombok.extern.slf4j.Slf4j;
import net.datasa.web2.domain.Person;

@Controller
@RequestMapping("th")
@Slf4j
public class ThymeleafController {
	@GetMapping("thymeleaf1")
	public String thymeleaf1(Model model) {
		String str = "문자열";
		int num = 100;
		Person p = new Person("홍길동", 20, "010-1111-2222");
		String tag = "<marquee>HTML 태그가 포함된 문자열</marquee>";
		String url = "https://google.com";
		
		model.addAttribute("str", str);
		model.addAttribute("num", num);
		model.addAttribute("person", p);
		model.addAttribute("tag", tag);
		model.addAttribute("url", url);
		
		return "thView/thymeleaf1";
	}
}

 

 

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

<!DOCTYPE html>
<html xmlns:th="http://thymeleaf.org"
	xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head>
<meta charset="UTF-8">
<title>thymeleaf1</title>
</head>
<body>
	<h1>[ Thymeleaf 문법1 ]</h1>
	
	<h3>값 출력</h3>
	<p>[[${str}]]</p>
	<!-- 바로 위의 코드와 결과는 동일하지만 아래 방식 사용을 더 추천함 -->
	<p th:text="${str}">임시문자열</p>
	<p th:text="${num}">000</p>
	<p>이름 : <span th:text=${person.name}>홍길동</span></p>
	<p th:text="${tag}"></p>
	<p th:utext="${tag}"></p>
	
	<h3>주석</h3>
	<!-- HTML 주석 -->
	<script>
		// Javascript 주석
		/* Javascript 주석 */
	</script>
	<!--/* 타임리프 주석 */-->
	
	<h3>연산자</h3>
	<p th:text="${num + 1}">000</p>
	
	<p>비교 연산자 : ==, !=, <, >, <=, >=</p>
	<p>비교 연산자 : eq, ne, lt, gt, le, ge</p>
	<p th:text="${num > 10}"></p>
	<p th:text="${num gt 10}"></p>
	
	<p>논리 연산자 : and, or, not</p>
	<p th:text="${num gt 10 and num lt 50}"></p>
	<!-- num이 3의 배수이거나 5의 배수이면 true -->
	<p th:text="${num % 3 eq 0 or num % 5 eq 0}"></p>
	<p></p>
	<p></p>
</body>
</html>

 

 

(3) 결과 화면

첫 접속 화면

 

 

"타임리프 연습1" 문구 클릭 시 화면

 

 

 

1-4) 추가 정리 사항

쿠키 : 서버 측에서 자바 코드로 다루는 것

local storage : 자바스크립트 전용으로 브라우저에 저장됨

local storage : 쿠키처럼 오래감(컴퓨터를 끄고 내일 켜도 내용이 남아 있음)

session storage : 쿠키처럼 오래가지 않음(컴퓨터를 끄고 다시 켜면 내용이 사라짐)

 

static 폴더에 저장한 것은 root에 저장한 것과 마찬가지이므로

경로 설정 시 root 주소 기준 바로 아래의 static 폴더 안에 있는

폴더나 파일들에 바로 접근 가능함

 

“person.name”은 getName() 메서드를 호출하는 것이 포함되어

마치 해당 메서드를 생략하고 바로 실행해준 것처럼 보이는 코드이다!

 

Thymeleaf : 템플릿 엔진의 일종으로 서버에서 자바 코드를 만들어주는 것을 의미함