이번에는 Session과 관련된 Spring MVC의 Handler Argument를 살펴보겠습니다.
Spring Request Handler에서 HttpSession
를 Argument으로 받아서 사용가능합니다.
@GetMapping("/events/form")
public String eventsForm(Model model, HttpSession httpSession) {
model.addAttribute("event", new Event());
httpSession.setAttribute("event", new Event());
return "/events/form";
}
위와 같이 Session Attribute에 문자열 Key/Value형태로 값을 저장할 수 있습니다.
HttpSession
를 직접 사용할 경우 Session에서 값을 가져올 때 Object
타입으로 받아서 명시적으로 캐스팅이 필요합니다.
Spring은
@Controller
@SessionAttributes("pet")
public class EditPetForm {
// ...
}
@SessionAttribute
는 model attribute들을 요청사이에 Http Servlet Session에 저장하기 위해 사용됩니다.
첫 요청에서 pet
이름을 가진 model attribute가 모델에 추가되었을때, 그 값은 자동으로 HttpServlet Session에 저장됩니다. 그리고 그것은 또 다른 controller method가 SessionStatus
method argument를 사용해서 session storage를 clear할 때까지 유지됩니다.
// ...
@PostMapping("/pets/{id}")
public String handle(Pet pet, BindingResult errors, SessionStatus status) {
if (errors.hasErrors) {
// ...
}
status.setComplete();
// ...
}
}
앞서 설명했던 @SessionAttritubes
와는 s
가 붙었냐 안붙었냐 차이지만 의미가 많이 다릅니다. 앞에서 설명했던 @SessionAttributes
는 하나의 Controller에서만 한정해서 ModelAttrbute를 Sessoin을 통해 자동으로 상태가 유지되도록했습니다.
하지만 @SessionAtttibute는 하나의 Controller에 한정적이지 않고 HttpSession을 Handler에서 Arugment로 Session Attribute로 가져올 수 있습니다.
Handler Argument에서 바로 HttpSession의 Attribute를 가져와줍니다.
@RequestMapping("/")
public String handle(@SessionAttribute User user) {
// ...
}
HttpSession을 직접 사용할 경우와의 차이는 타입 캐스팅을 직접해주지 않아도 됩니다.
이런 요청간에 상태가 유지되는 세션 Attribute의 대표적인 사례는 회원가입처럼 입력해야 할 값이 많은 경우, 여러 화면(여러 폼)으로 나누어서 단계적으로 진행할 필요가 있습니다. 그럴 때 이전에 입력한 값을 폼으로 두어 유지하게 됩니다.