Burninghering's Blog
article thumbnail

Redirect와 Forward 과정 비교

JSP를 가지고 비교를 한다

브라우저가 수동으로 요청을 한 뒤 300 Redirect 에러를 받고

브라우저가 자동으로 헤더를 읽어서 

새로운 곳으로 요청을 다시 한다.

(요청도 2번 응답도 2번)

 

forward

클라이언트가 요청을 한 뒤

write.jsp가 사용자가 요청한 내용을 그대로

login.jsp로 전달한다.

login.jsp가 요청을 받아 처리한 뒤 응답을 한다.(클라이언트로)

(요청도 1번 응답도 1번)

 

request가 모델 객체 역할을 한다.

login.jsp가 출력을 하는 뷰 역할을 한다.

write.jsp가 요청을 처리하는 컨트롤러 역할을 한다.

 

스프링이 이 forward를 통해 MVC를 구현하는 것이다.


RedirectView

클라이언트가 요청을 하면 디스패처 서블릿이 받고

이 요청을 처리할 수 있는 컨트롤러의 메소드를 호출한다.

유효성 검사를 통과 못해서 redirect를 한다면

컨트롤러가 redirect url을 주고,

디스패처 서블릿은 RedirectView로 그것을 전달하고

RedirectView가 응답헤더를 만들어 응답한다. 

클라이언트는 응답 헤더가 302번이므로

브라우저가 자동으로 Location URL로 자동 요청을 한다.  


JstlView

요청을 한 후 디스패처 서블릿이 받으면 해당 컨트롤러의 메소드를 호출한다.

뷰 이름을 디스패처 서블릿이 받아서 인터널리소스뷰리졸버에게 보낸다.

뷰 이름을 해석하고, /WEB-INF/views/registerForm.jsp로 해석하여 JstlView로 응답을 보내준다.

그럼 JstlView가 해당 jsp에 모델(데이터)를 넘겨준다.

registerForm.jsp가 데이터를 가지고 최종 응답을 만들어 응답을 해주게 되어있다.

JSTL(Jsp Standard Tag Library : JSP뷰를 처리하는 것)

 

스프링에는 다양한 뷰가 있는데, 우리가 jsp를 사용하고 있으므로

JSTL을 사용한다. 

 

경로

실습 사진 1

InternalResourceViewResolver가 DispatcherServlet으로부터 뷰 이름을 전달 받으면,

InternalResourceViewResolver가 접두사와 접미사를 붙여주는 것이다.


InternalResourceView

forward를 할 때 사용되는 것이다.

 

사용자가 요청을 하면 디스패처 서블릿이 받고 해당 컨트롤러의 메소드를 요청하는데

forward로 시작되는 문자열을 반환하고,

디스패처서블릿이 반환된 문자열을 보고 포워딩을 해야하는 것으로 인식하고 문자열을 InternalResourceView에게 전달한다.

InternalResourceView가 /register/add를 호출하라고 디스패처 서블릿한테 알려준다. 

요청한 것이 내부적으로 일어났으므로 forwarding이다.

포워딩은 InternalResourceView은 처리한다.

디스패처서블릿이 /register/add와 연결된 메소드를 호출한다.

 

메소드를 호출하면 "registerForm"이라는 문자열을 보고,

InternalResourceViewResolver한테 물어보고 응답받아서

해당 뷰를 JstlView에게 넘기고 

registerForm.jsp를 호출해서

응답한다.

 

 


Forward 예시

실습 사진2


Redirect 실습

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;
	}
}

실습 사진3

 

실습 사진4

요청을 save로 했는데

브라우저가 자동으로 url을 바꿔 add로 요청을 해주었다 


Forward 실습

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;
	}
}

실습 사진5

/register/add로 forward를 POST로 했는데

forward도 POST를 했는데

register/add에서는 GET밖에 처리하지 못하므로 에러가 난 것이다.

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만 처리할 수 있으므로...)

실습 사진 6

 

주석 처리

 

요청은 save인데

화면은 add이다

 

요청을 save로 하고 forward를 add로 한 것이다.

(redirect와 달리 forward는 요청이 한 번이다.)

실습 사진7


본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.

http://bit.ly/3Y34pE0

 

패스트캠퍼스 [직장인 실무교육]

프로그래밍, 영상편집, UX/UI, 마케팅, 데이터 분석, 엑셀강의, The RED, 국비지원, 기업교육, 서비스 제공.

fastcampus.co.kr

 

profile

Burninghering's Blog

@개발자 김혜린

안녕하세요! 반갑습니다.