RedirectAttributes
: 리다이렉트 할 때 기본적으로 Model에 들어있는 primitive type 데이터는 URI 쿼리 매개변수에 추가된다.
- 스프링 부트에서 이 기능이 기본적으로 비활성화 되어 있다
- spring.mvc.ignore-default-model-on-redirect=false 프로퍼티를 사용해서 활성화 할 수 있다.
원하는 값만 리다이렉트 할 때 전달하고 싶다면 RedirectAttributes에 명시적으로 추가할 수 있다.
리다이렉트 요청을 처리하는 곳에서 쿼리 매개변수를 @RequestParam 또는 @ModelAttribute로 받을 수 있다.
package com.example.demo;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttribute;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
@Controller
@SessionAttributes("event")
public class SampleController {
@GetMapping("/events/form/name")
public String eventFormName(Model model) {
model.addAttribute("event",new Event());
return "/events/form-name";
}
@PostMapping("/events/form/name")
public String eventsFromNameSubmit(@Validated @ModelAttribute Event event
,BindingResult bindingResult) {
if(bindingResult.hasErrors()) {
return "/events/form-name";
}
return "redirect:/events/form/limit";
}
@GetMapping("/events/form/limit")
public String eventFormLimit(@ModelAttribute Event event , Model model) {
model.addAttribute("event",event);
return "/events/form-limit";
}
@PostMapping("/events/form/limit")
public String createEvent(@Validated @ModelAttribute Event event
,BindingResult bindingResult
,SessionStatus sessionStatus
,Model model) {
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(@RequestParam String name,
@RequestParam Integer limit,
Model model ,
@SessionAttribute LocalDateTime 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<Event>();
eventList.add(event);
eventList.add(newEvent);
model.addAttribute(eventList);
return "/events/list";
}
}
=> model에 primitive 데이터를 담은 다음 redirect를 하게 되면 쿼리문에
model의 데이터들이 parameter로 들어가게 된다.
그래서 parameter로 노출시키고 싶은것만 RedirectAttributes 객체를 사용하여 전달한다.
package com.example.demo;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttribute;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
@Controller
@SessionAttributes("event")
public class SampleController {
@GetMapping("/events/form/name")
public String eventFormName(Model model) {
model.addAttribute("event", new Event());
return "/events/form-name";
}
@PostMapping("/events/form/name")
public String eventsFromNameSubmit(@Validated @ModelAttribute Event event, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return "/events/form-name";
}
return "redirect:/events/form/limit";
}
@GetMapping("/events/form/limit")
public String eventFormLimit(@ModelAttribute Event event, Model model) {
model.addAttribute("event", event);
return "/events/form-limit";
}
@PostMapping("/events/form/limit")
public String createEvent(@Validated @ModelAttribute Event event, BindingResult bindingResult,
SessionStatus sessionStatus, RedirectAttributes attributes) {
if (bindingResult.hasErrors()) {
return "/events/form-limit";
}
sessionStatus.setComplete();
attributes.addAttribute("name", event.getName());
return "redirect:/events/list";
}
@GetMapping("/events/list")
public String getEvents(@ModelAttribute("newEvent") Event event, Model model,
@SessionAttribute LocalDateTime visitTime) {
Event spring = new Event();
spring.setName("spring");
spring.setLimit(10);
List<Event> eventList = new ArrayList<Event>();
eventList.add(event);
eventList.add(spring);
model.addAttribute(eventList);
return "/events/list";
}
}
RedirectAttributes에 파라미터에 노출되고자 하는 값만(name) 넣어주면
아래 그림처럼 원하는 값만 파라미터로 붙게 된다.
그런데 RedirectAttributes로 전달한 값을 @RequestParam과 @ModelAttributes로 받을수 있는데
만약 컨트롤러에 @SessionAttributes가 설정되어 있다면 주의해야 할 점이 있다.
@ModelAttributes는 기본적으로 SessionAttributes가 있다면 Session을 뒤진다.
그런데 @GetMapping("/events/list") 핸들러에 들어오기전에 sessionStatus.setComplete(); 에서 비우게 된다.
그렇기 때문에 Error가 발생하게 된다.
이것을 해결하려면 SessionAttributes의 세션명과 다르게 사용하면 된다.
@ModelAttributes("newEvent") 이런식으로 ㅎㅎ
'Spring > SpringMVC' 카테고리의 다른 글
[Spring MVC] MultipartFile (0) | 2019.08.20 |
---|---|
[Spring MVC] Flash Attributes (0) | 2019.08.20 |
[Spring MVC] @SessionAttribute (0) | 2019.08.19 |
[Spring MVC] @SessionAttributes (0) | 2019.08.15 |
[Spring MVC] @Valid vs @Validated (1) | 2019.08.13 |