Allow @ResponseBody on the type level
This change enables having @ResponseBody on the type-level in which case it inherited and does not need to be added on the method level. For added convenience, there is also a new @RestController annotation, a meta-annotation in turn annotated with @Controller and @ResponseBody. Classes with the new annotation do not need to have @ResponseBody declared on the method level as it is inherited. Issue: SPR-10814
This commit is contained in:
@@ -16,9 +16,6 @@
|
||||
|
||||
package org.springframework.web.servlet.mvc.method.annotation;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
@@ -39,12 +36,17 @@ import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
|
||||
import org.springframework.web.bind.WebDataBinder;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.support.WebDataBinderFactory;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.context.request.ServletWebRequest;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Test fixture for a {@link RequestResponseBodyMethodProcessor} with actual delegation
|
||||
* to HttpMessageConverter instances.
|
||||
@@ -231,6 +233,34 @@ public class RequestResponseBodyMethodProcessorTests {
|
||||
assertEquals("text/plain;charset=UTF-8", servletResponse.getHeader("Content-Type"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void supportsReturnTypeResponseBodyOnType() throws Exception {
|
||||
|
||||
Method method = ResponseBodyController.class.getMethod("handle");
|
||||
MethodParameter returnType = new MethodParameter(method, -1);
|
||||
|
||||
List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>();
|
||||
converters.add(new StringHttpMessageConverter());
|
||||
|
||||
RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(converters);
|
||||
|
||||
assertTrue("Failed to recognize type-level @ResponseBody", processor.supportsReturnType(returnType));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void supportsReturnTypeRestController() throws Exception {
|
||||
|
||||
Method method = TestRestController.class.getMethod("handle");
|
||||
MethodParameter returnType = new MethodParameter(method, -1);
|
||||
|
||||
List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>();
|
||||
converters.add(new StringHttpMessageConverter());
|
||||
|
||||
RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(converters);
|
||||
|
||||
assertTrue("Failed to recognize type-level @RestController", processor.supportsReturnType(returnType));
|
||||
}
|
||||
|
||||
|
||||
public String handle(
|
||||
@RequestBody List<SimpleBean> list,
|
||||
@@ -289,4 +319,22 @@ public class RequestResponseBodyMethodProcessorTests {
|
||||
}
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
private static class ResponseBodyController {
|
||||
|
||||
@RequestMapping
|
||||
public String handle() {
|
||||
return "hello";
|
||||
}
|
||||
}
|
||||
|
||||
@RestController
|
||||
private static class TestRestController {
|
||||
|
||||
@RequestMapping
|
||||
public String handle() {
|
||||
return "hello";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,14 +16,6 @@
|
||||
|
||||
package org.springframework.web.servlet.mvc.method.annotation;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.beans.PropertyEditorSupport;
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
@@ -64,10 +56,6 @@ import org.junit.Test;
|
||||
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
|
||||
import org.springframework.aop.interceptor.SimpleTraceInterceptor;
|
||||
import org.springframework.aop.support.DefaultPointcutAdvisor;
|
||||
import org.springframework.tests.sample.beans.DerivedTestBean;
|
||||
import org.springframework.tests.sample.beans.GenericBean;
|
||||
import org.springframework.tests.sample.beans.ITestBean;
|
||||
import org.springframework.tests.sample.beans.TestBean;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
@@ -101,6 +89,10 @@ import org.springframework.mock.web.test.MockServletConfig;
|
||||
import org.springframework.mock.web.test.MockServletContext;
|
||||
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.tests.sample.beans.DerivedTestBean;
|
||||
import org.springframework.tests.sample.beans.GenericBean;
|
||||
import org.springframework.tests.sample.beans.ITestBean;
|
||||
import org.springframework.tests.sample.beans.TestBean;
|
||||
import org.springframework.ui.ExtendedModelMap;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.ui.ModelMap;
|
||||
@@ -123,6 +115,7 @@ import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.SessionAttributes;
|
||||
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
|
||||
import org.springframework.web.bind.support.WebArgumentResolver;
|
||||
@@ -142,6 +135,8 @@ import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
||||
import org.springframework.web.servlet.support.RequestContextUtils;
|
||||
import org.springframework.web.servlet.view.InternalResourceViewResolver;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* The origin of this test class is {@link ServletAnnotationControllerHandlerMethodTests}.
|
||||
*
|
||||
@@ -1569,6 +1564,18 @@ public class ServletAnnotationControllerHandlerMethodTests extends AbstractServl
|
||||
assertEquals("count:3", response.getContentAsString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void restController() throws Exception {
|
||||
|
||||
initServletWithControllers(ThisWillActuallyRun.class);
|
||||
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/");
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
getServlet().service(request, response);
|
||||
assertEquals("Hello World!", response.getContentAsString());
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Controllers
|
||||
*/
|
||||
@@ -2979,6 +2986,16 @@ public class ServletAnnotationControllerHandlerMethodTests extends AbstractServl
|
||||
}
|
||||
}
|
||||
|
||||
@RestController
|
||||
static class ThisWillActuallyRun {
|
||||
|
||||
@RequestMapping(value = "/", method = RequestMethod.GET)
|
||||
public String home() {
|
||||
return "Hello World!";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Test cases deleted from the original SevletAnnotationControllerTests:
|
||||
|
||||
// @Ignore("Controller interface => no method-level @RequestMapping annotation")
|
||||
|
||||
Reference in New Issue
Block a user