WebMvcConfigurationSupport 에서 SessionFlashMapManager 를 만든다
public FlashMapManager flashMapManager() {
return new SessionFlashMapManager();
}
DispatcherServlet에서 initFlashMapManager 한다
protected void initStrategies(ApplicationContext context) {
this.initMultipartResolver(context);
this.initLocaleResolver(context);
this.initThemeResolver(context);
this.initHandlerMappings(context);
this.initHandlerAdapters(context);
this.initHandlerExceptionResolvers(context);
this.initRequestToViewNameTranslator(context);
this.initViewResolvers(context);
this.initFlashMapManager(context);
}
flashMapManager 가 있는지
if (this.flashMapManager != null) {
FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate(request, response);
if (inputFlashMap != null) {
request.setAttribute(INPUT_FLASH_MAP_ATTRIBUTE, Collections.unmodifiableMap(inputFlashMap));
}
request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());
request.setAttribute(FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager);
}
flashMap 객체에 저장하기 위해 비어있는 객체를 만들고 flashMapManager 도 넣는다
request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());
request.setAttribute(FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager);
modelAndView 컨테이너에 input용 flashMap 객체를 담는다
mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request));
RedirectAttributesMethodArgumentResolver 에서
DataBinder dataBinder = binderFactory.createBinder(webRequest, (Object)null, "target");
redirectAttributes = new RedirectAttributesModelMap(dataBinder);
redirectAttributes 만들어서 전달
@GetMapping("/setFlash")
public String setFlash(RedirectAttributes redirectAttributes) {
redirectAttributes.addFlashAttribute("flashMessage", "이것은 1회성 플래시 메시지입니다.");
return "redirect:/getFlash";
}
이렇게 작업을 하면
ServletInvocableHandlerMethod에서 응답처리
this.returnValueHandlers.handleReturnValue(returnValue, this.getReturnValueType(returnValue), mavContainer, webRequest);
ViewNameMethodReturnValueHandler에서 redirect용인지 검사
public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
if (returnValue instanceof CharSequence) {
String viewName = returnValue.toString();
mavContainer.setViewName(viewName);
if (this.isRedirectViewName(viewName)) {
mavContainer.setRedirectModelScenario(true);
}
} else if (returnValue != null) {
String var10002 = returnType.getParameterType().getName();
throw new UnsupportedOperationException("Unexpected return type: " + var10002 + " in method: " + returnType.getMethod());
}
}
RequestMappingHandlerAdapter 에서
@Nullable
private ModelAndView getModelAndView(ModelAndViewContainer mavContainer, ModelFactory modelFactory, NativeWebRequest webRequest) throws Exception {
modelFactory.updateModel(webRequest, mavContainer);
if (mavContainer.isRequestHandled()) {
return null;
} else {
ModelMap model = mavContainer.getModel();
ModelAndView mav = new ModelAndView(mavContainer.getViewName(), model, mavContainer.getStatus());
if (!mavContainer.isViewReference()) {
mav.setView((View)mavContainer.getView());
}
if (model instanceof RedirectAttributes) {
RedirectAttributes redirectAttributes = (RedirectAttributes)model;
Map<String, ?> flashAttributes = redirectAttributes.getFlashAttributes();
HttpServletRequest request = (HttpServletRequest)webRequest.getNativeRequest(HttpServletRequest.class);
if (request != null) {
RequestContextUtils.getOutputFlashMap(request).putAll(flashAttributes);
}
}
return mav;
}
}