본문 바로가기
  • 실행력이 모든걸 결정한다
Spring Series/Spring Framework

[Spring] @SessionAttributes와 SessionStatus

by 김코더 김주역 2022. 9. 14.
반응형

세션은 로그인 정보와 같이 애플리케이션 내에서 유지되어야 하는 정보를 저장하는 데 쓰인다.

 

1. 세션 도입의 필요성

수정 폼에서는 일부 정보만 수정할 수 있도록 일부 정보만 보여지기 때문에, 수정 데이터를 서버로 전송했을 때 역시 일부 정보만 전송될 것이다. 그렇게 되면, 수정한 내용이 들어있는 오브젝트를 서비스 계층이나 DAO에 전달하는 경우에 일부 프로퍼티 값은 null이거나 0인 상태로 전달될 것이고, 이러한 문제를 해결하기 위해 도메인 오브젝트 중심 방법이 아닌 계층 간의 결합도가 높은 데이터 중심 방식을 선택하게 되기 쉬워진다.

 

물론 다음과 같은 방법들을 생각해볼 수는 있겠지만 각각 작지 않은 단점이 존재한다.

  • <input type="hidden"> 태그로 정보를 유지하는 방법 : 보안에 매우 취약함
  • DB를 재조회해서 수정된 부분만 바꿔주는 방법 : 번거롭고 DB에 부담이 갈 수 있음
  • 계층 사이에 강한 결합을 주는 방법 : 확장성과 유지보수성을 포기해야 함

 

Spring의 세션을 이용하면 위에서 설명한 방법들의 단점을 모두 피해가면서 기존 객체의 상태를 유지시킬 수 있다.

 

 

 

2. @SessionAttributes

- 기본적으로 HTTP 세션을 사용하며, 세션 정보를 저장하는 방법은 변경 가능하다.

 

@SessionAttributes 사용 방법 (HTTP 세션 기준)

- 아래와 같이 @SessionAttributes 어노테이션을 클래스 레벨에 부여하고, 기본 파라미터에는 세션에 저장해둘 모델의 이름을 넣어주기만 하면 된다. @SessionAttributes의 설정은 클래스의 모든 메소드에 적용된다.

@Controller
@SessionAttributes("user")
public class UserController {
    ...
    @RequestMapping(...)
    public String method1(Model model) {
        model.addAttribute("user", userService.getUser(1)); // user라는 세션 애트리뷰트에 User 오브젝트가 저장된다.
        return "user";
    }
    
    @RequestMapping(...)
    public String method2(@ModelAttribute User user) {...}
}

위의 예시에서 @SessionAttributes가 해주는 일은 3가지가 있다.

  • 모델 정보에 담긴 오브젝트들 중에서 @SessionAttributes에 지정한 이름과 동일한 이름의 모델이 있다면 이를 세션에 저장해준다. 위의 예시에서는, method1() 메소드에 대한 뷰의 출력이 끝나고 세션을 보면 모델 정보에 추가한 User 오브젝트가 저장되어 있을 것이다.
  • @SessionAttributes에 지정한 이름과 @ModelAttribute 파라미터의 이름이 동일하다면, 먼저 세션에 같은 이름의 오브젝트가 존재하는지 확인한다. 만약 존재한다면 세션에 저장된 해당 오브젝트를 적절한 @ModelAttribute 파라미터에 전달해준다. 마지막에는 @ModelAttribute에 의해 요청 파라미터에 대한 바인딩도 이루어진다. 즉, 기존 오브젝트의 유지와 수정 데이터의 반영이 같이 이루어지는 것이다.
  • 사용자가 폼을 제출했을 때 검증 오류가 발생하면 세션에 저장해둔 오브젝트를 활용해서 다시 사용자 폼을 띄워준다.

 

 

 

3. SessionStatus

- 현재 세션을 다룰 수 있도록 하는 오브젝트로, 컨트롤러 메소드의 파라미터로 사용할 수 있는 Spring 내장 타입이다.

- 세션에 더 이상 저장할 필요가 없어진 모델 오브젝트를 제거하는 책임은 컨트롤러 코드에게 있다. 그래서 SessionStatus.setComplete() 메소드를 직접 호출해서 세션을 제거해줘야 한다.

- @SessionAttributes를 사용할 때는 SessionStatus를 이용해서 세션을 정리해주는 코드가 반드시 필요하다.

 

 

 

4. 등록 폼에 @SessionAttributes가 사용되는 경우

- 등록 폼에 사용할 복잡한 도메인 오브젝트를 미리 초기화해놓고 싶다면 이를 세션에 저장해둬도 된다. 사용자의 입력을 돕기 위해 디폴트 값을 보여주고 싶을 때 이 방법을 사용할 수도 있다. 등록 폼의 입력 값에 잘못된 것이 있다면 세션에 저장된 오브젝트를 활용해서 등록 폼을 다시 띄우면 된다.

- Spring의 폼 태그는 등록과 수정에 상관 없이 폼의 내용을 담은 도메인 오브젝트를 필요로 한다. 초기에 빈 폼을 보여줄 때와 기존 입력 값을 보여줄 때 모두 같은 폼을 사용하도록 하기 위함이다. 즉, 최초에 폼을 출력하는 컨트롤러에서 빈 도메인 오브젝트를 만들어서 세션에 저장해둬야 한다.

 

 

 

● 참고 자료 : 토비의 스프링 3.1 Vol.2

 

반응형

댓글