MVC 활용(18) : 핸들러 메소드 10부 - @SessionAttribute

18. 핸들러 메소드 10부 - @SessionAttribute

HTTP 세션에 들어있는 값 참조할 때 사용

  • HttpSession을 사용할 때 비해 타입 컨버전을 자동으로 지원하기 때문에 조금 편리함.
  • HTTP 세션에 데이터를 넣고 빼고 싶은 경우에는 HttpSession을 사용할 것.

@SessionAttributes와는 다르다.

  • @SessionAttributes는 해당 컨트롤러 내에서만 동작.
    - 즉, 해당 컨트롤러 안에서 다루는 특정 모델 객체를 세션에 넣고 공유할 때 사용.
    - @SessionAttribute는 컨트롤러 밖(인터셉터 또는 필터 등)에서 만들어 준 세션 데이터에 접근할 때 사용한다.

어떤 웹 사이트에 접속한 시간을 기록하는 Interceptor가 있다고 가정하자.

public class VisitTimeInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        HttpSession session = request.getSession();
        if (session.getAttribute("visitTime") == null){
            session.setAttribute("visitTime", LocalDateTime.now());
        }
        return true;
    }
}

WebMvcConfigurer에 Interceptor 등록하기

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new VisitTimeInterceptor());
    }
}
@Controller
@SessionAttributes("event")
public class SampleController {

    @GetMapping("/events/form/name")
    public String eventsFormName(Model model) {
        model.addAttribute("event", new Event());
        // 자동으로 세션에 넣어줌
        return "events/form-name";
    }

    @PostMapping("/events/form/name")
    public String eventsFormNameSubmit(@ModelAttribute @Valid Event event, BindingResult bindingResult){
        if(bindingResult.hasErrors()){
            return "/events/form-name";
        }
        return "redirect:/events/form/limit";
    }
    
    @GetMapping("/events/form/limit")
    public String eventsFormLimit(@ModelAttribute @Valid Event event, Model model) {
        model.addAttribute("event", event);
        // 자동으로 세션에 넣어줌
        return "events/form-limit";
    }
    
    @PostMapping("/events/form/limit")
    public String eventsFormLimitSubmit(@ModelAttribute @Valid Event event, BindingResult bindingResult, SessionStatus sessionStatus){
        if(bindingResult.hasErrors()){
            return "/events/form-limit";
        }
        sessionStatus.setComplete();
        // 데이터베이스에서 save 했다고 가정
        return "redirect:/events/list";
    }
    
    @GetMapping("/events/list")
    public String getEvents(Model model, @SessionAttriubte LocalDateTime visitTime){
    	System.out.println(visitTime);
        Event event = new Event();
        event.setName("spring");
        event.setLimit(10);
        // 데이터베이스에서 읽어왔다고 가정한다.
        List<Event> eventList = new ArrayList<>();
        eventList.add(event);
        model.addAttribute("eventList", eventList);
        return "/events/list";
    }
}

만약 HttpSession을 사용하고 싶으면 타입 컨버전을 해야 한다.

@Controller
@SessionAttributes("event")
public class SampleController {

    @GetMapping("/events/form/name")
    public String eventsFormName(Model model) {
        model.addAttribute("event", new Event());
        // 자동으로 세션에 넣어줌
        return "events/form-name";
    }

    @PostMapping("/events/form/name")
    public String eventsFormNameSubmit(@ModelAttribute @Valid Event event, BindingResult bindingResult){
        if(bindingResult.hasErrors()){
            return "/events/form-name";
        }
        return "redirect:/events/form/limit";
    }
    
    @GetMapping("/events/form/limit")
    public String eventsFormLimit(@ModelAttribute @Valid Event event, Model model) {
        model.addAttribute("event", event);
        // 자동으로 세션에 넣어줌
        return "events/form-limit";
    }
    
    @PostMapping("/events/form/limit")
    public String eventsFormLimitSubmit(@ModelAttribute @Valid Event event, BindingResult bindingResult, SessionStatus sessionStatus){
        if(bindingResult.hasErrors()){
            return "/events/form-limit";
        }
        sessionStatus.setComplete();
        // 데이터베이스에서 save 했다고 가정
        return "redirect:/events/list";
    }
    
    @GetMapping("/events/list")
    public String getEvents(Model model, HttpSession httpSession){
    	LocalDateTime visitTime = (LocalDateTime)httpSession.getAttribute("visitTime");
        System.out.println(visitTime);
        Event event = new Event();
        event.setName("spring");
        event.setLimit(10);
        // 데이터베이스에서 읽어왔다고 가정한다.
        List<Event> eventList = new ArrayList<>();
        eventList.add(event);
        model.addAttribute("eventList", eventList);
        return "/events/list";
    }
}

참고

  • 인프런 : 스프링 웹 MVC(백기선)

좋은 웹페이지 즐겨찾기