Browse Source

Add HttpStatus to ModelAndView

Issue: SPR-13560
pull/955/merge
Rossen Stoyanchev 9 years ago
parent
commit
a5f4aa6824
  1. 21
      spring-web/src/main/java/org/springframework/web/method/support/ModelAndViewContainer.java
  2. 5
      spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java
  3. 40
      spring-webmvc/src/main/java/org/springframework/web/servlet/ModelAndView.java
  4. 3
      spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ModelAndViewMethodReturnValueHandler.java
  5. 4
      spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapter.java
  6. 23
      spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ServletAnnotationControllerHandlerMethodTests.java

21
spring-web/src/main/java/org/springframework/web/method/support/ModelAndViewContainer.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -18,6 +18,7 @@ package org.springframework.web.method.support; @@ -18,6 +18,7 @@ package org.springframework.web.method.support;
import java.util.Map;
import org.springframework.http.HttpStatus;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.validation.support.BindingAwareModelMap;
@ -54,6 +55,8 @@ public class ModelAndViewContainer { @@ -54,6 +55,8 @@ public class ModelAndViewContainer {
private boolean redirectModelScenario = false;
private HttpStatus status;
private final SessionStatus sessionStatus = new SimpleSessionStatus();
private boolean requestHandled = false;
@ -176,6 +179,22 @@ public class ModelAndViewContainer { @@ -176,6 +179,22 @@ public class ModelAndViewContainer {
return this.sessionStatus;
}
/**
* Provide a HTTP status that will be passed on to with the
* {@code ModelAndView} used for view rendering purposes.
* @since 4.3
*/
public void setStatus(HttpStatus status) {
this.status = status;
}
/**
* Return the configured HTTP status, if any.
*/
public HttpStatus getStatus() {
return this.status;
}
/**
* Whether the request has been handled fully within the handler, e.g.
* {@code @ResponseBody} method, and therefore view resolution is not

5
spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -1240,6 +1240,9 @@ public class DispatcherServlet extends FrameworkServlet { @@ -1240,6 +1240,9 @@ public class DispatcherServlet extends FrameworkServlet {
logger.debug("Rendering view [" + view + "] in DispatcherServlet with name '" + getServletName() + "'");
}
try {
if (mv.getStatus() != null) {
response.setStatus(mv.getStatus().value());
}
view.render(mv.getModelInternal(), request, response);
}
catch (Exception ex) {

40
spring-webmvc/src/main/java/org/springframework/web/servlet/ModelAndView.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -18,6 +18,7 @@ package org.springframework.web.servlet; @@ -18,6 +18,7 @@ package org.springframework.web.servlet;
import java.util.Map;
import org.springframework.http.HttpStatus;
import org.springframework.ui.ModelMap;
import org.springframework.util.CollectionUtils;
@ -36,6 +37,7 @@ import org.springframework.util.CollectionUtils; @@ -36,6 +37,7 @@ import org.springframework.util.CollectionUtils;
* @author Rod Johnson
* @author Juergen Hoeller
* @author Rob Harrop
* @author Rossen Stoyanchev
* @see DispatcherServlet
* @see ViewResolver
* @see HandlerAdapter#handle
@ -49,6 +51,9 @@ public class ModelAndView { @@ -49,6 +51,9 @@ public class ModelAndView {
/** Model Map */
private ModelMap model;
/** Optional status for the response */
private HttpStatus status;
/** Indicates whether or not this instance has been cleared with a call to {@link #clear()} */
private boolean cleared = false;
@ -115,6 +120,24 @@ public class ModelAndView { @@ -115,6 +120,24 @@ public class ModelAndView {
}
}
/**
* Creates new ModelAndView given a view name, model, and status.
* @param viewName name of the View to render, to be resolved
* by the DispatcherServlet's ViewResolver
* @param model Map of model names (Strings) to model objects
* (Objects). Model entries may not be {@code null}, but the
* model Map may be {@code null} if there is no model data.
* @param status an alternative status code to use for the response.
*/
public ModelAndView(String viewName, Map<String, ?> model, HttpStatus status) {
this.view = viewName;
if (model != null) {
getModelMap().addAllAttributes(model);
}
this.status = status;
}
/**
* Convenient constructor to take a single model object.
* @param viewName name of the View to render, to be resolved
@ -215,6 +238,21 @@ public class ModelAndView { @@ -215,6 +238,21 @@ public class ModelAndView {
return getModelMap();
}
/**
* Set the status to use for the response.
* @since 4.3
*/
public void setStatus(HttpStatus status) {
this.status = status;
}
/**
* Return the configured status for the response.
*/
public HttpStatus getStatus() {
return this.status;
}
/**
* Add an attribute to the model.

3
spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ModelAndViewMethodReturnValueHandler.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -98,6 +98,7 @@ public class ModelAndViewMethodReturnValueHandler implements HandlerMethodReturn @@ -98,6 +98,7 @@ public class ModelAndViewMethodReturnValueHandler implements HandlerMethodReturn
}
}
}
mavContainer.setStatus(mav.getStatus());
mavContainer.addAllAttributes(mav.getModel());
}

4
spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapter.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -916,7 +916,7 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter @@ -916,7 +916,7 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter
return null;
}
ModelMap model = mavContainer.getModel();
ModelAndView mav = new ModelAndView(mavContainer.getViewName(), model);
ModelAndView mav = new ModelAndView(mavContainer.getViewName(), model, mavContainer.getStatus());
if (!mavContainer.isViewReference()) {
mav.setView((View) mavContainer.getView());
}

23
spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ServletAnnotationControllerHandlerMethodTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -1736,6 +1736,19 @@ public class ServletAnnotationControllerHandlerMethodTests extends AbstractServl @@ -1736,6 +1736,19 @@ public class ServletAnnotationControllerHandlerMethodTests extends AbstractServl
assertArrayEquals(content, response.getContentAsByteArray());
}
@Test
public void modelAndViewWithStatus() throws Exception {
initServletWithControllers(ModelAndViewController.class);
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/path");
MockHttpServletResponse response = new MockHttpServletResponse();
getServlet().service(request, response);
assertEquals(422, response.getStatus());
assertEquals("view", response.getForwardedUrl());
}
/*
* Controllers
*/
@ -3219,6 +3232,14 @@ public class ServletAnnotationControllerHandlerMethodTests extends AbstractServl @@ -3219,6 +3232,14 @@ public class ServletAnnotationControllerHandlerMethodTests extends AbstractServl
}
}
@Controller
public static class ModelAndViewController {
@RequestMapping("/path")
public ModelAndView methodWithHttpStatus(MyEntity object) {
return new ModelAndView("view", new ModelMap(), HttpStatus.UNPROCESSABLE_ENTITY);
}
}
// Test cases deleted from the original ServletAnnotationControllerTests:

Loading…
Cancel
Save