1. redirect와 forward의 처리 과정 비교
* redirect

1) 브라우저를 통해 클라이언트가 /ch2/write.jsp라는 요청을 했을 때 그 요청이 담긴 request 객체가 생성된다.
-> '수동요청, GET or POST 원하는 방식'
2) 객체가 전달이 되었는데 write.jsp가 봤더니 로그인을 안한 상태! -> login.jsp로 요청하라고 응답해주게 된다.
(3xx 은 redirect - 다른 곳으로 재요청)
3) 브라우저가 해당 응답을 받고 /ch2/login.jsp로 다시 요청을 수행한다. 새로운 요청이 담긴 request 객체가 만들어지고,
이게 login.jsp로 전달된다. (1번의 request 객체와는 서로 다른 객체) -> '브라우저가 자동 요청, GET방식'
4) login.jsp가 다시 응답해준다.
: redirect는 2번 요청, 2번 응답을 하게 된다.
EX) 카드 잃어버림
-> 전화했는데 '한도 조회'부서가 받음. (요청1)
-> '카드 분실' 부서가 처리해야 하는 쪽이라 '카드 분실'부서 번호 알려줌(응답1)
-> 해당 부서로 다시 전화(요청2)
-> '카드 분실' 부서가 응답(응답2)
* forward

1) 요청을 하면 request를 생성하여 해당 요청을 write.jsp가 받는다.
2) write.jsp가 요청을 다른 프로그램 encode.jsp로 전달해준다. (위 request와 같은 것)
3) encode.jsp 프로그램이 응답해준다.
실제로는 encode.jsp가 처리를 하더라도 이걸 브라우저는 알지 못한다.
요청한 write.jsp가 처리한 줄 알기 때문에 URL도 바뀌지 않는다.
: forward는 1번 요청, 1번 응답을 하게 된다.
write.jsp가 아무일도 안할 수 있지만, 일부 작업만 수행하고 나머지는 encode.jsp가 처리하는 서로 협력하는 방식으로도
처리할 수 있다. write.jsp가 처리한 결과를 request 객체에 저장할 수 있는데, 저장하면 그게 그대로 전달된다.
이걸 encode.jsp에서 저장된 결과를 읽어서 사용할 수 있다.
세션이나 애플리케이션 같은 다른 다른 저장공간에 저장하는 것보다 request는 서로 관련된 요청을 한 번 처리하고 나면
없어지기 때문에 나중에 삭제해줘야 하는 문제와 서버에 대한 부담을 줄일 수 있다.
EX) 카드 잃어버림
-> 전화했는데 '한도 조회'부서가 받음. (요청1)
-> '한도 조회'부서가 '카드 분실' 부서로 바로 '요청1'을 넘겨줌
-> 전화는 '한도 조회' 부서가 받고 있지만, '카드 분실' 부서가 요청을 처리해줌. (응답1)
고객은 '한도 조회' 부서로 전화했기 때문에 이쪽에서 처리한 줄 알고, '카드 분실'쪽에서 처리한줄은 모르고
응답을 받게 된다.(똑같은 요청을 2번하지 않기 때문에 고객이 더 편하다!)
2. RedirectView

- Spring에서는 RedirectView를 이용해서 redirect를 처리한다.
1) 처음 요청을 /ch2/register/save을 요청
2) DispatcherServlet이 받아서 해당 컨트롤러로 보냄
3) 컨트롤러에서 회원 가입할 때 입력할 내용을 체크했는데 아이디를 잘못 입력했다면,
redirect를 사용해서 재요청할 URL을 적어준다.
@PostMapping("/register/save")
public String save(User user, Model m) throws Exception {
if(!isValid(user)) {
String msg = URLEncoder.encode("id를 잘못입력하셨습니다.", "utf-8");
m.addAttribute("msg", msg);
return "redirect:/register/add";
}
4) 컨트롤러가 반환한 redirect:/register/add가 DispatcherServlet에 전달된다.
5) DispatcherServlet이 redirect해야 한다는 것을 알고 RedirectView에게 보내준다.
6) RedirectView가 응답을 만들어준다.
7) 이 응답이 가면 브라우저가 자동으로 해당 Location으로 재요청을 한다.
3. forward의 예시

@RequestMapping("/download")
public String download(HttpServletRequest request,
@RequestParam(required=false, defaultValue="") String type) {
List<User> userList = getUserList();
request.setAttribute("data", userList); // request에 저장하면, forward된 곳에서 사용가능
if(type.equals("pdf")) {
return "forward:/pdfView";
} else if(type.equals("csv")) {
return "forward:/csvView";
}
return "forward:/txtView";
}
컨트롤러가 userList를 request 객체에 저장하고, 이 객체가 pdfView에게 전달.
pdfView에서는 컨트롤러가 조회해서 준 userList를 가지고 pdfView를 만들어준다.
요청을 전달하는 것이기 때문에 request에 userList를 저장해도 pdfView한테 전달이 되는 것이다. -> forward 사
(redirect는 서로 다른 request이기 때문에 이렇게 할 수 없다.)
Ex) 은행 1년치 거래내역 -> 조회 누르니 목록이 나옴 -> 저장 버튼이 종류별로 나옴(엑셀, csv, pdf)
-> /download?type=pdf로 주면 타입이 일치하니 pdfView를 처리하는 프로그램으로 전달한다.
4. HTTP 요청과 요청 방법
- HTTP 요청과 요청 방법 요약 정리
1) URL 직접 입력으로 요청(GET)

2) 링크 <a>로 요청(GET)

3) 폼<form>으로 요청(GET, POST)

GET일때는 ?year=2020 이런식으로 문자열이 URL뒤에 만들어질 것이고, POST일 때는 여기 안붙고 Body에 들어간다.
4) redirect - 다른 URL로 이동(GET). 자동 재요청. 브라우저 URL변경됨. (요청 2번, 응답 2번)
5) forward - 요청(GET, POST)을 다른 URL로 전달. 브라우저 URL변경 안됨.
'SpringBoot' 카테고리의 다른 글
| ch2 16. thymeleaf 사용하기 (0) | 2023.07.18 |
|---|---|
| ch2 15. forward와 redirect - 실습 (0) | 2023.07.14 |
| ch2 13. filter와 interceptor (0) | 2023.07.07 |
| ch2 12. Thymeleaf로 레이아웃 적용하기 (0) | 2023.07.07 |
| ch2 11. @RequestMapping과 URL인코딩 (0) | 2023.07.07 |