쿠키를 이용한 상태정보 유지하기

2020-07-29

해당 Post는 예제를 통해 쿠키에 대한 사용방법에 대해서 정리한 파일입니다.


실습

guestbook 예제를 이용해 실습을 합니다.

guestbook에서 list를 요청했을 때 쿠키를 이용해서 일단은 이 클라이언트가 처음 방문한 건지 두 번째 방문한 건지 몇 번째 방문한 건지 그것들을 기억하고 있다가 보여주는 예제입니다.

package kr.or.connect.guestbook.controller;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
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.RequestParam;

import kr.or.connect.guestbook.dto.Guestbook;
import kr.or.connect.guestbook.service.GuestbookService;

@Controller
public class GuestbookController {
	@Autowired
	GuestbookService guestbookService;

	@GetMapping(path="/list")
	public String list(@RequestParam(name="start", required=false, defaultValue="0") int start,
					   ModelMap model,
                       HttpServletRequest request,
					   HttpServletResponse response) {

        
		String value = null;
		boolean find = false;
		Cookie[] cookies = request.getCookies();
		if(cookies != null) {
			for(Cookie cookie : cookies) {
				if("count".equals(cookie.getName())) {
					find = true;
					value = cookie.getValue();
				}
			}
		}
		
      
		if(!find) {
			value = "1";
		}else { // 쿠키를 찾았다면.
			try {
				int i = Integer.parseInt(value);
				value = Integer.toString(++i);
			}catch(Exception ex) {
				value = "1";
			}
		}
		
   
		Cookie cookie = new Cookie("count", value);
		cookie.setMaxAge(60 * 60 * 24 * 365); // 1년 동안 유지.
		cookie.setPath("/"); // / 경로 이하에 모두 쿠키 적용. 
		response.addCookie(cookie);
		
		
		List<Guestbook> list = guestbookService.getGuestbooks(start);
		
		int count = guestbookService.getCount();
		int pageCount = count / GuestbookService.LIMIT;
		if(count % GuestbookService.LIMIT > 0)
			pageCount++;
		
		List<Integer> pageStartList = new ArrayList<>();
		for(int i = 0; i < pageCount; i++) {
			pageStartList.add(i * GuestbookService.LIMIT);
		}
		
		model.addAttribute("list", list);
		model.addAttribute("count", count);
		model.addAttribute("pageStartList", pageStartList);
		model.addAttribute("cookieCount", value); // jsp에게 전달하기 위해서 쿠키 값을 model에 담아 전송한다.
		
		return "list";
	}
	
	@PostMapping(path="/write")
	public String write(@ModelAttribute Guestbook guestbook,
						HttpServletRequest request) {
		String clientIp = request.getRemoteAddr();
		System.out.println("clientIp : " + clientIp);
		guestbookService.addGuestbook(guestbook, clientIp);
		return "redirect:list";
	}
}

브라우저를 실행시킨 후, 새로 고침을 조금 여러 번 했을 때 방문한 수가 늘어나 있음을 볼 수 있습니다.

실제 이 쿠키를 제가 만들었을 때 “setMaxAge()를 1년 동안 유지” 라고 지정을 해놨기 때문에 이 쿠키가 없어지지 않을 겁니다.

그런데 새 시크릿 창을 이용해가지고 해당 페이지를 한번 접속한다면?

새 시크릿 창에서는 방문한 수가 1로 나타나게 됩니다.

브라우저가 하나의 클라이언트이고, 전에 켰던 브라우저랑 시크릿 창으로 열려있는 브라우저는

각기 다른 브라우저라고 보기 때문에 이 클라이언트와 해당 클라이언트는 다른 클라이언트라고 판단합니다.

예를 들어서 인터넷 익스플로러를 이용해서 다시 리스트를 보여주세요 하게 되면 방문한 수가 처음 방문했던 거니까 1 하고 나오는 것을 볼 수 있습니다.

### 자세히 봅시다.

일단은 우리가 해야 될 일은 이 클라이언트가 해당 페이지로 요청이 들어왔을 때

실제 지금 쿠키가 존재하는지 판단해야 합니다.

쿠키가 이미 존재하고 있는 클라이언트라고 한다면 이 클라이언트가 가지고 있는 쿠키의 값, 현재는 1일 것 입니다.

1이라는 값을 가져와서 이 값에다가 1을 더한 다음에 다시 클라이언트한테 보내주는 일을 수행해야겠죠.

그러니까 다시 한번 요청을 하게 되면 1이라는 값을 가져가서 1을 더해서 다시 줬기 때문에 2라는 값이 출력이 되고 있는 것을 확인할 수 있습니다.

이것을 위해서는 뭐를 사용할까?

이것을 확인하기 위해서는 request라는 객체를 이용해야 합니다.

이 request라는 객체를 사용하기 위해서 해당 메서드 인자에다가 Http ServletRequest를 선언을 해주시면 바로 사용할 수 있습니다.

그럼 request한테 getCookies() 라는 메서드를 이용하게 되면 클라이언트로부터 쿠키의 배열을 얻어올 수 있습니다.

쿠키가 여러 개일 수 있기 때문에 항상 쿠키의 배열로 return이 될 것입니다.

이때 주의하셔야 될 점!

없었을 때 null을 return 하기 떄문에 반드시 null에 대해서 이렇게 처리를 해주셔야지만

처음 요청이 들어왔을 때 오류를 발생시키지 않을 거예요.

그 다음.

그래서 처음 요청이 들어왔을 때, find라는 변수가 처음은 초기화가 false로 되어 있었기 때문에

처음 요청이 들어왔을 때는 당연히 find가 true가 아닙니다.

그랬을 때는 value에다가 1 하고 주고 있는 것을 볼 수 있을 거고요. 그런 다음에 이 값을 가지고 쿠키를 하나 생성하고 있습니다.

이때 생성할 때 쿠키의 name을 count 하고 주고 있는 걸 볼 수 있고, 이렇게 쿠키 객체를 생성한 다음에 기본적인 사항들을 반드시 넣어주시는 게 좋습니다.

쿠키가 유지 시간을 가진다면 유지 시간을 부여하시면 되고요.

우리는 쿠키가 1년 동안 유지되도록 만들어 두었었기 때문에 브라우저가 닫혔을 때에도 쿠키가 계속 유지되고 있는 것을 볼 수가 있습니다.