/** * Return the list of return value handlers to use including built-in and * custom handlers provided via {@link #setReturnValueHandlers}. */ protected List<HandlerMethodReturnValueHandler> getDefaultReturnValueHandlers() { List<HandlerMethodReturnValueHandler> handlers = new ArrayList<>(); // Single-purpose return value types handlers.add(new ModelAndViewMethodReturnValueHandler()); handlers.add(new ModelMethodProcessor()); handlers.add(new ViewMethodReturnValueHandler()); handlers.add(new HttpEntityMethodProcessor( getMessageConverters(), this.contentNegotiationManager, this.responseBodyAdvice)); // Annotation-based return value types handlers.add(new ModelAttributeMethodProcessor(false)); handlers.add(new RequestResponseBodyMethodProcessor( getMessageConverters(), this.contentNegotiationManager, this.responseBodyAdvice)); // Multi-purpose return value types handlers.add(new ViewNameMethodReturnValueHandler()); handlers.add(new MapMethodProcessor()); // Custom return value types if (getCustomReturnValueHandlers() != null) { handlers.addAll(getCustomReturnValueHandlers()); } // Catch-all handlers.add(new ModelAttributeMethodProcessor(true)); return handlers; }
@Override 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 (isRedirectViewName(viewName)) { mavContainer.setRedirectModelScenario(true); } } else if (returnValue != null){ // should not happen throw new UnsupportedOperationException("Unexpected return type: " + returnType.getParameterType().getName() + " in method: " + returnType.getMethod()); } }
@Test public void returnViewCustomRedirect() throws Exception { ModelMap redirectModel = new RedirectAttributesModelMap(); this.mavContainer.setRedirectModel(redirectModel); this.handler.setRedirectPatterns("myRedirect:*"); this.handler.handleReturnValue("myRedirect:testView", this.param, this.mavContainer, this.webRequest); assertEquals("myRedirect:testView", this.mavContainer.getViewName()); assertSame(redirectModel, this.mavContainer.getModel()); }
@Test public void returnViewName() throws Exception { this.handler.handleReturnValue("testView", this.param, this.mavContainer, this.webRequest); assertEquals("testView", this.mavContainer.getViewName()); }
@Test public void supportsReturnType() throws Exception { assertTrue(this.handler.supportsReturnType(this.param)); }
@Test public void returnViewNameRedirect() throws Exception { ModelMap redirectModel = new RedirectAttributesModelMap(); this.mavContainer.setRedirectModel(redirectModel); this.handler.handleReturnValue("redirect:testView", this.param, this.mavContainer, this.webRequest); assertEquals("redirect:testView", this.mavContainer.getViewName()); assertSame(redirectModel, this.mavContainer.getModel()); }
handlers.add(new ViewNameMethodReturnValueHandler()); handlers.add(new MapMethodProcessor());
@Override 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 (isRedirectViewName(viewName)) { mavContainer.setRedirectModelScenario(true); } } else if (returnValue != null){ // should not happen throw new UnsupportedOperationException("Unexpected return type: " + returnType.getParameterType().getName() + " in method: " + returnType.getMethod()); } }
@Test public void returnViewRedirectWithCustomRedirectPattern() throws Exception { ModelMap redirectModel = new RedirectAttributesModelMap(); this.mavContainer.setRedirectModel(redirectModel); this.handler.setRedirectPatterns("myRedirect:*"); this.handler.handleReturnValue("redirect:testView", this.param, this.mavContainer, this.webRequest); assertEquals("redirect:testView", this.mavContainer.getViewName()); assertSame(redirectModel, this.mavContainer.getModel()); }
/** * Return the list of return value handlers to use including built-in and * custom handlers provided via {@link #setReturnValueHandlers}. */ protected List<HandlerMethodReturnValueHandler> getDefaultReturnValueHandlers() { List<HandlerMethodReturnValueHandler> handlers = new ArrayList<>(); // Single-purpose return value types handlers.add(new ModelAndViewMethodReturnValueHandler()); handlers.add(new ModelMethodProcessor()); handlers.add(new ViewMethodReturnValueHandler()); handlers.add(new HttpEntityMethodProcessor( getMessageConverters(), this.contentNegotiationManager, this.responseBodyAdvice)); // Annotation-based return value types handlers.add(new ModelAttributeMethodProcessor(false)); handlers.add(new RequestResponseBodyMethodProcessor( getMessageConverters(), this.contentNegotiationManager, this.responseBodyAdvice)); // Multi-purpose return value types handlers.add(new ViewNameMethodReturnValueHandler()); handlers.add(new MapMethodProcessor()); // Custom return value types if (getCustomReturnValueHandlers() != null) { handlers.addAll(getCustomReturnValueHandlers()); } // Catch-all handlers.add(new ModelAttributeMethodProcessor(true)); return handlers; }
@Override public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception { if (returnValue instanceof CharSequence) { String viewName = returnValue.toString(); mavContainer.setViewName(viewName); if (isRedirectViewName(viewName)) { mavContainer.setRedirectModelScenario(true); } } else if (returnValue != null){ // should not happen throw new UnsupportedOperationException("Unexpected return type: " + returnType.getParameterType().getName() + " in method: " + returnType.getMethod()); } }
@Before public void setup() throws NoSuchMethodException { this.handler = new ViewNameMethodReturnValueHandler(); this.mavContainer = new ModelAndViewContainer(); this.webRequest = new ServletWebRequest(new MockHttpServletRequest()); this.param = new MethodParameter(getClass().getDeclaredMethod("viewName"), -1); }
@Test public void setCustomReturnValueHandlers() { HandlerMethodReturnValueHandler handler = new ViewNameMethodReturnValueHandler(); this.handlerAdapter.setCustomReturnValueHandlers(Collections.singletonList(handler)); this.handlerAdapter.afterPropertiesSet(); assertTrue(this.handlerAdapter.getReturnValueHandlers().contains(handler)); assertMethodProcessorCount(RESOLVER_COUNT, INIT_BINDER_RESOLVER_COUNT, HANDLER_COUNT + 1); }
@Test public void setCustomReturnValueHandlers() { HandlerMethodReturnValueHandler handler = new ViewNameMethodReturnValueHandler(); this.resolver.setCustomReturnValueHandlers(Collections.singletonList(handler)); this.resolver.afterPropertiesSet(); assertTrue(this.resolver.getReturnValueHandlers().getHandlers().contains(handler)); assertMethodProcessorCount(RESOLVER_COUNT, HANDLER_COUNT + 1); }
handlers.add(new ViewNameMethodReturnValueHandler()); handlers.add(new MapMethodProcessor());
@Test public void setAlwaysUseRedirectAttributes() throws Exception { HandlerMethodArgumentResolver redirectAttributesResolver = new RedirectAttributesMethodArgumentResolver(); HandlerMethodArgumentResolver modelResolver = new ModelMethodProcessor(); HandlerMethodReturnValueHandler viewHandler = new ViewNameMethodReturnValueHandler(); this.handlerAdapter.setArgumentResolvers(Arrays.asList(redirectAttributesResolver, modelResolver)); this.handlerAdapter.setReturnValueHandlers(Collections.singletonList(viewHandler)); this.handlerAdapter.setIgnoreDefaultModelOnRedirect(true); this.handlerAdapter.afterPropertiesSet(); this.request.setAttribute(DispatcherServlet.OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap()); HandlerMethod handlerMethod = handlerMethod(new RedirectAttributeController(), "handle", Model.class); ModelAndView mav = this.handlerAdapter.handle(request, response, handlerMethod); assertTrue("Without RedirectAttributes arg, model should be empty", mav.getModel().isEmpty()); }
@Test public void invokeAndHandle_DynamicReturnValue() throws Exception { this.argumentResolvers.addResolver(new RequestParamMethodArgumentResolver(null, false)); this.returnValueHandlers.addHandler(new ViewMethodReturnValueHandler()); this.returnValueHandlers.addHandler(new ViewNameMethodReturnValueHandler()); // Invoke without a request parameter (String return value) ServletInvocableHandlerMethod handlerMethod = getHandlerMethod(new Handler(), "dynamicReturnValue", String.class); handlerMethod.invokeAndHandle(this.webRequest, this.mavContainer); assertNotNull(this.mavContainer.getView()); assertEquals(RedirectView.class, this.mavContainer.getView().getClass()); // Invoke with a request parameter (RedirectView return value) this.request.setParameter("param", "value"); handlerMethod.invokeAndHandle(this.webRequest, this.mavContainer); assertEquals("view", this.mavContainer.getViewName()); }
handlers.add(new ViewNameMethodReturnValueHandler()); handlers.add(new MapMethodProcessor());
/** * Return the list of return value handlers to use including built-in and * custom handlers provided via {@link #setReturnValueHandlers}. */ protected List<HandlerMethodReturnValueHandler> getDefaultReturnValueHandlers() { List<HandlerMethodReturnValueHandler> handlers = new ArrayList<HandlerMethodReturnValueHandler>(); // Single-purpose return value types handlers.add(new ModelAndViewMethodReturnValueHandler()); handlers.add(new ModelMethodProcessor()); handlers.add(new ViewMethodReturnValueHandler()); handlers.add(new HttpEntityMethodProcessor( getMessageConverters(), this.contentNegotiationManager, this.responseBodyAdvice)); // Annotation-based return value types handlers.add(new ModelAttributeMethodProcessor(false)); handlers.add(new RequestResponseBodyMethodProcessor( getMessageConverters(), this.contentNegotiationManager, this.responseBodyAdvice)); // Multi-purpose return value types handlers.add(new ViewNameMethodReturnValueHandler()); handlers.add(new MapMethodProcessor()); // Custom return value types if (getCustomReturnValueHandlers() != null) { handlers.addAll(getCustomReturnValueHandlers()); } // Catch-all handlers.add(new ModelAttributeMethodProcessor(true)); return handlers; }
handlers.add(new ViewNameMethodReturnValueHandler()); handlers.add(new MapMethodProcessor());