project 에는 context root
와 web resources
폴더가 있다.
그 중 web resources 의 기본적인 폴더 구조는 src/main/resources/~ 로 시작된다.
물론 /resources/~/
라는 폴더는 사용자가 다른 이름으로 생성할 수도 있다.
service 는 stateless 하기 때문에, 하나를 만들어놓고 공유해서 사용하는 것이 더 효율적이다.
session 에 인증 정보를 넣는 것은 위험하다. 하지만 프로그램을 편하게 끌어갈 수 있는 방법 중 하나인 것이 session 이다.
session
은 HttpSession 객체.
기존의 servlet 에서는 session 객체를 얻기 위한 방식으로 request.getSession(true|false)
로 session 을 생성하거나 얻어왔다.
스프링에서도 이 방법을 사용할 수는 있지만, 다소 비효율적인 부분이 생기기 때문에, 이 점을 편하게 사용하고자 등장한 어노테이션이 @SessionAttributes
이다.
@SessionAttributes 는 session 에 값을 저장하거나, 값을 찾을 수 있도록 지정해주는 어노테이션.
즉 session 에 값을 저장하는 것이 아니다.
@SessionAttributes
public class sessionClass{
}
@SessionAttributes
어노테이션은, session 을 가져오려는 클래스 상단에 작성하게 된다.
# 주의! `@SessionAttribute` 라는, 하는 일이 다른 어노테이션이 존재한다. 혼동하면 안된다.
selvlet filter 와 같은, 컨트롤러가 아닌 외부에서 저장해놓은 session 안의 값(객체)를 사용하기 위해서 사용한다.
일반 메소드의 상단에 작성하게 된다.
외부 session 으로부터 값을 가져와서 parameter 에 그 session 값을 사용할 때, 어노테이션을 사용하게 된다.
data1 이라는 model 객체가 내 session 에도 자동적으로 설정이 되게 된다.
또한, controlelr 의 어느 부분에서든 Model 객체에 값을 지정할 수 있는데, 이 때 지정하는 값의 key 값이 @SessionAttributes
의 속성으로 저장되어 있다면 자동적으로 session 에도 저장이 이루어진다.
현재 @SessionAttributes
의 속성으로 data01, shin, newStudent 라는 값이 지정되어 있다.
단, newStudent
라는 attribute 에 대한 개념을 명확히 해야 하는데, newStudent 는 메소드의 인자에 있는 @ModelAttribute
이다. 그리고 인자에 있는 @ModelAttribute
의 경우, 가장 먼저 @SessionAttributes
에 값이 있는지 없는지를 검사한다.
@ModelAttribute
는 session 으로부터 @SessionAttributes
의 속성에 적혀있는 값을 가져오는 역할을 한다.
따라서, handler 의 인자로 작성한 @ModelAttribute(newStudent)
코드는 가장 먼저 Session 을 뒤지게 되고, Session 에는 newStudnet 라는 값이 없기 때문에 에러를 내게 된다.
이 에러를 잡기 위해서는, handler 가 실행되기 전에 실행되는 @ModelAttribute 어노테이션이 붙은 메소드를 하나 생성하고, 해당 메소드의 실행 결과로 newStudent 라는 빈 객체 하나를 리턴해준다.
그리고 다시 실행을 하게 되면, 가장 먼저 @ModelAttribute 어노테이션이 붙은 메소드들이 실행되고, return 값을 model에 담는다.
sessionAttribute 의 속성으로 적힌 값과 model 의 key값이 일치하기 때문에 return 값인 new Studnet() 라는 빈 객체를 session 에도 담는다.
hnadler의 인자로 vo타입(@ModelAttribute)을 받을 때,
key 값인 newStudent
라는 값이 @SessionAttributes 에 설정되어 있다면,
Sesison에 저장되어 있는 newStudent = new Student
를 가장 먼저 꺼내온다.
그 후에 session에서 command 객체와 동일한 타입으로 저장된 객체에 request 로 들어온 값들을 setter 로 주입한다.
그렇게 주입이 완료된 객체가 model과, 그리고 session 에도 저장이 된다.
즉 이 방법을 통해서, 사용자가 id, pwd 를 입력하고 handler 를 거치기만 해도 바로 session 으로 저장할 수 있게 된다.
페이지가 넘어가면서 사용자가 하는 행동을 추적할 때 사용한다.
대표적으로, 회원가입을 할 때 기본 정보를 입력하고, 다음 페이지에서 취미들을 입력하고, 또 다음 페이지에서 개인정보 동의를 하다가, 이전의 페이지에서 잘못 입력된 것을 찾아서 다시 뒤로 돌아갈 때.
원래대로라면 뒤로 가기를 누르게 되면 기존에 입력해두었던 모든 내용들이 사라지게 된다.
그런데 지금의 이 sessionAttribute 를 사용하게 되면, 저장된 값을 유지할 수 있게 된다.
또한, session 처리를 위해 빈 객체를 리턴하는 메소드를 만들었다면, 해당 메소드는 모든 처리 과정에서 단 한 번 처리가 이루어지고, 세션에 해당 key에 대한 값이 담겼다면, 그 뒤로는 다시 메소드가 실행되지는 않는다.
하지만, sessionAttributes 에 값이 담기지 않았다면, 그 메소드는 계속해서 객체를 생성한다.
@SessionAttributes
를 통해서 session 내부에 넣어놓은 session 값을 만료 시킬 수 있다.