PRG 패턴 (Post-Redirect-Get)
웹 개발 패턴 중 자주 쓰이는 패턴 중 하나이다.
HTTP Post 요청에 대한 응답을 다른 URL로의 GET방식으로 Redirect 하는 것이다.
PRG 패턴을 사용하지 않을 때 발생하는 문제
첫 번째로, Post 요청 처리 시 새로고침으로 인해 동일한 요청이 연속적으로 보내지는 오류가 발생할 수 있다.
Post 요청을 처리할 때, 변경이 일어나지 않는 로직이라면 상관없지만, Post로 값을 받아 무언가를 변경하는 로직이 있다면 새로고침 했을 때 그 로직이 반복 실행되는 문제가 발생할 수 있다.
두 번째로, Post 요청 처리 후 다른 페이지를 호출하는 경우 해당 페이지를 호출할 때 필요한 파라미터들을 넘겨주지 않아서 문제가 발생할 수 있다.
이런 문제들을 해결하고자 Post요청에 대한 응답으로 다른 URL에 갈 때,
GET 방식으로 redirect 하는 PRG 패턴을 사용한다.
PRG 패턴 적용
PRG 패턴 적용 전
- PostMapping 로직 처리 후
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";
}
}
PRG 패턴 적용 후
- PostMapping 로직 처리 후
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);
}
}
RedirectAttributes
redirect시 경로변수(PathVariable)가 필요한 페이지로 이동시키려면 어떻게 해야 할까?
(잘못된 예시)
위의 예제를 조금 변형해 보자.
만약 /success가 아닌 /success/{memberId}로 이동하고자 한다.
이때는 반환문에 해당 String을 추가해 줄 수 있다.
@PostMapping("/add")
public String addMember(@ModelAttribute("member") Member member){
//멤버를 추가하는 로직을 실행
return "redirect:/success/"+ member.getId();
}
위와 같이 URL에 변수를 더해서 사용하면 URL 인코딩이 되지 않기 때문에 위험하다.
이때, RedirectAttributes를 사용하면, PathVariable과 QueryParameter을 redirect URL에 담을 수 있다.
redirectAttributes.addAttribute() 사용
아래와 같이 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
반환문에 PathVariable 바인딩 시 경로변수로 사용된다. ex) {memberId}
나머지는 쿼리 파라미터로 사용된다. ex) add=true
'JAVA & Spring > Spring' 카테고리의 다른 글
[Spring / Transaction] 트랜잭션 실제 적용되고 있는지 확인하는 방법 (0) | 2023.05.17 |
---|---|
[Spring] 세션, 쿠키, @SessionAttribute 로그인 확인 (0) | 2023.04.21 |
[Spring Boot] @PathVariable과 @RequestParam - 파라미터 받기 (0) | 2023.04.21 |
[Spring Boot] 스프링 인터셉터 (Spring Interceptor) (0) | 2023.04.21 |
[Spring] Bean Validation (0) | 2023.04.21 |