둘셋 개발!

[Spring] RedirectAttributes와 Model차이 (+ addAttribute, addFlashAttribute) 본문

SPRING

[Spring] RedirectAttributes와 Model차이 (+ addAttribute, addFlashAttribute)

23 2023. 8. 3. 21:19

우선 Model에 대해서 간단히 살펴보자.

(RedirectAttributes에 대해 궁금한 분들은 바로 아래로 넘어가 주세요)

 

Model은  Controller 메서드를 작성할 때 파리미터로 선언해주면 View로 데이터를 넘겨주기 위한 객체이다.

Servlet의 request.setAttribute() 와 비슷한 역할을 한다.

다음은 Model사용 예시이다.

 

ModelController.java

@GetMapping("/model")
public String modelTest(Model model){
    model.addAttribute("time", new java.util.Date());
    return "modelTest";
}

- 파라미터로 Model model을 선언해줌

- model은 hashMap형태를 가지고 있어서 key, value 형태로 담아줌

- key를 "time", value은 현재 시간 데이터를 담음

 

modelTest.html

<!DOCTYPE html>
<html lang="kr" xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Hello Hello</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<p th:text="${time}"></p>
</body>
</html>

 

 

결과

정상적으로 time파라미터에 정상적으로 현재 시간을 잘 담겼다.


그렇다면 RedirectAttributes은 어떨 때 쓰는 것일까?

RedirectAttributes는 리다이렉트할 때 데이터를 담아서 보내고자 할 때 사용한다.

리다이렉트는 새롭게 Get요청을 보내는 것이기 때문에 요청객체와 응답객체가 새로 생겨 Model에 값을 담아도 소멸된다.

따라서 리다이렉트할 때 데이터를 전달하고자 할 때 Model에 담으면 안된다.

 

다음은 실제 RedirectAttributes 코드이다.

public interface RedirectAttributes extends Model {

 	// ...
	@Override
	RedirectAttributes addAttribute(String attributeName, @Nullable Object attributeValue);

	RedirectAttributes addFlashAttribute(String attributeName, @Nullable Object attributeValue);

	// ...
}

여기서  중요 메서드를 살펴보면 Model과 같이 addAttritubute를 사용해서 key, value 값을 담을 수 있고, addFlashAttritue 또한 마찬가지이다.

 

이 두 메서드에는 데이터를 전달하는 방식에 차이가 있다.

- addAttribute는 url 파라미터를 통해 데이터를 전달
- addFlashAttritue는 세션에 데이터를 임시적으로 저장한다. (임시적으로 저장하기 때문에 Flash라는 단어가 붙었나보다)

(참고로 리다이렉트를 하면 요청객체와 응답객체를 새로 생성되지만 세션은 유지되기 때문에 RedirectAttributes은 이를 이용한다)

 


실제로 테스트를 진행했다.

1. (리다이렉트 시) Model에 데이터를 담는 예시

2. (리다이렉트 시) RedirectAttributes addAttribute메서드 사용

3. (리다이렉트 시) RedirectAttributes addFlashAttritue메서드 사용

 

 

1. 리다이렉트시 Model에 데이터를 담는 예시 (실패 버전)

ModelController.java

@GetMapping("/fail/redirect")
public String failRedirectAttributes(Model model) {
    model.addAttribute("id", 23); // 리다이렉트 전 model에 값을 담음
    return "redirect:/test/model";
}

@GetMapping("/model")
public String modelTest(Model model){
    model.addAttribute("time", new java.util.Date());
    return "modelTest";
}

 

modelTest.html

<!DOCTYPE html>
<html lang="kr" xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Hello Hello</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<p th:text="${time}"></p>
<p th:text="${id}"></p>
</body>
</html>

 

결과

(localhost:8080/test/fail/redirect 요청 후 리다이레트 결과)

id의 값은 온데간데없다.

 

 

 

2. 리다이렉트시 RedirectAttributes addAttribute메서드 사용

ModelController.java

@GetMapping("/success/redirect/v1")
public String successRedirectAttributes1(RedirectAttributes redirectAttributes) {
    redirectAttributes.addAttribute("id", 23);
    return "redirect:/test/model";
}

 

modelTest.html

<!DOCTYPE html>
<html lang="kr" xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Hello Hello</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<p th:text="${time}"></p>
</body>
</html>

 

결과

(localhost:8080/test/success/redirect/v1 요청 후 리다이레트 결과)

url의 파라미터로 값이 들어간 것을 확인할 수 있다. 

 

 

3. 리다이렉트시 RedirectAttributes addFlashAttritue메서드 사용

ModelController.java

@GetMapping("/success/redirect/v2")
public String successRedirectAttributes2(RedirectAttributes redirectAttributes) {
    redirectAttributes.addFlashAttribute("id", 23);
    return "redirect:/test/model";
}

@GetMapping("/model")
public String modelTest(Model model){
    model.addAttribute("time", new java.util.Date());
    return "modelTest";
}

 

modelTest.html

<!DOCTYPE html>
<html lang="kr" xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Hello Hello</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<p th:text="${time}"></p>
<p th:text="${id}"></p>
</body>
</html>

 

결과

(localhost:8080/test/success/redirect/v2 요청 후 리다이레트 결과)

다음과 같이 url 파라미터로 저장하는 것이 아니라 세션을 통해 임시적으로 값이 담겨 값이 보여진다.

 

세션에 임시적으로 값이 담기기 때문에 새로고침하면 바람처럼 사라진다.....

다음과 같이 새로고침을 눌렀더니 id값이 사라졌다.

 

 

나는 세션에 저장되었다고 하길래 세션에서 id값을 꺼내보려고 했다.

하지만 세션에서 id값이 null이 나왔다......!!

 더  찾아보니 공식문서에 '플래시 속성은 리다이렉트 전에 세션에서 즉시 제거한다' 라고 나와있었다.

나는 세션에 임시적으로만 저장된다는 것은 알고있었지만 삭제되는 시점을 잘 몰랐던 것이었다.

 

또한 FlashAttribute는 리다이렉션 후 해당 컨트롤러의 Model에 자동으로 담긴다고 나와있다.

그래서 위의 코드를 실행했을 때 값이 보였던 것이다.

 

로그를 한번 찍어봤다.

 

ModelController.java

@GetMapping("/model")
public String modelTest(Model model){
    String findId = (String) model.getAttribute("id");
    System.out.println("findId: "+ findId);                  // model에 담긴 id의 value 출력
    model.addAttribute("time", new java.util.Date());
    return "modelTest";
}

@GetMapping("/success/redirect/v2")
public String successRedirectAttributes2(RedirectAttributes redirectAttributes, HttpSession session) {
    redirectAttributes.addFlashAttribute("id", "23");
    return "redirect:/test/model";
}

 

로그 화면

23값이 나온 걸 볼 수 있다.

당연히 새로고침을 하면 사라지겠지만.


ref

https://brightmango.tistory.com/entry/Spring-%EB%A6%AC%EB%8B%A4%EC%9D%B4%EB%A0%89%ED%8A%B8-%EB%8F%99%EC%9E%91-%EC%9B%90%EB%A6%AC

https://lionpower.tistory.com/297

https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-controller/ann-methods/flash-attributes.html