ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 핸들러 메소드 11부 RedirectAttributes
    SPRING/스프링 MVC 2021. 7. 8. 18:49

    리다이렉트 할 때 기본적으로 Model에 들어있는 primitive type 데이터는 URI 쿼리 매개변수에 추가된다.

    • 스프링 부트에서는 이 기능이 기본적으로 비활성화 되어 있다.
    • Ignore-default-model-on-redirect 프로퍼티를 사용해서 활성화 할 수 있다.

    원하는 값만 리다이렉트 할 때 전달하고 싶다면 RedirectAttributes에 명시적으로 추가할 수 있다.

    리다이렉트 요청을 처리하는 곳에서 쿼리 매개변수를 @RequestParam 또는 @ModelAttribute로 받을 수 있다.

     

    @Controller
    @SessionAttributes("event")
    public class SampleController2 {
    
        // 이름 Form 화면
        @GetMapping("/events/form/name")
        public String eventsForm(Model model, HttpSession httpSession) {
    
            model.addAttribute("event",new Event());
            return "/events/form-name";
        }
    
    
        // 이름 form에서 입력받은 내용 전송
        @PostMapping("/events/form/name")
        public String eventForNameSubmit(@ModelAttribute @Validated(Event.ValidateName.class) Event event,
                              BindingResult bindingResult, Model model,
                              SessionStatus sessionStatus) {
    
            // @Validated 어노테이션을 통하여 Validation 체크에 맞지 않으면 다시 form으로 리턴
            if(bindingResult.hasErrors()) {
                return "/events/form-name";
            }
    
            // POST-REDIRECT-GET 패턴
            // ( Post 이후에 브라우저를 리프래시 하더라도 폼 서브밋이 발생하지 않도록 하는 패턴)
            return "redirect:/events/form/limit";
        }
    
        // limit Form 화면
        @GetMapping("/events/form/limit")
        public String eventForLimit(@ModelAttribute Event event, Model model) {
    
            model.addAttribute("event",event);
            return "events/form-limit";
        }
    
        // limit form에서 입력받은 내용 전송
        @PostMapping("/events/form/limit")
        public String eventForLimitSubmit(@ModelAttribute @Validated(Event.ValidateLimit.class)
                                          Event event,BindingResult bindingResult,
                                          Model model, SessionStatus sessionStatus) {
    
            if(bindingResult.hasErrors()) {
                return "/events/form-limit";
            }
            // 세션 데이터 초기화
            sessionStatus.setComplete();
    
            model.addAttribute("name", event.getName());
            model.addAttribute("limit",event.getLimit());
    
            return "redirect:/events/list";
        }
    
        // 이벤트 목록 페이지
        @GetMapping("/events/list")
        public String getEvents(Model model, @SessionAttribute 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);
            return "/events/list";
        }
        
    }

    application.properties에 아래와 같이 설정을 해야 URI 쿼리변수에 Model정보를 보낼 수 있다.

    spring.mvc.Ignore-default-model-on-redirect=false

     

     

    Model에 있는 모든 정보를 보내지 않고, 일부만 보내고 싶다면 Model 대신에 RedirectAttributes를 사용한다.

     

      @PostMapping("/events/form/limit")
        public String eventForLimitSubmit(@ModelAttribute @Validated(Event.ValidateLimit.class)
                                          Event event, BindingResult bindingResult,
                                          RedirectAttributes attributes, SessionStatus sessionStatus) {
    
            if(bindingResult.hasErrors()) {
                return "/events/form-limit";
            }
            // 세션 데이터 초기화
            sessionStatus.setComplete();
    
            attributes.addAttribute("name", event.getName());
            attributes.addAttribute("limit",event.getLimit());
    
            return "redirect:/events/list";
        }

     

    redirect를 호출하여 파라메터를 받는 쪽에서는 아래와 같이 사용할 수 있다.

     

    1. @RequestParam

     // 이벤트 목록 페이지
        @GetMapping("/events/list")
        public String getEvents(@RequestParam String name, @RequestParam Integer limit,
                                Model model, @SessionAttribute LocalDateTime visitTime) {
    
            System.out.println(visitTime);
            Event newEvent = new Event();
            newEvent.setName(name);
            newEvent.setLimit(limit);
    
            // 리스트를 불러오는 부분
            Event event = new Event();
            event.setName("spring");
            event.setLimit(10);
    
            List<Event> eventList = new ArrayList<>();
            eventList.add(event);
            eventList.add(newEvent);
            model.addAttribute(eventList);
            return "/events/list";
        }

     

    2. @ModelAttribute로 받기

      @GetMapping("/events/list")
        public String getEvents(@ModelAttribute("newEvent") Event event,
                                Model model, @SessionAttriubte LocalDateTime visitTime){
            System.out.println(visitTime);
            
            Event spring = new Event();
            spring.setName("spring");
            spring.setLimit(10);
            
            List<Event> eventList = new ArrayList<>();
            eventList.add(spring);
            eventList.add(newEvent);
            model.addAttribute("eventList", eventList);
            return "/events/list";
        }

    @SessionAttributes("name")과 같은 이름으로 @ModelAttribute("name")을 사용하면 Session쪽에서 참조를 하기 때문에 겹쳐서 쓰면 안된다. 특히 sessionStatus.setComplete(); 에서 이미 세션을 제거한 경우에는 에러가 발생한다.

     

    결과

     

     

Designed by Tistory.