본문으로 바로가기

[Spring MVC] RedirectAttributes

category Spring/SpringMVC 2019. 8. 19. 22:17

RedirectAttributes

: 리다이렉트 할 때 기본적으로 Model에 들어있는 primitive type 데이터는 URI 쿼리 매개변수에 추가된다.

  - 스프링 부트에서 이 기능이 기본적으로 비활성화 되어 있다

  - spring.mvc.ignore-default-model-on-redirect=false 프로퍼티를 사용해서 활성화 할 수 있다.

 

원하는 값만 리다이렉트 할 때 전달하고 싶다면 RedirectAttributes에 명시적으로 추가할 수 있다.

 

리다이렉트 요청을 처리하는 곳에서 쿼리 매개변수를 @RequestParam 또는 @ModelAttribute로 받을 수 있다.

 

package com.example.demo;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpSession;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttribute;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

@Controller
@SessionAttributes("event")
public class SampleController {
	
	@GetMapping("/events/form/name")
	public String eventFormName(Model model) {
		model.addAttribute("event",new Event());
		return "/events/form-name";
	}

	@PostMapping("/events/form/name")
	public String eventsFromNameSubmit(@Validated @ModelAttribute Event event
			,BindingResult bindingResult) {
		if(bindingResult.hasErrors()) {
			return "/events/form-name";
		}
		
		return "redirect:/events/form/limit";
	}
	
	@GetMapping("/events/form/limit")
	public String eventFormLimit(@ModelAttribute Event event , Model model) {
		model.addAttribute("event",event);
		return "/events/form-limit";
	}

	@PostMapping("/events/form/limit")
	public String createEvent(@Validated @ModelAttribute Event event
			,BindingResult bindingResult
			,SessionStatus sessionStatus
			,Model model) {
		if(bindingResult.hasErrors()) {
			return "/events/form-limit";
		}
		sessionStatus.setComplete();
		model.addAttribute("name",event.getName());
		model.addAttribute("limit",event.getLimit());
		return "redirect:/events/list";
	}
		
	
	@GetMapping("/events/list")
	public String getEvents(@RequestParam String name,
							@RequestParam Integer limit,
			                Model model , 
			                @SessionAttribute LocalDateTime visitTime) {
		
		Event newEvent = new Event();
		newEvent.setName(name);
		newEvent.setLimit(limit);
		
		Event event = new Event();
		event.setName("spring");
		event.setLimit(10);
		
		
		List<Event> eventList = new ArrayList<Event>();
		eventList.add(event);
		eventList.add(newEvent);
		model.addAttribute(eventList);
		
		return "/events/list";
	}
	
}

 

=> model에 primitive 데이터를 담은 다음 redirect를 하게 되면 쿼리문에

     model의 데이터들이 parameter로 들어가게 된다.

 

     

 

그래서 parameter로 노출시키고 싶은것만 RedirectAttributes 객체를 사용하여 전달한다.

 

package com.example.demo;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpSession;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttribute;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

@Controller
@SessionAttributes("event")
public class SampleController {

	@GetMapping("/events/form/name")
	public String eventFormName(Model model) {
		model.addAttribute("event", new Event());
		return "/events/form-name";
	}

	@PostMapping("/events/form/name")
	public String eventsFromNameSubmit(@Validated @ModelAttribute Event event, BindingResult bindingResult) {
		if (bindingResult.hasErrors()) {
			return "/events/form-name";
		}

		return "redirect:/events/form/limit";
	}

	@GetMapping("/events/form/limit")
	public String eventFormLimit(@ModelAttribute Event event, Model model) {
		model.addAttribute("event", event);
		return "/events/form-limit";
	}

	@PostMapping("/events/form/limit")
	public String createEvent(@Validated @ModelAttribute Event event, BindingResult bindingResult,
			SessionStatus sessionStatus, RedirectAttributes attributes) {
		if (bindingResult.hasErrors()) {
			return "/events/form-limit";
		}
		sessionStatus.setComplete();
		attributes.addAttribute("name", event.getName());
		return "redirect:/events/list";
	}

	@GetMapping("/events/list")
	public String getEvents(@ModelAttribute("newEvent") Event event, Model model,
			@SessionAttribute LocalDateTime visitTime) {

		Event spring = new Event();
		spring.setName("spring");
		spring.setLimit(10);

		List<Event> eventList = new ArrayList<Event>();
		eventList.add(event);
		eventList.add(spring);
		model.addAttribute(eventList);

		return "/events/list";
	}

}

 

RedirectAttributes에 파라미터에 노출되고자 하는 값만(name) 넣어주면

아래 그림처럼 원하는 값만 파라미터로 붙게 된다.

 

 

그런데 RedirectAttributes로 전달한 값을 @RequestParam과 @ModelAttributes로 받을수 있는데

만약 컨트롤러에 @SessionAttributes가 설정되어 있다면 주의해야 할 점이 있다.

 

@ModelAttributes는 기본적으로 SessionAttributes가 있다면 Session을 뒤진다.

그런데 @GetMapping("/events/list") 핸들러에 들어오기전에 sessionStatus.setComplete(); 에서 비우게 된다.

그렇기 때문에 Error가 발생하게 된다.

이것을 해결하려면 SessionAttributes의 세션명과 다르게 사용하면 된다.

@ModelAttributes("newEvent") 이런식으로 ㅎㅎ

 

'Spring > SpringMVC' 카테고리의 다른 글

[Spring MVC] MultipartFile  (0) 2019.08.20
[Spring MVC] Flash Attributes  (0) 2019.08.20
[Spring MVC] @SessionAttribute  (0) 2019.08.19
[Spring MVC] @SessionAttributes  (0) 2019.08.15
[Spring MVC] @Valid vs @Validated  (1) 2019.08.13