세션, 모델, 그리고 요청 - @SessionAttributes
이전까지 우리는 jsp로 값을 보내고, 보낸 값을 사용하는 법을 배운 적이 있다. 그리고 그 값을 이용해 login에 성공하면 다른 페이지로 이동하는 법을 배웠다.
하나 생각해보자. 우리가 특정 jsp에 값을 보냈을 때, 우리는 지금까지 배운 걸 이용해서 다른 jsp에서도 그 값을 사용할 수 있게끔 할 수 있는가?
안된다. 지금까지 배운 것만으로는 할 수 없다. 때문에 이번 시간에는 세션이라는 걸 이용해서 여러 jsp에서 값을 이용할 수 있게끔 하는 방법을 배워보려 한다.
이를 위해서 일단 페이지 내부에 다른 페이지로 갈 수 있는 링크를 삽입해보려 한다.
```
<html>
<head>
<title>Welcome Page</title>
</head>
<body>
<div>${name} Welcome~!</div>
<div><a href="list-todos">Manage</a> your todos</div>
</body>
</html>
```
이렇게 하고 나서, 페이지 내부의 링크를 통해 list-todos로 이동해보자. 페이로드를 확인해보면 jsp에 전송되어있던 값이 보이지 않는 걸 알 수 있다.
이는 우리가 model에 값을 넣어 전송했기 때문이다. 여러 요청에 걸쳐서 값이 살아있기를 바란다면 세션에 값을 넣어야 한다. 이는 @SessionAttributes 어노테이션을 통해 가능하다.
LoginController를 통해 이해해보자.
@SessionAttributes 어노테이션을 활용한 코드는 아래와 같다.
```
@Controller
@SessionAttributes("name")
public class LoginController {
AuthenticationService authenticationService;
public LoginController(AuthenticationService authenticationService) {
super();
this.authenticationService = authenticationService;
}
@RequestMapping(value="login", method=RequestMethod.GET)
public String gotoLoginPage() {
return "login";
}
@RequestMapping(value="login", method=RequestMethod.POST)
public String gotoWelcomePage(@RequestParam String name, @RequestParam String password, ModelMap model) {
if(authenticationService.authenticate(name, password)) {
model.put("name", name);
return "welcome";
}
model.put("errorMessage", "Invalid Credential. try again.");
return "login";
}
}
```
모델에 값을 넣어주는 건 동일하다. 여기에서 값을 사용하려는 컨트롤러에 @SessionAttributes를 통해 어떤 값을 사용할지 정해준다는 점이 다르다.
주의해야 할 것은 이렇게 LoginController에만 @SessionAttributes를 붙이면 끝나는 게 아니다. 해당 값을 사용하고 싶은 모든 컨트롤러에서 @SessionAttributes를 사용해줘야 한다.
때문에 list-todos에서도 활용하고 싶다면 TodoController에도 @SessionAttributes 어노테이션을 붙여줘야한다.
이제 복습 차원에서 세션을 활용했을 때와 하지 않았을 때를 비교해보자.
일단 브라우저에서 오는 모든 요청은 우리가 서버에 배포한 웹 애플리케이션을 통해 처리된다.
만약 세션을 활용하지 않았다면, 서버는 요청을 처리하고, 필요한 정보를 메모리에 잠시 저장한다. 이 정보는 요청이 끝나면 사라진다. 때문에 다음에 같은 사용자가 요청을 보낼 때, 정보를 다시 입력하고 저장해야 한다. 이 방식은 메모리를 적게 사용하지만 매번 정보를 새로 입력해야 한다는 단점이 있다.
세션을 활용했다면, 요청이 끝나도 정보가 사라지지 않아 다수의 요청에 걸쳐 이를 사용할 수 있다. 편리하지만, 메모리에 정보가 계속 저장되어 있기 땜누에 메모리 사용량이 늘어난다. 이렇게 저장된 정보는 사용자가 애플리케이션을 종료하거나 세션이 만료될 때 사라진다.