Session을 이용한 상태정보 유지하기

2020-07-31

해당 Post는 자바 웹 어플리케이션에서 세션을 사용하는 방법에 대해서 정리한 파일입니다.


실습코드

  • /guess로 요청을 하면 컴퓨터가 1부터 100 사이의 임의의 값 중의 하나를 맞춰보라는 메시지가 출력합니다.
  • 해당 값은 세션에 저장합니다.
  • 사용자는 1부터 100 사이의 값을 입력합니다.
  • 입력한 값이 세션 값보다 작으면, 입력한 값이 작다고 출력합니다.
  • 입력한 값이 세션 값보다 크면, 입력한 값이 크다고 출력합니다.
  • 입력한 값이 세션 값과 같다면 몇 번째에 맞췄다고 출력합니다.

GuessNumberController

package kr.or.connect.guestbook.controller;

import javax.servlet.http.HttpSession;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class GuessNumberController {

	@GetMapping("/guess")
	public String guess(@RequestParam(name="number", required=false) Integer number,
			HttpSession session,
			ModelMap model) {
		
		String message = null;

		// get방식으로 /guess 를 요청하는데 파라미터 number가 없을 경우에는 session에 count를 0으로 randomNumber엔 1부터 100사이의 값을 저장합니다.
		if(number == null) {
			session.setAttribute("count", 0);
			session.setAttribute("randomNumber", (int)(Math.random() * 100) + 1); // 1 ~ 100사이의 random값
			message = "내가 생각한 숫자를 맞춰보세요.";
		}else {

			// number파라미터가 있을 경우 세션에서 값을 읽어들인 후, number와 세션에 저장된 값을 비교합니다.
			// 값을 비교해서 작거나 크다면 카운트를 1증가시켜주고
			// 값이 같다면 세션 정보를 삭제합니다.
			// 각 상황에 맞는 메시지를 message변수에 저장을 한 후 jsp에게 전달하기 위해서 ModelMap의 addAttribute메소드를 통해 전달하게 됩니다.
			int count = (Integer)session.getAttribute("count");
			int randomNumber = (Integer)session.getAttribute("randomNumber");
		
			
			if(number < randomNumber) {
				message = "입력한 값은 내가 생각하고 있는 숫자보다 작습니다.";
				session.setAttribute("count", ++count);
			}else if(number > randomNumber) {
				message = "입력한 값은 내가 생각하고 있는 숫자보다 큽니다.";
				session.setAttribute("count", ++count);
			}else {
				message = "OK " + ++count + " 번째 맞췄습니다. 내가 생각한 숫자는 " + number + " 입니다.";
				session.removeAttribute("count");
				session.removeAttribute("randomNumber");
			}
		}
		
		model.addAttribute("message", message);
		
		return "guess";
	}
}

guess.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>       
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>숫자 맞추기 게임</title>
</head>
<body>
<h1> 숫자 맞추기 게임.</h1>
<hr>
<h3>${message }</h3>

<c:if test="${sessionScope.count != null}">
<form method="get" action="guess">
1부터 100사이의 숫자로 맞춰주세요.<br>
<input type="text" name="number"><br>
<input type="submit" value="확인">
</form>
</c:if>

<a href="guess">게임 다시 시작하기.</a>
</body>
</html>

/guess라고 요청을 하게 되면 컴퓨터가 1부터 100사이의 임의의 값 중 하나를 맞춰보라는 메시지를 출력할 것 입니다.

실제 여기에 있는 임의의 값을 하나 구해내게 할 거고 이때 구해진 값은 세션에다가 저장을 하게 됩니다.

사용자는 다시 1부터 100사이의 값을 입력을 하게 될 것입니다.

입력한 값이 세션에 있는 값보다 작다면 입력한 값이 작다고 출력을 하게 될 것이고, 입력한 값이 크다면 크다고 출력을 하게 될 것입니다.

이런 동작들을 계속 수행을 하게 될 거고요.

그러다가 이제 입력한 값이 세션의 값과 같다면 몇 번째에 맞췄는지 출력을 하게 될 거예요.

이 부분들이 수행이 될 때마다 몇 번째라는 값을 출력하기 위해서 그 부분도 값을 유지하고 있었어야 되겠죠.

먼저 Controller 패키지에다가 GuessNumberController를 하나 추가하면 됩니다.

Controller니까 Controller 하고 어노테이션 하나 붙여주셔야겠죠.

아까 요구 사항 중에 하나가 guess라고 요청했을 때 수행할 것이라는 점이기 때문에 GetMapping에다가 guess라는 값을 하나 부여했습니다.

하나 넘겼을 때, 일단은 사용자가 값을 보냈을 때 받아와야 될 거니까 RequestParam 이런 거 어노테이션 하나 넣어서 얻어오고,

얻어올 때 input 상자의 이름을 number라고 지정합니다.

이때 받아온 값을 number라는 Integer 타입의 변수에다가 넣어줍니다.

HttpSession, 스프링을 사용하지 않으셨을 때는 request로부터 getSession() 해서 얻어내오시면 되는데 스프링에서는 그 일도 대신해줍니다.

그러니까 session 하고 하나 선언만 하시면 되시고,

값을 저장하기 위해서 ModelMap 객체도 하나 만들어줍니다.

그리고 return, String으로 하겠다고 했으니까 JSP. view에 대한 정보를 String 값으로 return하시면 됩니다.

guess.jsp 이렇게 하나 만들어낼 거니까 guess 하고 return 하게 합니다.

요구 사항을 보면 일단은 해야 될 것이 1부터 100까지 임의의 값을 하나 구해야 될 거고.

“몇 번째 맞췄습니다.”를 출력하기 위한 부분을 구현해야합니다.

그리고 “값이 작다 또는 크다”와 같이 현재 값과의 비교를 하는 메시지를 갖고 있을 변수도 하나 지정을 합니다.

RequestParam으로 number를 받는데 number의 값이 없을때는 최초로 요청이 들어왔을 때 입니다.

그럼 그때 이 사용자가 몇 번째 맞췄는지 알아야 되니까 그 값을 저장할 수 있는 count도 생성해 줍시다.

그리고 1부터 100사이의 랜덤 값도 생성해 줍시다.

만약에 number가 null 이라면 이제 어떤 일을 할까요.

세션의 setAttribute()에다가 count를 0이라고 초깃값을 하나 부여하고, 그리고 이 세션에다가 setAttribute() 하셔가지고

1부터 100사이의 값 이거 하나 부여합니다.

이 세션 name은 random Number 이렇게 하나 지정으로 하고, 이때 randomNumber는 1에서 100까지의 값을 하나 구해야 되죠.

Math.random() 이런 거 이용하시면 되는데 Math.random()을 이용해서 1에서 100사이의 수를 구해내게 하고 싶은데

Math.random()은 실수를 return 시 마다 +1을 해줘야합니다.

그리고 처음 요청이 들어왔을 때 우리는 이 메시지를 뭐라고 주기로 했냐면 내가 생각한 숫자를 맞춰보세요 이렇게 메시지를 보내주기로 했으니까

처음 요청이 들어왔을 때 그런데 number가 이미 null이 아니었다는 것은 이 부분이 한번 실행이 됐고 사용자로부터 값을 입력받았을 때죠.

그럼 이때는 해야 될 일 실제 이 세션이 갖고 있는 값과 사용자가 보내준 값을 비교해야겠죠.

이런 값을 비교해서 작거나 크다면 count를 1증가 시켜야 될 거고요.

값이 같다면은 세션 정보를 삭제, 각 상황에 맞는 메시지 변수를 저장한 후에 JSP에 전달하기 위한 아래와 같은 수행을 하면 되는데요.

이 두 가지 일을 다 수행하게 하기 위해서 세션한테 얻어내야 합니다..

세션한테 getAttribute() 해서 count의 값을 얻어와야 될 거고요.

세션의 값이 object로 들어있었을 거기 때문에 적절하게 형 변환 필요하겠죠.

이렇게 세션이 가지고 있는 randomNumber도 얻어왔을 거고요.

만약에 사용자가 입력한 값 number랑 randomNumber랑 비교했을 때. 만약에 사용자가 입력한 값이 작다고 한다면 어떤 일을 수행하면??

메시지에다가 입력한 값은, 이런 적절한 메시지를 넣어주시면 될 거고요.

count만 하나 늘려서 다시 세션에다가 저장을 해주면 되겠죠. count하시면 될 거고 이미 세션에서 count를 꺼내와서

count라는 변수에다가 넣어뒀으니까 이 count라는 변수에 1을 더해서 넣어주면 되겠죠.

그런데 만약에 반대의 경우로 사용자가 입력한 값이 이미 세션에서 가지고 있는 random Number보다 컸을 때에는 ‘큽니다’ 하고,

큽니다라는 메시지를 보내주면 됩니다.

값이 크지도 않고 작지도 않다는 것은 맞았으니까 메시지를 보내주면 될 텐데 맞았을 때 OK 이렇게 하나 보내줍니다.

이렇게 정답을 맞혔을 때에는 세션의 값을 없애기 위해 세션에 removeAttribute() 메서드를 수행을 해주시면 돼요.

그리고 이 세션이 가지고 있는 count 값이랑 randomNumber 값도 같이 없앱니다.

이제 결과 화면을 보여주기 위한 부분을 작성하시면 되는데 기회 정보는 guess라고 줬기 때문에 이에 해당하는 JSP를 하나 만들어주고,

JSP 파일을 만들어주셨으면 이 JSP 내에서 JSTL 사용해야 될 거니까 사용할 수 있도록 라이브러리를 넣어주시면 될 거 같습니다.