RedirectAttributes-FlashAttributes

tokkaiiii·2025년 5월 1일

spring-mvc

목록 보기
12/27

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;
    }
  }
profile
풀스택 자바 개발자입니다

0개의 댓글