1. Redirect와 Forward 과정 비교
JSP를 가지고 비교를 한다
브라우저가 수동으로 요청을 한 뒤 300 Redirect 에러를 받고
브라우저가 자동으로 헤더를 읽어서
새로운 곳으로 요청을 다시 한다.
(요청도 2번 응답도 2번)
forward
클라이언트가 요청을 한 뒤
write.jsp가 사용자가 요청한 내용을 그대로
login.jsp로 전달한다.
login.jsp가 요청을 받아 처리한 뒤 응답을 한다.(클라이언트로)
(요청도 1번 응답도 1번)
request가 모델 객체 역할을 한다.
login.jsp가 출력을 하는 뷰 역할을 한다.
write.jsp가 요청을 처리하는 컨트롤러 역할을 한다.
스프링이 이 forward를 통해 MVC를 구현하는 것이다.

2. RedirectView
클라이언트가 요청을 하면 디스패처 서블릿이 받고
이 요청을 처리할 수 있는 컨트롤러의 메소드를 호출한다.
유효성 검사를 통과 못해서 redirect를 한다면
컨트롤러가 redirect url을 주고,
디스패처 서블릿은 RedirectView로 그것을 전달하고
RedirectView가 응답헤더를 만들어 응답한다.
클라이언트는 응답 헤더가 302번이므로
브라우저가 자동으로 Location URL로 자동 요청을 한다.

3. JstlView
요청을 한 후 디스패처 서블릿이 받으면 해당 컨트롤러의 메소드를 호출한다.
뷰 이름을 디스패처 서블릿이 받아서 인터널리소스뷰리졸버에게 보낸다.
뷰 이름을 해석하고, /WEB-INF/views/registerForm.jsp로 해석하여 JstlView로 응답을 보내준다.
그럼 JstlView가 해당 jsp에 모델(데이터)를 넘겨준다.
registerForm.jsp가 데이터를 가지고 최종 응답을 만들어 응답을 해주게 되어있다.
JSTL(Jsp Standard Tag Library : JSP뷰를 처리하는 것)
스프링에는 다양한 뷰가 있는데, 우리가 jsp를 사용하고 있으므로
JSTL을 사용한다.

경로


InternalResourceViewResolver가 DispatcherServlet으로부터 뷰 이름을 전달 받으면,
InternalResourceViewResolver가 접두사와 접미사를 붙여주는 것이다.
4. InternalResourceView
forward를 할 때 사용되는 것이다.
사용자가 요청을 하면 디스패처 서블릿이 받고 해당 컨트롤러의 메소드를 요청하는데
forward로 시작되는 문자열을 반환하고,
디스패처서블릿이 반환된 문자열을 보고 포워딩을 해야하는 것으로 인식하고 문자열을 InternalResourceView에게 전달한다.
InternalResourceView가 /register/add를 호출하라고 디스패처 서블릿한테 알려준다.
요청한 것이 내부적으로 일어났으므로 forwarding이다.
포워딩은 InternalResourceView은 처리한다.
디스패처서블릿이 /register/add와 연결된 메소드를 호출한다.
메소드를 호출하면 "registerForm"이라는 문자열을 보고,
InternalResourceViewResolver한테 물어보고 응답받아서
해당 뷰를 JstlView에게 넘기고
registerForm.jsp를 호출해서
응답한다.


5. Forward 예시

6. Redirect 실습
<java />
package com.fastcampus.ch2;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class RegisterController {
// @RequestMapping("/register/save", method={RequestMethod.POST,RequestMethod.GET}) //POST와 GET방식 둘 다 가능하도록 배열에 넣음
// @RequestMapping("/register/add") //신규회원 가입 화면
// @GetMapping("/register/add")
// public String register() {
// return "registerForm"; //WEB-INF/views/registerForm.jsp
// }
// @RequestMapping("/register/save", method=RequestMethod.POST)
@PostMapping("/register/save")
public String save(User user,Model m) throws Exception {
//1. 유효성 검사
if(!isValid(user)) {
String msg =URLEncoder.encode("id를 잘못입력하셨습니다.","utf-8"); // -> 예외 처리 필요
//유효하지 않으면 다시 회원가입 화면으로
// return "redirect:/register/add?msg="+msg; //URL 재작성 (rewriting) -> redirect에 msg를 전달해줌
m.addAttribute("msg",msg);
return "redirect:/register/add";
}
//유효하면 회원 정보 화면 보여주기
return "registerInfo";
}
private boolean isValid(User user) {
return false;
}
}


요청을 save로 했는데
브라우저가 자동으로 url을 바꿔 add로 요청을 해주었다
7. Forward 실습
<java />
package com.fastcampus.ch2;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class RegisterController {
// @RequestMapping("/register/save", method={RequestMethod.POST,RequestMethod.GET}) //POST와 GET방식 둘 다 가능하도록 배열에 넣음
// @RequestMapping("/register/add") //신규회원 가입 화면
// @GetMapping("/register/add")
// public String register() {
// return "registerForm"; //WEB-INF/views/registerForm.jsp
// }
// @RequestMapping("/register/save", method=RequestMethod.POST)
@PostMapping("/register/save")
public String save(User user,Model m) throws Exception {
//1. 유효성 검사
if(!isValid(user)) {
String msg =URLEncoder.encode("id를 잘못입력하셨습니다.","utf-8"); // -> 예외 처리 필요
//유효하지 않으면 다시 회원가입 화면으로
// return "redirect:/register/add?msg="+msg; //URL 재작성 (rewriting) -> redirect에 msg를 전달해줌
m.addAttribute("msg",msg);
return "forward:/register/add";
}
//유효하면 회원 정보 화면 보여주기
return "registerInfo";
}
private boolean isValid(User user) {
return false;
}
}

/register/add로 forward를 POST로 했는데
forward도 POST를 했는데
register/add에서는 GET밖에 처리하지 못하므로 에러가 난 것이다.
<java />
package com.fastcampus.ch2;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
public class RegisterController {
@RequestMapping(value="/register/add", method={RequestMethod.GET, RequestMethod.POST}) //POST와 GET방식 둘 다 가능하도록 배열에 넣음
public String register() {
return "registerForm"; //WEB-INF/views/registerForm.jsp
}
// @RequestMapping("/register/save", method=RequestMethod.POST)
@PostMapping("/register/save")
public String save(User user,Model m) throws Exception {
//1. 유효성 검사
if(!isValid(user)) {
String msg =URLEncoder.encode("id를 잘못입력하셨습니다.","utf-8"); // -> 예외 처리 필요
//유효하지 않으면 다시 회원가입 화면으로
// return "redirect:/register/add?msg="+msg; //URL 재작성 (rewriting) -> redirect에 msg를 전달해줌
m.addAttribute("msg",msg);
return "forward:/register/add";
}
//유효하면 회원 정보 화면 보여주기
return "registerInfo";
}
private boolean isValid(User user) {
return false;
}
}
코드를 고쳐준 뒤
뷰 컨트롤러를 삭제한다. (GET만 처리할 수 있으므로...)



요청은 save인데

화면은 add이다
요청을 save로 하고 forward를 add로 한 것이다.
(redirect와 달리 forward는 요청이 한 번이다.)

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.
패스트캠퍼스 [직장인 실무교육]
프로그래밍, 영상편집, UX/UI, 마케팅, 데이터 분석, 엑셀강의, The RED, 국비지원, 기업교육, 서비스 제공.
fastcampus.co.kr
'패캠 챌린지' 카테고리의 다른 글
패스트캠퍼스 챌린지 - 19일차 [스프링의 정석:남궁성과 끝까지 간다] (0) | 2023.03.10 |
---|---|
패스트캠퍼스 챌린지 - 18일차 [스프링의 정석:남궁성과 끝까지 간다] (2) | 2023.03.09 |
패스트캠퍼스 챌린지 - 16일차 [스프링의 정석:남궁성과 끝까지 간다] (0) | 2023.03.07 |
패스트캠퍼스 챌린지 - 15일차 [스프링의 정석:남궁성과 끝까지 간다] (0) | 2023.03.06 |
패스트캠퍼스 챌린지 - 14일차 [스프링의 정석:남궁성과 끝까지 간다] (0) | 2023.03.05 |