---
# System prepended metadata

title: '@ModelAttrbute 2부 - @SessionAttributes 조합하기'
tags: [' SessionAttribute', ModelAttribute]

---

---
tags: ModelAttribute, SessionAttribute
---
@ModelAttrbute 2부 - @SessionAttributes 조합하기
===

아래 코드는 1부의 것과 동일한 소스인데, @SessionAttributes("user") 만 추가 하였다.

```java 
@SessionAttributes("user")    
public class A{

   @PostMapping("/opr/cmpgn/model")
   public String model(@ModelAttribute("user") @Valid User user){
      log.info("user : " + user);
      return user.getOutlinkCategoryCode();
   }
}

```

1부에서 @ModelAttribute는 3가지 단계로 진행된다고 했다.
1. 모델객체 생성 // new User()
2. 프로퍼티 바인딩 // setName(), setAge()..
3. 검증

이때 1번 모델객체 생성시, @SessionAttributes 가 있다면 @ModelAttribute 의 동작이 달라진다.

## @ModelAttribute 객체 생성시, @SessionAttributes 가 있다면 세션에서 가져온다
@ModelAttribute가 객체를 생성할때, Session 에 동일한 이름의 객체가 있다면, 세션에 있는 값으로 모델 객체를 생성을 대신한다.
```java 
@SessionAttributes("user")
@ModelAttribute("user")
````
풀어서 설명하자면 아래 2개를 한것과 같다.

1. `User f = (User)session.getAttribute("user")` 
2. `model.addAttribute('user',f)` 

때문에 user라는 이름의 모델객체가 세션에 없는경우 `HttpSessionRequiredException` 이 발생한다.
이제 이름이 다른 아래 코드를 보면서 차이점을 예상해보자.
```java 
@SessionAttributes("user")
@ModelAttribute("user1")
```
일부러 @ModelAttribute의 이름을 user1 로 @SessionAttributes와 다르게 했다. 
이경우에는 는 @SessionAttributes 가 관리하는 모델중 user1 이라는건 없으므로 연관이 없다.
@ModelAttribute는 세션에서 가져오지 않고 그냥 `model.addAttribute("user1", new User())` 으로 생성 하게 된다.


## @SessionAttributes 는 step 으로 페이지가 나눠진 등록폼을 구현할때 쓰면 좋다.
step1 에서 입력한 데이터들을 step2 로 넘길때 step1 의 정보를 간직할수 있게 된다.
단, session 을 이용하는 만큼 너무 큰 객체는 저장하지 않도록 하고, L4 알고리즘에 따라 세션이 끊어지는 경우도 있으니 서버 상황을 고려해서 사용해야 한다.
> 코드 설명은 ReactionMakeController 로 하겠다.

