웹 개발 패턴중 자주 쓰이는 패턴중 하나이다.
HTTP Post 요청에 대한 응답을 다른 URL로의 GET방식으로 Redirect하는 것이다.
첫번째로, Post 요청 처리시 새로고침으로 인해 동일한 요청이 연속적으로 보내지는 오류가 발생할 수 있다.
Post 요청을 처리할 때 , 변경이 일어나지 않는 로직이라면 상관 없지만, Post로 값을 받아 무언가를 변경하는 로직이 있다면 새로고침 했을 때 그 로직이 반복 실행되는 문제가 발생할 수 있다.
두번째로, Post 요청 처리 후 다른 페이지를 호출하는 경우 해당 페이지를 호출할때 필요한 파라미터들을 넘겨주지 않아서 문제가 발생할 수 있다.
이런 문제들을 해결하고자 Post요청에 대한 응답으로 다른 URL에 갈때,
GET 방식으로 redirect 하는 PRG 패턴을 사용한다.
success
뷰를 그대로 호출한다.새로고침 시 로직이 반복처리될 수 있고,
success
뷰를 호출하는데 파라미터가 필요하다면 오류가 발생할 수 있다.
@Controller
public class TestController{
@GetMapping
public String home(Model model){
//로직 처리 후 view에 memberList를 넘겨준다.
model.addAttribute("list" , memberList);
return "home";
}
@PostMapping("/add")
public String addMember(@ModelAttribute("member") Member member){
//멤버를 추가하는 로직을 실행 후 success페이지로 이동한다.
return "success";
}
}
success
뷰를 그대로 호출하는 대신, /success
로 redirect 한다.PostMapping 처리 후 뷰를 호출하는 것이 아닌, Get방식으로 /success
를 호출하는것이기 때문에
파라미터도 정상적으로 넘겨줄 수 있고, 새로고침시 오류도 발생하지 않는다.
@Controller
public class TestController{
@GetMapping
public String home(){
return "home";
}
@PostMapping("/add")
public String addMember(@ModelAttribute("member") Member member){
//멤버를 추가하는 로직을 실행 후 success페이지로 이동한다.
return "redirect:/success";
}
@GetMapping("/success")
public String success(Model model){
//view에 member객체를 넘겨준다.
model.addAttribute("member" , member);
}
}
redirect시 경로변수(PathVariable)이 필요한 페이지로 이동시키려면 어떻게 해야할까?
위의 예제를 조금 변형해보자.
만약 /success
가 아닌 /success/{memberId}
로 이동하고자 한다.
이때는 반환문에 해당 String을 추가해줄 수 있다.
@PostMapping("/add")
public String addMember(@ModelAttribute("member") Member member){
//멤버를 추가하는 로직을 실행
return "redirect:/success"+ member.getId();
}
RedirectAttributes
를 사용하면, PathVariable
과 QueryParameter
을아래와 같이 redirect에 여러 값을 담을 수 있다.
@PostMapping("/add")
public String addMember(@ModelAttribute("member") Member member,
RedirectAttributes redirectAttributes){
//멤버를 추가하는 로직을 실행
//memberId = "hello"
redirectAttributes.addAttribute("memberId" , member.getId());
redirectAttributes.addAttribute("add" , true);
return "redirect:/success/{memberId}";
}
/success/hello?add=true
반환문에 {memberId}
로 PathVariable 바인딩시 경로변수로 사용되고,
나머지는 쿼리 파라미터로 사용된다.