diff --git a/spring-web/src/main/java/org/springframework/web/bind/annotation/ResponseBody.java b/spring-web/src/main/java/org/springframework/web/bind/annotation/ResponseBody.java index 69ec801103..7a8349ec04 100644 --- a/spring-web/src/main/java/org/springframework/web/bind/annotation/ResponseBody.java +++ b/spring-web/src/main/java/org/springframework/web/bind/annotation/ResponseBody.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 the original author or authors. + * Copyright 2002-2013 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. @@ -23,15 +23,18 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** - * Annotation which indicates that a method return value should be bound to the web response body. - * Supported for annotated handler methods in Servlet environments. + * Annotation that indicates a method return value should be bound to the web response + * body. Supported for annotated handler methods in Servlet environments. + *
+ * As of version 4.0 this annotation can also be added on the type level in which case + * is inherited and does not need to be added on the method level. * * @author Arjen Poutsma * @since 3.0 * @see RequestBody - * @see org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter + * @see RestController */ -@Target(ElementType.METHOD) +@Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface ResponseBody { diff --git a/spring-web/src/main/java/org/springframework/web/bind/annotation/RestController.java b/spring-web/src/main/java/org/springframework/web/bind/annotation/RestController.java new file mode 100644 index 0000000000..aa93d35e2d --- /dev/null +++ b/spring-web/src/main/java/org/springframework/web/bind/annotation/RestController.java @@ -0,0 +1,45 @@ +/* + * Copyright 2002-2012 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.web.bind.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.springframework.stereotype.Controller; + +/** + * A convenience annotation that is itself annotated with {@link Controller @Controller} + * and {@link ResponseBody @ResponseBody}. + *
+ * Types that carry this annotation are treated as
+ * controllers where {@link RequestMapping @RequestMapping} methods assume
+ * {@link ResponseBody @ResponseBody} semantics by default.
+ *
+ * @author Rossen Stoyanchev
+ * @since 4.0
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Controller
+@ResponseBody
+public @interface RestController {
+
+}
diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessor.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessor.java
index 0e2cc60956..ba32ccbb9c 100644
--- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessor.java
+++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessor.java
@@ -81,7 +81,8 @@ public class RequestResponseBodyMethodProcessor extends AbstractMessageConverter
@Override
public boolean supportsReturnType(MethodParameter returnType) {
- return returnType.getMethodAnnotation(ResponseBody.class) != null;
+ return ((AnnotationUtils.findAnnotation(returnType.getDeclaringClass(), ResponseBody.class) != null)
+ || (returnType.getMethodAnnotation(ResponseBody.class) != null));
}
/**
diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessorTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessorTests.java
index 5c69b6f424..56e2533d46 100644
--- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessorTests.java
+++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessorTests.java
@@ -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