You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@juneau.apache.org by ja...@apache.org on 2018/08/05 18:27:05 UTC

[juneau] branch master updated: Merge functionality of @Response and @ResponseBody

This is an automated email from the ASF dual-hosted git repository.

jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git


The following commit(s) were added to refs/heads/master by this push:
     new b45935d  Merge functionality of @Response and @ResponseBody
b45935d is described below

commit b45935d79899cc4f46d294dcf5665eadcd4eab69
Author: JamesBognar <ja...@apache.org>
AuthorDate: Sun Aug 5 14:26:39 2018 -0400

    Merge functionality of @Response and @ResponseBody
---
 .../http/annotation/AnnotationUtilsTest.java       |  18 -
 .../juneau/http/annotation/AnnotationUtils.java    |  28 --
 .../apache/juneau/http/annotation/Response.java    |   2 +-
 .../juneau/http/annotation/ResponseBody.java       | 237 +-----------
 .../org/apache/juneau/httppart/HttpPartSchema.java |   2 -
 .../juneau/httppart/HttpPartSchemaBuilder.java     |   9 -
 .../juneau/httppart/bean/ResponseBeanMeta.java     | 109 ++++--
 .../org/apache/juneau/internal/ClassUtils.java     |  12 +-
 .../java/org/apache/juneau/rest/RestContext.java   |   2 -
 .../org/apache/juneau/rest/RestJavaMethod.java     |  12 +-
 .../org/apache/juneau/rest/RestParamDefaults.java  |  32 +-
 .../java/org/apache/juneau/rest/RestResponse.java  |  25 +-
 .../org/apache/juneau/rest/SwaggerGenerator.java   |  38 --
 .../juneau/rest/reshandlers/DefaultHandler.java    |  29 +-
 .../rest/annotation/ResponseAnnotationTest.java    | 409 +++++++++++++++++++-
 .../annotation/ResponseBodyAnnotationTest.java     | 428 ---------------------
 16 files changed, 496 insertions(+), 896 deletions(-)

diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/http/annotation/AnnotationUtilsTest.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/http/annotation/AnnotationUtilsTest.java
index f9a9937..684e09a 100644
--- a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/http/annotation/AnnotationUtilsTest.java
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/http/annotation/AnnotationUtilsTest.java
@@ -44,7 +44,6 @@ public class AnnotationUtilsTest {
 
 	@Body
 	@Response
-	@ResponseBody
 	@ResponseHeader
 	@X
 	public static class A01 {
@@ -56,7 +55,6 @@ public class AnnotationUtilsTest {
 	public void testEmpty() throws Exception {
 		assertTrue(empty(A01.class.getAnnotation(Body.class)));
 		assertTrue(empty(A01.class.getAnnotation(Response.class)));
-		assertTrue(empty(A01.class.getAnnotation(ResponseBody.class)));
 		assertTrue(empty(A01.class.getAnnotation(ResponseHeader.class)));
 
 		X x = A01.class.getAnnotation(X.class);
@@ -82,7 +80,6 @@ public class AnnotationUtilsTest {
 	public void testEmptyNonExistent() throws Exception {
 		assertTrue(empty(B01.class.getAnnotation(Body.class)));
 		assertTrue(empty(B01.class.getAnnotation(Response.class)));
-		assertTrue(empty(B01.class.getAnnotation(ResponseBody.class)));
 		assertTrue(empty(B01.class.getAnnotation(ResponseHeader.class)));
 
 		assertTrue(empty((Contact)null));
@@ -171,21 +168,6 @@ public class AnnotationUtilsTest {
 		assertTrue(usePartSerializer(D01e.class.getAnnotation(Body.class)));
 	}
 
-	@ResponseBody public static class E01a {}
-	@ResponseBody(usePartSerializer=true) public static class E01b {}
-	@ResponseBody(schema=@Schema) public static class E01c {}
-	@ResponseBody(schema=@Schema(description="foo")) public static class E01d {}
-	@ResponseBody(partSerializer=OpenApiPartSerializer.class) public static class E01e {}
-
-	@Test
-	public void usePartSerializerResponseBody() {
-		assertFalse(usePartSerializer(E01a.class.getAnnotation(ResponseBody.class)));
-		assertTrue(usePartSerializer(E01b.class.getAnnotation(ResponseBody.class)));
-		assertFalse(usePartSerializer(E01c.class.getAnnotation(ResponseBody.class)));
-		assertTrue(usePartSerializer(E01d.class.getAnnotation(ResponseBody.class)));
-		assertTrue(usePartSerializer(E01e.class.getAnnotation(ResponseBody.class)));
-	}
-
 	@Response public static class F01a {}
 	@Response(usePartSerializer=true) public static class F01b {}
 	@Response(schema=@Schema) public static class F01c {}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/AnnotationUtils.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/AnnotationUtils.java
index f22c67a..8fdfcfc 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/AnnotationUtils.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/AnnotationUtils.java
@@ -155,21 +155,6 @@ public class AnnotationUtils {
 			&& empty(a.schema());
 	}
 
-
-	/**
-	 * Returns <jk>true</jk> if the specified annotation contains all default values.
-	 *
-	 * @param a The annotation to check.
-	 * @return <jk>true</jk> if the specified annotation contains all default values.
-	 */
-	public static boolean empty(ResponseBody a) {
-		if (a == null)
-			return true;
-		return
-			allEmpty(a.example(), a.examples(), a.api())
-			&& empty(a.schema());
-	}
-
 	/**
 	 * Returns <jk>true</jk> if the specified annotation contains all default values.
 	 *
@@ -333,19 +318,6 @@ public class AnnotationUtils {
 	 * @param a The annotation to check.
 	 * @return <jk>true</jk> if the part serializer should be used on the specified part.
 	 */
-	public static boolean usePartSerializer(ResponseBody a) {
-		return
-			a.usePartSerializer()
-			|| a.partSerializer() != HttpPartSerializer.Null.class
-			|| ! empty(a.schema());
-	}
-
-	/**
-	 * Returns <jk>true</jk> if the part serializer should be used on the specified part.
-	 *
-	 * @param a The annotation to check.
-	 * @return <jk>true</jk> if the part serializer should be used on the specified part.
-	 */
 	public static boolean usePartSerializer(Response a) {
 		return
 			a.usePartSerializer()
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/Response.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/Response.java
index 1ba720d..0c16949 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/Response.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/Response.java
@@ -48,7 +48,7 @@ import org.apache.juneau.jsonschema.*;
  * </ul>
  */
 @Documented
-@Target({PARAMETER,TYPE})
+@Target({PARAMETER,TYPE,METHOD})
 @Retention(RUNTIME)
 @Inherited
 public @interface Response {
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/ResponseBody.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/ResponseBody.java
index e1aafcb..cce8cf0 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/ResponseBody.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/ResponseBody.java
@@ -17,244 +17,11 @@ import static java.lang.annotation.RetentionPolicy.*;
 
 import java.lang.annotation.*;
 
-import org.apache.juneau.*;
-import org.apache.juneau.annotation.*;
-import org.apache.juneau.httppart.*;
-import org.apache.juneau.json.*;
-import org.apache.juneau.jsonschema.*;
-
 /**
  * TODO
  */
 @Documented
-@Target({PARAMETER,METHOD,TYPE})
+@Target(METHOD)
 @Retention(RUNTIME)
 @Inherited
-public @interface ResponseBody {
-
-	/**
-	 * Specifies the {@link HttpPartSerializer} class used for serializing values to strings.
-	 *
-	 * <p>
-	 * Overrides for this part the part serializer defined on the REST resource which by default is {@link OpenApiPartSerializer}.
-	 */
-	Class<? extends HttpPartSerializer> partSerializer() default HttpPartSerializer.Null.class;
-
-	/**
-	 * Specifies whether a part serializer should be used for serializing this value.
-	 *
-	 * <p>
-	 * If <jk>false</jk>, then it indicates that normal Juneau serializers (e.g. {@link JsonSerializer}) should be used for this part.
-	 */
-	public boolean usePartSerializer() default false;
-
-	/**
-	 * <mk>schema</mk> field of the Swagger <a class="doclink" href="https://swagger.io/specification/v2/#responseObject">Response</a> object.
-	 *
-	 * <h5 class='section'>Used for:</h5>
-	 * <ul class='spaced-list'>
-	 * 	<li>
-	 * 		Server-side schema-based serializing and serializing validation.
-	 * 	<li>
-	 * 		Server-side generated Swagger documentation.
-	 * </ul>
-	 */
-	Schema schema() default @Schema;
-
-	/**
-	 * A serialized example of the body of a response.
-	 *
-	 * <p>
-	 * This is the <a class='doclink' href='../../../../../overview-summary.html#juneau-marshall.JsonDetails.SimplifiedJson'>Simplified JSON</a> of an example of the body.
-	 *
-	 * <p>
-	 * This value is converted to a POJO and then serialized to all the registered serializers on the REST method to produce examples for all
-	 * supported language types.
-	 * <br>These values are then used to automatically populate the {@link #examples} field.
-	 *
-	 * <h5 class='section'>Example:</h5>
-	 * <p class='bcode w800'>
-	 * 	<jc>// A JSON representation of a PetCreate object.</jc>
-	 * 	<ja>@ResponseBody</ja>(
-	 * 		example=<js>"{name:'Doggie',price:9.99,species:'Dog',tags:['friendly','cute']}"</js>
-	 * 	)
-	 * </p>
-	 *
-	 * <p>
-	 * There are several other options for defining this example:
-	 * <ul class='spaced-list'>
-	 * 	<li>
-	 * 		Defining an <js>"x-example"</js> field in the inherited Swagger JSON response object (classpath file or <code><ja>@ResourceSwagger</ja>(value)</code>/<code><ja>@MethodSwagger</ja>(value)</code>).
-	 * 	<li>
-	 * 		Defining an <js>"x-example"</js> field in the Swagger Schema Object for the response object (including referenced <js>"$ref"</js> schemas).
-	 * 	<li>
-	 * 		Allowing Juneau to auto-generate a code example.
-	 * </ul>
-	 *
-	 * <p>
-	 * The latter is important because Juneau also supports auto-generation of JSON-Schema from POJO classes using {@link JsonSchemaSerializer} which has several of it's own
-	 * options for auto-detecting and calculation POJO examples.
-	 *
-	 * <p>
-	 * In particular, examples can be defined via static methods, fields, and annotations on the classes themselves.
-	 *
-	 * <p class='bcode w800'>
-	 * 	<jc>// Annotation on class.</jc>
-	 * 	<ja>@Example</ja>(<js>"{name:'Doggie',price:9.99,species:'Dog',tags:['friendly','cute']}"</js>)
-	 * 	<jk>public class</jk> PetCreate {
-	 * 		...
-	 * 	}
-	 * </p>
-	 * <p class='bcode w800'>
-	 * 	<jc>// Annotation on static method.</jc>
-	 * 	<jk>public class</jk> PetCreate {
-	 *
-	 * 		<ja>@Example</ja>
-	 * 		<jk>public static</jk> PetCreate <jsm>sample</jsm>() {
-	 * 			<jk>return new</jk> PetCreate(<js>"Doggie"</js>, 9.99f, <js>"Dog"</js>, <jk>new</jk> String[] {<js>"friendly"</js>,<js>"cute"</js>});
-	 * 		}
-	 * 	}
-	 * </p>
-	 * <p class='bcode w800'>
-	 * 	<jc>// Static method with specific name 'example'.</jc>
-	 * 	<jk>public class</jk> PetCreate {
-	 *
-	 * 		<jk>public static</jk> PetCreate <jsm>example</jsm>() {
-	 * 			<jk>return new</jk> PetCreate(<js>"Doggie"</js>, 9.99f, <js>"Dog"</js>, <jk>new</jk> String[] {<js>"friendly"</js>,<js>"cute"</js>});
-	 * 		}
-	 * 	}
-	 * </p>
-	 * <p class='bcode w800'>
-	 * 	<jc>// Static field.</jc>
-	 * 	<jk>public class</jk> PetCreate {
-	 *
-	 * 		<ja>@Example</ja>
-	 * 		<jk>public static</jk> PetCreate <jsf>EXAMPLE</jsf> = <jk>new</jk> PetCreate(<js>"Doggie"</js>, 9.99f, <js>"Dog"</js>, <jk>new</jk> String[] {<js>"friendly"</js>,<js>"cute"</js>});
-	 * 	}
-	 * </p>
-	 *
-	 * <p>
-	 * Examples can also be specified via generic properties as well using the {@link BeanContext#BEAN_examples} property at either the class or method level.
-	 * <p class='bcode w800'>
-	 * 	<jc>// Examples defined at class level.</jc>
-	 * 	<ja>@RestResource</ja>(
-	 * 		properties={
-	 * 			<ja>@Property</ja>(
-	 * 				name=<jsf>BEAN_examples</jsf>,
-	 * 				value=<js>"{'org.apache.juneau.examples.rest.petstore.PetCreate': {name:'Doggie',price:9.99,species:'Dog',tags:['friendly','cute']}}"</js>
-	 * 			)
-	 * 		}
-	 * 	)
-	 * </p>
-	 *
-	 * <h5 class='section'>Used for:</h5>
-	 * <ul class='spaced-list'>
-	 * 	<li>
-	 * 		Server-side generated Swagger documentation.
-	 * </ul>
-	 *
-	 * <h5 class='section'>See also:</h5>
-	 * <ul>
-	 * 	<li class='ja'>{@link Example}
-	 * 	<li class='jc'>{@link BeanContext}
-	 * 	<ul>
-	 * 		<li class='jf'>{@link BeanContext#BEAN_examples BEAN_examples}
-	 * 	</ul>
-	 * 	<li class='jc'>{@link JsonSchemaSerializer}
-	 * 	<ul>
-	 * 		<li class='jf'>{@link JsonSchemaSerializer#JSONSCHEMA_addExamplesTo JSONSCHEMA_addExamplesTo}
-	 * 		<li class='jf'>{@link JsonSchemaSerializer#JSONSCHEMA_allowNestedExamples JSONSCHEMA_allowNestedExamples}
-	 * 	</ul>
-	 * </ul>
-	 *
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul class='spaced-list'>
-	 * 	<li>
-	 * 		The format is any <a class='doclink' href='../../../../../overview-summary.html#juneau-marshall.JsonDetails.SimplifiedJson'>Simplified JSON</a> if the object can be converted to a POJO using {@link JsonParser#DEFAULT} or a simple String if the object
-	 * 		has a schema associated with it can be converted from a String.
-	 * 		<br>Multiple lines are concatenated with newlines.
-	 * 	<li>
-	 * 		The format of this object can also be a simple String if the body has a schema associated with it, meaning it's meant to be treated as an HTTP part.
-	 * 	<li>
-	 * 		Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a>
-	 * 		(e.g. <js>"$L{my.localized.variable}"</js>).
-	 * </ul>
-	 */
-	String[] example() default {};
-
-	/**
-	 * Serialized examples of the body of a response.
-	 *
-	 * <p>
-	 * This is a <a class='doclink' href='../../../../../overview-summary.html#juneau-marshall.JsonDetails.SimplifiedJson'>Simplified JSON</a> object whose keys are media types and values are string representations of that value.
-	 *
-	 * <p>
-	 * In general you won't need to populate this value directly since it will automatically be calculated based on the value provided in the {@link #example()} field.
-	 * <br>However, this field allows you to override the behavior and show examples for only specified media types or different examples for different media types.
-	 *
-	 * <p class='bcode w800'>
-	 * 	<jc>// A JSON representation of a PetCreate object.</jc>
-	 * 	<ja>@ResponseBody</ja>(
-	 * 		examples={
-	 * 			<js>"'application/json':'{name:\\'Doggie\\',species:\\'Dog\\'}',"</js>,
-	 * 			<js>"'text/uon':'(name:Doggie,species=Dog)'"</js>
-	 * 		}
-	 * 	)
-	 * </p>
-	 *
-	 * <h5 class='section'>Used for:</h5>
-	 * <ul class='spaced-list'>
-	 * 	<li>
-	 * 		Server-side generated Swagger documentation.
-	 * </ul>
-	 *
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul class='spaced-list'>
-	 * 	<li>
-	 * 		The format is a <a class='doclink' href='../../../../../overview-summary.html#juneau-marshall.JsonDetails.SimplifiedJson'>Simplified JSON</a> object with string keys (media type) and string values (example for that media type) .
-	 * 	<li>
-	 * 		The leading/trailing <code>{ }</code> characters are optional.
-	 * 	<li>
-	 * 		Multiple lines are concatenated with newlines so that you can format the value to be readable:
-	 * 	<li>
-	 * 		Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a>
-	 * 		(e.g. <js>"$L{my.localized.variable}"</js>).
-	 * 	<li>
-	 * 		Resolution of variables is delayed until request time and occurs before parsing.
-	 * 		<br>This allows you to, for example, pull in a JSON construct from a properties file based on the locale of the HTTP request.
-	 * </ul>
-	 */
-	String[] examples() default {};
-
-	/**
-	 * Free-form value for the Swagger <a class="doclink" href="https://swagger.io/specification/v2/#responseObject">Response</a> object.
-	 *
-	 * <p>
-	 * This is a <a class='doclink' href='../../../../../overview-summary.html#juneau-marshall.JsonDetails.SimplifiedJson'>Simplified JSON</a> object that makes up the swagger information for this field.
-	 *
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul class='spaced-list'>
-	 * 	<li>
-	 * 		Note that the only swagger field you can't specify using this value is <js>"code"</js> whose value needs to be known during servlet initialization.
-	 * 	<li>
-	 * 		The format is a <a class='doclink' href='../../../../../overview-summary.html#juneau-marshall.JsonDetails.SimplifiedJson'>Simplified JSON</a> object.
-	 * 	<li>
-	 * 		The leading/trailing <code>{ }</code> characters are optional.
-	 * 		<br>The following two example are considered equivalent:
-	 * 		<p class='bcode w800'>
-	 * 	<ja>@ResponseBody</ja>(api=<js>"{schema:{type:'string'}}}"</js>)
-	 * 		</p>
-	 * 		<p class='bcode w800'>
-	 * 	<ja>@ResponseBody</ja>(api=<js>"schema: {type:'string'}"</js>)
-	 * 		</p>
-	 * 	<li>
-	 * 		Multiple lines are concatenated with newlines so that you can format the value to be readable.
-	 * 	<li>
-	 * 		Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a>
-	 * 		(e.g. <js>"$L{my.localized.variable}"</js>).
-	 * 	<li>
-	 * 		Values defined in this field supersede values pulled from the Swagger JSON file and are superseded by individual values defined on this annotation.
-	 * </ul>
-	 */
-	String[] api() default {};
-}
+public @interface ResponseBody {}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/HttpPartSchema.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/HttpPartSchema.java
index 08e9500..87cdd19 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/HttpPartSchema.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/HttpPartSchema.java
@@ -140,7 +140,6 @@ public class HttpPartSchema {
 	 * 		<li>{@link Path}
 	 * 		<li>{@link Response}
 	 * 		<li>{@link ResponseHeader}
-	 * 		<li>{@link ResponseBody}
 	 * 		<li>{@link HasQuery}
 	 * 		<li>{@link HasFormData}
 	 * 	</ul>
@@ -169,7 +168,6 @@ public class HttpPartSchema {
 	 * 		<li>{@link Path}
 	 * 		<li>{@link Response}
 	 * 		<li>{@link ResponseHeader}
-	 * 		<li>{@link ResponseBody}
 	 * 		<li>{@link HasQuery}
 	 * 		<li>{@link HasFormData}
 	 * 	</ul>
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/HttpPartSchemaBuilder.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/HttpPartSchemaBuilder.java
index 3ecef7e..1ad58f9 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/HttpPartSchemaBuilder.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/HttpPartSchemaBuilder.java
@@ -108,8 +108,6 @@ public class HttpPartSchemaBuilder {
 			apply((Path)a);
 		else if (a instanceof Response)
 			apply((Response)a);
-		else if (a instanceof ResponseBody)
-			apply((ResponseBody)a);
 		else if (a instanceof ResponseHeader)
 			apply((ResponseHeader)a);
 		else if (a instanceof HasQuery)
@@ -134,13 +132,6 @@ public class HttpPartSchemaBuilder {
 		return this;
 	}
 
-	HttpPartSchemaBuilder apply(ResponseBody a) {
-		serializer(a.partSerializer());
-		usePartSerializer(AnnotationUtils.usePartSerializer(a));
-		apply(a.schema());
-		return this;
-	}
-
 	HttpPartSchemaBuilder apply(Header a) {
 		name(a.value());
 		name(a.name());
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/ResponseBeanMeta.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/ResponseBeanMeta.java
index 17ccdea..0554fd8 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/ResponseBeanMeta.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/bean/ResponseBeanMeta.java
@@ -37,16 +37,70 @@ public class ResponseBeanMeta {
 	/**
 	 * Create metadata from specified class.
 	 *
-	 * @param c The class annotated with {@link Response}.
+	 * @param t The class annotated with {@link Response}.
 	 * @param ps
 	 * 	Configuration information used to instantiate part serializers and part parsers.
 	 * 	<br>Can be <jk>null</jk>.
 	 * @return Metadata about the class, or <jk>null</jk> if class not annotated with {@link Response}.
 	 */
-	public static ResponseBeanMeta create(Class<?> c, PropertyStore ps) {
-		if (! hasAnnotation(Response.class, c))
+	public static ResponseBeanMeta create(Type t, PropertyStore ps) {
+		if (! hasAnnotation(Response.class, t))
 			return null;
-		return new ResponseBeanMeta.Builder(ps).apply(c).build();
+		Builder b = new Builder(ps);
+		if (Value.isType(t))
+			b.apply(Value.getParameterType(t));
+		else
+			b.apply(t);
+		for (Response r : getAnnotationsParentFirst(Response.class, t))
+			b.apply(r);
+		return b.build();
+	}
+
+	/**
+	 * Create metadata from specified method return.
+	 *
+	 * @param m The method annotated with {@link Response}.
+	 * @param ps
+	 * 	Configuration information used to instantiate part serializers and part parsers.
+	 * 	<br>Can be <jk>null</jk>.
+	 * @return Metadata about the class, or <jk>null</jk> if class not annotated with {@link Response}.
+	 */
+	public static ResponseBeanMeta create(Method m, PropertyStore ps) {
+		if (! hasAnnotation(Response.class, m))
+			return null;
+		Builder b = new Builder(ps);
+		Type t = m.getGenericReturnType();
+		if (Value.isType(t))
+			b.apply(Value.getParameterType(t));
+		else
+			b.apply(t);
+		for (Response r : getAnnotationsParentFirst(Response.class, m))
+			b.apply(r);
+		return b.build();
+	}
+
+	/**
+	 * Create metadata from specified method parameter.
+	 *
+	 * @param m The method containing the parameter annotated with {@link Response}.
+	 * @param i The parameter index.
+	 * @param ps
+	 * 	Configuration information used to instantiate part serializers and part parsers.
+	 * 	<br>Can be <jk>null</jk>.
+	 * @return Metadata about the class, or <jk>null</jk> if class not annotated with {@link Response}.
+	 */
+	public static ResponseBeanMeta create(Method m, int i, PropertyStore ps) {
+		if (! hasAnnotation(Response.class, m, i))
+			return null;
+		Builder b = new Builder(ps);
+		Type t = m.getGenericParameterTypes()[i];
+		if (Value.isType(t))
+			b.apply(Value.getParameterType(t));
+		else
+			b.apply(t);
+		for (Response r : getAnnotationsParentFirst(Response.class, m, i))
+			b.apply(r);
+		return b.build();
 	}
 
 	//-----------------------------------------------------------------------------------------------------------------
@@ -56,8 +110,7 @@ public class ResponseBeanMeta {
 	private final ClassMeta<?> cm;
 	private final int code;
 	private final Map<String,ResponseBeanPropertyMeta> headerMethods;
-	private final Method statusMethod;
-	private final ResponseBeanPropertyMeta bodyMethod;
+	private final Method statusMethod, bodyMethod;
 	private final HttpPartSerializer partSerializer;
 	private final HttpPartSchema schema;
 	private final boolean usePartSerializer;
@@ -76,8 +129,7 @@ public class ResponseBeanMeta {
 
 		}
 		this.headerMethods = Collections.unmodifiableMap(hm);
-
-		this.bodyMethod = b.bodyMethod == null ? null : b.bodyMethod.build(partSerializer);
+		this.bodyMethod = b.bodyMethod;
 		this.statusMethod = b.statusMethod;
 	}
 
@@ -90,15 +142,15 @@ public class ResponseBeanMeta {
 		HttpPartSchemaBuilder schema = HttpPartSchema.create();
 
 		Map<String,ResponseBeanPropertyMeta.Builder> headerMethods = new LinkedHashMap<>();
-		ResponseBeanPropertyMeta.Builder bodyMethod;
+		Method bodyMethod;
 		Method statusMethod;
 
 		Builder(PropertyStore ps) {
 			this.ps = ps;
 		}
 
-		Builder apply(Class<?> c) {
-			apply(getAnnotation(Response.class, c));
+		Builder apply(Type t) {
+			Class<?> c = ClassUtils.toClass(t);
 			this.cm = BeanContext.DEFAULT.getClassMeta(c);
 			for (Method m : ClassUtils.getAllMethods(c, false)) {
 				if (isAll(m, PUBLIC, HAS_NO_ARGS)) {
@@ -129,9 +181,7 @@ public class ResponseBeanMeta {
 						Class<?> rt = m.getReturnType();
 						if (rt == void.class)
 							throw new InvalidAnnotationException("Invalid return type for @ResponseBody annotation on method.  Method=''{0}''", m);
-						ResponseBody a = getAnnotation(ResponseBody.class, m);
-						HttpPartSchemaBuilder s = HttpPartSchema.create().apply(a);
-						bodyMethod = ResponseBeanPropertyMeta.create().partType(HttpPartType.BODY).apply(s).getter(m);
+						bodyMethod = m;
 					}
 					if (hasAnnotation(Body.class, m))
 						throw new InvalidAnnotationException("@Body annotation cannot be used in a @Response bean.  Use @ResponseBody instead.  Method=''{0}''", m);
@@ -142,17 +192,16 @@ public class ResponseBeanMeta {
 			return this;
 		}
 
-		Builder apply(Response rb) {
-			if (rb != null) {
-				if (rb.partSerializer() != HttpPartSerializer.Null.class)
-					partSerializer = rb.partSerializer();
-				if (rb.usePartSerializer())
-					usePartSerializer = true;
-				if (rb.value().length > 0)
-					code = rb.value()[0];
-				if (rb.code().length > 0)
-					code = rb.code()[0];
-				schema.apply(rb.schema());
+		Builder apply(Response a) {
+			if (a != null) {
+				if (a.partSerializer() != HttpPartSerializer.Null.class)
+					partSerializer = a.partSerializer();
+				if (a.value().length > 0)
+					code = a.value()[0];
+				if (a.code().length > 0)
+					code = a.code()[0];
+				usePartSerializer = AnnotationUtils.usePartSerializer(a);
+				schema.apply(a.schema());
 			}
 			return this;
 		}
@@ -190,18 +239,18 @@ public class ResponseBeanMeta {
 	}
 
 	/**
-	 * Returns metadata about the <ja>@ResponseBody</ja>-annotated method.
+	 * Returns the <ja>@ResponseBody</ja>-annotated method.
 	 *
-	 * @return Metadata about the <ja>@ResponseBody</ja>-annotated method, or <jk>null</jk> if it doesn't exist.
+	 * @return The <ja>@ResponseBody</ja>-annotated method, or <jk>null</jk> if it doesn't exist.
 	 */
-	public ResponseBeanPropertyMeta getBodyMethod() {
+	public Method getBodyMethod() {
 		return bodyMethod;
 	}
 
 	/**
-	 * Returns metadata about the <ja>@ResponseBody</ja>-annotated method.
+	 * Returns the <ja>@ResponseStatus</ja>-annotated method.
 	 *
-	 * @return Metadata about the <ja>@ResponseBody</ja>-annotated method, or <jk>null</jk> if it doesn't exist.
+	 * @return The <ja>@ResponseStatus</ja>-annotated method, or <jk>null</jk> if it doesn't exist.
 	 */
 	public Method getStatusMethod() {
 		return statusMethod;
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ClassUtils.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ClassUtils.java
index c61c5ab..4ee46ca 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ClassUtils.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ClassUtils.java
@@ -2485,7 +2485,17 @@ public final class ClassUtils {
 		}
 	}
 
-	private static Class<?> toClass(Type t) {
+	/**
+	 * Returns the specified type as a <code>Class</code>.
+	 *
+	 * <p>
+	 * If it's already a <code>Class</code>, it just does a cast.
+	 * <br>If it's a <code>ParameterizedType</code>, it returns the raw type.
+	 *
+	 * @param t The type to convert.
+	 * @return The type converted to a <code>Class</code>, or <jk>null</jk> if it could not be converted.
+	 */
+	public static Class<?> toClass(Type t) {
 		if (t instanceof Class)
 			return (Class<?>)t;
 		if (t instanceof ParameterizedType) {
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
index 4771c2e..aba79f1 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
@@ -4326,8 +4326,6 @@ public final class RestContext extends BeanContext {
 				rp[i] = new RestParamDefaults.ResponseBeanObject(method, i, ps);
 			} else if (hasAnnotation(ResponseHeader.class, method, i)) {
 				rp[i] = new RestParamDefaults.ResponseHeaderObject(method, i, ps);
-			} else if (hasAnnotation(ResponseBody.class, method, i)) {
-				rp[i] = new RestParamDefaults.ResponseBodyObject(method, i, ps);
 			} else if (hasAnnotation(ResponseStatus.class, method, i)) {
 				rp[i] = new RestParamDefaults.ResponseStatusObject(method, t);
 			} else if (hasAnnotation(HasFormData.class, method, i)) {
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestJavaMethod.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestJavaMethod.java
index fc968ec..d588cd5 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestJavaMethod.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestJavaMethod.java
@@ -79,7 +79,7 @@ public class RestJavaMethod implements Comparable<RestJavaMethod>  {
 	final Map<Class<?>,ResponseBeanMeta> responseBeanMetas = new ConcurrentHashMap<>();
 	final Map<Class<?>,ResponsePartMeta> headerPartMetas = new ConcurrentHashMap<>();
 	final Map<Class<?>,ResponsePartMeta> bodyPartMetas = new ConcurrentHashMap<>();
-	final ResponsePartMeta returnBodyMeta;
+	final ResponseBeanMeta responseMeta;
 
 	RestJavaMethod(Object servlet, java.lang.reflect.Method method, RestContext context) throws RestServletException {
 		Builder b = new Builder(servlet, method, context);
@@ -107,7 +107,7 @@ public class RestJavaMethod implements Comparable<RestJavaMethod>  {
 		this.priority = b.priority;
 		this.supportedAcceptTypes = b.supportedAcceptTypes;
 		this.supportedContentTypes = b.supportedContentTypes;
-		this.returnBodyMeta = b.returnBodyMeta;
+		this.responseMeta = b.responseMeta;
 		this.widgets = unmodifiableMap(b.widgets);
 	}
 
@@ -130,7 +130,7 @@ public class RestJavaMethod implements Comparable<RestJavaMethod>  {
 		Integer priority;
 		Map<String,Widget> widgets;
 		List<MediaType> supportedAcceptTypes, supportedContentTypes;
-		ResponsePartMeta returnBodyMeta;
+		ResponseBeanMeta responseMeta;
 
 		Builder(Object servlet, java.lang.reflect.Method method, RestContext context) throws RestServletException {
 			String sig = method.getDeclaringClass().getName() + '.' + method.getName();
@@ -410,10 +410,8 @@ public class RestJavaMethod implements Comparable<RestJavaMethod>  {
 
 				methodParams = context.findParams(method, pathPattern, false);
 
-				if (hasAnnotation(ResponseBody.class, method)) {
-					HttpPartSchema s = HttpPartSchema.create(ResponseBody.class, method);
-					returnBodyMeta = new ResponsePartMeta(HttpPartType.BODY, s, createPartSerializer(s.getSerializer(), serializers.getPropertyStore(), partSerializer));
-				}
+				if (hasAnnotation(Response.class, method))
+					responseMeta = ResponseBeanMeta.create(method, serializers.getPropertyStore());
 
 				// Need this to access methods in anonymous inner classes.
 				setAccessible(method, true);
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestParamDefaults.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestParamDefaults.java
index 0cb7a14..355faea 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestParamDefaults.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestParamDefaults.java
@@ -673,42 +673,12 @@ class RestParamDefaults {
 		}
 	}
 
-	static final class ResponseBodyObject extends RestMethodParam {
-		final ResponsePartMeta rpm;
-
-		protected ResponseBodyObject(Method m, int i, PropertyStore ps) {
-			super(RESPONSE_BODY, m, i);
-			HttpPartSchema schema = HttpPartSchema.create(ResponseBody.class, method, i);
-			this.rpm = new ResponsePartMeta(HttpPartType.BODY, schema, createPartSerializer(schema.getSerializer(), ps));
-
-			if (getTypeClass() != Value.class)
-				throw new InternalServerError("Invalid type {0} specified with @ResponseHeader annotation.  It must be Value.", type);
-		}
-
-		@SuppressWarnings({ "unchecked", "rawtypes" })
-		@Override /* RestMethodParam */
-		public Object resolve(final RestRequest req, final RestResponse res) throws Exception {
-			Value<Object> v = (Value<Object>)getTypeClass().newInstance();
-			v.listener(new ValueListener() {
-				@Override
-				public void onSet(Object o) {
-					ResponsePartMeta rpm = req.getResponseBodyMeta(o);
-					if (rpm == null)
-						rpm = ResponseBodyObject.this.rpm;
-					res.setResponseBodyMeta(rpm);
-					res.setOutput(o);
-				}
-			});
-			return v;
-		}
-	}
-
 	static final class ResponseBeanObject extends RestMethodParam {
 		final ResponseBeanMeta rbm;
 
 		protected ResponseBeanObject(Method m, int i, PropertyStore ps) {
 			super(RESPONSE, m, i);
-			this.rbm = ResponseBeanMeta.create(m.getParameterTypes()[i], ps);
+			this.rbm = ResponseBeanMeta.create(m, i, ps);
 			if (getTypeClass() != Value.class)
 				throw new InternalServerError("Invalid type {0} specified with @Response annotation.  It must be Value.", type);
 		}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestResponse.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestResponse.java
index b38221d..70947b4 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestResponse.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestResponse.java
@@ -68,7 +68,6 @@ public final class RestResponse extends HttpServletResponseWrapper {
 	private HtmlDocBuilder htmlDocBuilder;
 
 	private ResponseBeanMeta resBeanMeta;
-	private ResponsePartMeta resBodyMeta;
 
 	/**
 	 * Constructor.
@@ -121,7 +120,7 @@ public final class RestResponse extends HttpServletResponseWrapper {
 			throw new NotAcceptable("No supported charsets in header ''Accept-Charset'': ''{0}''", request.getHeader("Accept-Charset"));
 		super.setCharacterEncoding(charset);
 
-		this.resBodyMeta = rjm.returnBodyMeta;
+		this.resBeanMeta = rjm.responseMeta;
 	}
 
 	/**
@@ -539,28 +538,6 @@ public final class RestResponse extends HttpServletResponseWrapper {
 	}
 
 	/**
-	 * Returns the metadata about this response body.
-	 *
-	 * @return
-	 * 	The metadata about this response.
-	 * 	<jk>Never <jk>null</jk>.
-	 */
-	public ResponsePartMeta getResponseBodyMeta() {
-		return resBodyMeta;
-	}
-
-	/**
-	 * Sets metadata about this response body.
-	 *
-	 * @param rpm The metadata about this response body.
-	 * @return This object (for method chaining).
-	 */
-	public RestResponse setResponseBodyMeta(ResponsePartMeta rpm) {
-		this.resBodyMeta = rpm;
-		return this;
-	}
-
-	/**
 	 * Returns <jk>true</jk> if this response object is of the specified type.
 	 *
 	 * @param c The type to check against.
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/SwaggerGenerator.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/SwaggerGenerator.java
index 1bed25a..2cb0d7a 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/SwaggerGenerator.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/SwaggerGenerator.java
@@ -379,18 +379,6 @@ final class SwaggerGenerator {
 				}
 			}
 
-			if (hasAnnotation(ResponseBody.class, m)) {
-				ObjectMap om = responses.getObjectMap("200", true);
-				boolean usePS = false;
-				for (ResponseBody a : getAnnotationsParentFirst(ResponseBody.class, m)) {
-					merge(om, a);
-					usePS |= usePartSerializer(a);
-				}
-				if (usePS && ! om.containsKey("schema"))
-					om.appendSkipEmpty("schema", getSchema(om.getObjectMap("schema", true), m.getGenericReturnType()));
-				addXExamples(sm, om, "ok", m.getGenericReturnType());
-			}
-
 			if (hasAnnotation(Response.class, m)) {
 				boolean usePS = false;
 				for (Response a : getAnnotationsParentFirst(Response.class, m)) {
@@ -441,19 +429,6 @@ final class SwaggerGenerator {
 							}
 						}
 					}
-
-				} else if (in == RESPONSE_BODY) {
-					ObjectMap response = responses.getObjectMap("200", true);
-					boolean usePS = false;
-					for (ResponseBody a : getAnnotationsParentFirst(ResponseBody.class, mp.method, mp.index)) {
-						merge(response, a);
-						usePS |= usePartSerializer(a);
-					}
-					if (usePS && ! response.containsKey("schema")) {
-						Type type = Value.getParameterType(mp.type);
-						if (type != null)
-							response.appendSkipEmpty("schema", getSchema(response.getObjectMap("schema", true), type));
-					}
 				}
 			}
 
@@ -1088,19 +1063,6 @@ final class SwaggerGenerator {
 		;
 	}
 
-	private ObjectMap merge(ObjectMap om, ResponseBody a) throws ParseException {
-		if (empty(a))
-			return om;
-		om = newMap(om);
-		if (a.api().length > 0)
-			om.putAll(parseMap(a.api()));
-		return om
-			.appendSkipEmpty("x-example", resolve(a.example()))
-			.appendSkipEmpty("examples", joinnl(a.examples()))
-			.appendSkipEmpty("schema", merge(om.getObjectMap("schema"), a.schema()))
-		;
-	}
-
 	private ObjectMap merge(ObjectMap om, Response a) throws ParseException {
 		if (empty(a))
 			return om;
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/reshandlers/DefaultHandler.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/reshandlers/DefaultHandler.java
index c9004a6..8b9cf43 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/reshandlers/DefaultHandler.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/reshandlers/DefaultHandler.java
@@ -86,14 +86,14 @@ public class DefaultHandler implements ResponseHandler {
 				}
 			}
 
-			ResponseBeanPropertyMeta m = rbm.getBodyMethod();
+			Method m = rbm.getBodyMethod();
 			boolean usePartSerializer = rbm.isUsePartSerializer();
 			HttpPartSchema schema = rbm.getSchema();
 
 			if (m != null) {
 				try {
-					o = m.getGetter().invoke(o);
-					schema = m.getSchema();
+					o = m.invoke(o);
+					schema = rbm.getSchema();
 					usePartSerializer |= schema.isUsePartSerializer();
 				} catch (Exception e) {
 					throw new InternalServerError(e, "Could not get body.");
@@ -117,29 +117,6 @@ public class DefaultHandler implements ResponseHandler {
 			}
 		}
 
-		ResponsePartMeta rpm = res.getResponseBodyMeta();
-		if (rpm == null)
-			rpm = req.getResponseBodyMeta(o);
-
-		if (rpm != null && rpm.getSchema().isUsePartSerializer()) {
-			if (res.getContentType() == null)
-				res.setContentType("text/plain");
-			HttpPartSerializer ps = rpm.getSerializer();
-			if (ps == null)
-				ps = req.getPartSerializer();
-			if (ps != null) {
-				try (FinishablePrintWriter w = res.getNegotiatedWriter()) {
-					w.append(ps.serialize(HttpPartType.BODY, rpm.getSchema(), o));
-					w.flush();
-					w.finish();
-				} catch (SchemaValidationException | SerializeException e) {
-					throw new InternalServerError(e);
-				}
-				return true;
-			}
-		}
-
-
 		if (sm != null) {
 			Serializer s = sm.getSerializer();
 			MediaType mediaType = res.getMediaType();
diff --git a/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/ResponseAnnotationTest.java b/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/ResponseAnnotationTest.java
index c2e6a59..cd03b9c 100644
--- a/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/ResponseAnnotationTest.java
+++ b/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/ResponseAnnotationTest.java
@@ -22,9 +22,11 @@ import org.apache.juneau.*;
 import org.apache.juneau.dto.swagger.*;
 import org.apache.juneau.http.annotation.*;
 import org.apache.juneau.httppart.*;
+import org.apache.juneau.json.*;
 import org.apache.juneau.rest.*;
 import org.apache.juneau.rest.mock.*;
 import org.apache.juneau.serializer.*;
+import org.apache.juneau.utils.*;
 import org.junit.*;
 import org.junit.runners.*;
 
@@ -39,11 +41,15 @@ public class ResponseAnnotationTest {
 	// Setup
 	//=================================================================================================================
 
-	private static Swagger getSwagger(Object resource) throws Exception {
-		RestContext rc = RestContext.create(resource).build();
-		RestRequest req = rc.getCallHandler().createRequest(new MockServletRequest());
-		RestInfoProvider ip = rc.getInfoProvider();
-		return ip.getSwagger(req);
+	private static Swagger getSwagger(Object resource) {
+		try {
+			RestContext rc = RestContext.create(resource).build();
+			RestRequest req = rc.getCallHandler().createRequest(new MockServletRequest());
+			RestInfoProvider ip = rc.getInfoProvider();
+			return ip.getSwagger(req);
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
 	}
 
 
@@ -126,13 +132,13 @@ public class ResponseAnnotationTest {
 	@RestResource(partSerializer=XPartSerializer.class)
 	public static class B {
 
-		@ResponseBody(usePartSerializer=true)
+		@Response(usePartSerializer=true)
 		@RestMethod(name=GET,path="/useOnMethod")
 		public String b01() {
 			return "foo";
 		}
 
-		@ResponseBody(usePartSerializer=false)
+		@Response(usePartSerializer=false)
 		@RestMethod(name=GET,path="/dontUseOnMethod")
 		public String b02() {
 			return "foo";
@@ -159,12 +165,12 @@ public class ResponseAnnotationTest {
 		}
 
 		@RestMethod(name=GET,path="/useOnParameter")
-		public void b07(@ResponseBody(usePartSerializer=true) Value<String> value) {
+		public void b07(@Response(usePartSerializer=true) Value<String> value) {
 			value.set("foo");
 		}
 
 		@RestMethod(name=GET,path="/dontUseOnParameter")
-		public void b08(@ResponseBody(usePartSerializer=false) Value<String> value) {
+		public void b08(@Response(usePartSerializer=false) Value<String> value) {
 			value.set("foo");
 		}
 
@@ -244,7 +250,7 @@ public class ResponseAnnotationTest {
 	@RestResource
 	public static class C {
 
-		@ResponseBody(partSerializer=XPartSerializer.class)
+		@Response(partSerializer=XPartSerializer.class)
 		@RestMethod(name=GET,path="/useOnMethod")
 		public String c01() {
 			return "foo";
@@ -277,12 +283,12 @@ public class ResponseAnnotationTest {
 		}
 
 		@RestMethod(name=GET,path="/useOnParameter")
-		public void c07(@ResponseBody(partSerializer=XPartSerializer.class) Value<String> value) {
+		public void c07(@Response(partSerializer=XPartSerializer.class) Value<String> value) {
 			value.set("foo");
 		}
 
 		@RestMethod(name=GET,path="/dontUseOnParameter")
-		public void c08(@ResponseBody Value<String> value) {
+		public void c08(@Response Value<String> value) {
 			value.set("foo");
 		}
 
@@ -362,7 +368,7 @@ public class ResponseAnnotationTest {
 	@RestResource
 	public static class D {
 
-		@ResponseBody(schema=@Schema(collectionFormat="pipes"),usePartSerializer=true)
+		@Response(schema=@Schema(collectionFormat="pipes"),usePartSerializer=true)
 		@RestMethod(name=GET,path="/useOnMethod")
 		public String[] d01() {
 			return new String[]{"foo","bar"};
@@ -379,11 +385,11 @@ public class ResponseAnnotationTest {
 		}
 
 		@RestMethod(name=GET,path="/useOnParameter")
-		public void d04(@ResponseBody(schema=@Schema(collectionFormat="pipes"),usePartSerializer=true) Value<String[]> value) {
+		public void d04(@Response(schema=@Schema(collectionFormat="pipes"),usePartSerializer=true) Value<String[]> value) {
 			value.set(new String[]{"foo","bar"});
 		}
 
-		@ResponseBody(schema=@Schema(type="string",format="byte"),usePartSerializer=true)
+		@Response(schema=@Schema(type="string",format="byte"),usePartSerializer=true)
 		@RestMethod(name=GET,path="/useOnMethodBytes")
 		public byte[] d05() {
 			return "foo".getBytes();
@@ -401,7 +407,7 @@ public class ResponseAnnotationTest {
 
 
 		@RestMethod(name=GET,path="/useOnParameterBytes")
-		public void d08(@ResponseBody(schema=@Schema(type="string",format="byte"),usePartSerializer=true) Value<byte[]> value) {
+		public void d08(@Response(schema=@Schema(type="string",format="byte"),usePartSerializer=true) Value<byte[]> value) {
 			value.set("foo".getBytes());
 		}
 
@@ -479,6 +485,377 @@ public class ResponseAnnotationTest {
 	}
 
 
+	//-----------------------------------------------------------------------------------------------------------------
+	// Basic
+	//-----------------------------------------------------------------------------------------------------------------
+
+	@RestResource
+	public static class E {
+
+		@RestMethod
+		public void m01(@Response Value<E01> body) {
+			body.set(new E01());
+		}
+
+		@RestMethod
+		public void m02(Value<E02> body) {
+			body.set(new E02());
+		}
+
+		@RestMethod
+		@Response
+		public E01 m03() {
+			return new E01();
+		}
+
+		@RestMethod
+		public E02 m04() {
+			return new E02();
+		}
+	}
+
+	public static class E01 {
+		@Override
+		public String toString() {return "foo";}
+	}
+
+	@Response
+	public static class E02 {
+		@Override
+		public String toString() {return "foo";}
+	}
+
+	static MockRest e = MockRest.create(E.class);
+
+	@Test
+	public void e01_basic_onParameter() throws Exception {
+		e.get("/m01").execute().assertStatus(200).assertBody("foo");
+	}
+	@Test
+	public void e02_basic_onType() throws Exception {
+		e.get("/m02").execute().assertStatus(200).assertBody("foo");
+	}
+	@Test
+	public void e03_basic_onMethod() throws Exception {
+		e.get("/m03").execute().assertStatus(200).assertBody("foo");
+	}
+	@Test
+	public void e04_basic_onReturnedType() throws Exception {
+		e.get("/m04").execute().assertStatus(200).assertBody("foo");
+	}
+
+	//-----------------------------------------------------------------------------------------------------------------
+	// Basic swagger
+	//-----------------------------------------------------------------------------------------------------------------
+
+	@RestResource
+	public static class F {
+
+		@RestMethod
+		public void m01(@Response(schema=@Schema(description="f01", collectionFormat="pipes")) Value<List<Integer>> body) {
+			body.set(AList.create(1,2));
+		}
+
+		@RestMethod
+		public void m02(Value<F01> body) {
+			body.set(new F01());
+		}
+
+		@RestMethod
+		@Response(schema=@Schema(description="f03", collectionFormat="pipes"))
+		public List<Integer> m03() {
+			return AList.create(1,2);
+		}
+
+		@RestMethod
+		public F01 m04() {
+			return new F01();
+		}
+	}
+
+	@Response(schema=@Schema(description="f01", collectionFormat="pipes"))
+	public static class F01 extends ArrayList<Integer> {
+		public F01() {
+			add(1);
+			add(2);
+		}
+	}
+
+	static MockRest f = MockRest.create(F.class);
+	static Swagger sf = getSwagger(new F());
+
+	@Test
+	public void f01a_basic_onParameter() throws Exception {
+		f.get("/m01").execute().assertStatus(200).assertBody("1|2");
+	}
+	@Test
+	public void f01b_basic_onParameter_swagger() throws Exception {
+		ResponseInfo ri = sf.getResponseInfo("/m01", "get", 200);
+		assertObjectEquals("{description:'OK',schema:{description:'f01',collectionFormat:'pipes'}}", ri);
+	}
+	@Test
+	public void f02a_basic_onType() throws Exception {
+		f.get("/m02").execute().assertStatus(200).assertBody("1|2");
+	}
+	@Test
+	public void f02b_basic_onParameter_swagger() throws Exception {
+		ResponseInfo ri = sf.getResponseInfo("/m02", "get", 200);
+		assertObjectEquals("{description:'OK',schema:{description:'f01',collectionFormat:'pipes'}}", ri);
+	}
+	@Test
+	public void f03a_basic_onMethod() throws Exception {
+		f.get("/m03").execute().assertStatus(200).assertBody("1|2");
+	}
+	@Test
+	public void f03b_basic_onParameter_swagger() throws Exception {
+		ResponseInfo ri = sf.getResponseInfo("/m03", "get", 200);
+		assertObjectEquals("{description:'OK',schema:{description:'f03',collectionFormat:'pipes'}}", ri);
+	}
+	@Test
+	public void f04a_basic_onReturnedType() throws Exception {
+		f.get("/m04").execute().assertStatus(200).assertBody("1|2");
+	}
+	@Test
+	public void f04b_basic_onParameter_swagger() throws Exception {
+		ResponseInfo ri = sf.getResponseInfo("/m04", "get", 200);
+		assertObjectEquals("{description:'OK',schema:{description:'f01',collectionFormat:'pipes'}}", ri);
+	}
+
+	//-----------------------------------------------------------------------------------------------------------------
+	// Test JSON Accept
+	//-----------------------------------------------------------------------------------------------------------------
+
+	@RestResource(serializers=SimpleJsonSerializer.class)
+	public static class G {
+
+		@RestMethod
+		public void m01(@Response Value<List<Integer>> body) {
+			body.set(AList.create(1,2));
+		}
+
+		@RestMethod
+		public void m02(Value<G01> body) {
+			body.set(new G01());
+		}
+
+		@RestMethod
+		@Response
+		public List<Integer> m03() {
+			return AList.create(1,2);
+		}
+
+		@RestMethod
+		public G01 m04() {
+			return new G01();
+		}
+	}
+
+	@Response
+	public static class G01 extends ArrayList<Integer> {
+		public G01() {
+			add(1);
+			add(2);
+		}
+	}
+
+	static MockRest g = MockRest.create(G.class);
+	static Swagger sg = getSwagger(new G());
+
+	@Test
+	public void g01a_basic_onParameter() throws Exception {
+		g.get("/m01").json().execute().assertStatus(200).assertBody("[1,2]");
+	}
+	@Test
+	public void g01b_basic_onParameter_swagger() throws Exception {
+		ResponseInfo ri = sg.getResponseInfo("/m01", "get", 200);
+		assertObjectEquals("{description:'OK'}", ri);
+	}
+	@Test
+	public void g02a_basic_onType() throws Exception {
+		g.get("/m02").json().execute().assertStatus(200).assertBody("[1,2]");
+	}
+	@Test
+	public void g02b_basic_onParameter_swagger() throws Exception {
+		ResponseInfo ri = sg.getResponseInfo("/m02", "get", 200);
+		assertObjectEquals("{description:'OK'}", ri);
+	}
+	@Test
+	public void g03a_basic_onMethod() throws Exception {
+		g.get("/m03").json().execute().assertStatus(200).assertBody("[1,2]");
+	}
+	@Test
+	public void g03b_basic_onParameter_swagger() throws Exception {
+		ResponseInfo ri = sg.getResponseInfo("/m03", "get", 200);
+		assertObjectEquals("{description:'OK'}", ri);
+	}
+	@Test
+	public void g04a_basic_onReturnedType() throws Exception {
+		g.get("/m04").json().execute().assertStatus(200).assertBody("[1,2]");
+	}
+	@Test
+	public void g04b_basic_onParameter_swagger() throws Exception {
+		ResponseInfo ri = sg.getResponseInfo("/m04", "get", 200);
+		assertObjectEquals("{description:'OK'}", ri);
+	}
+
+	//=================================================================================================================
+	// PartSerializers
+	//=================================================================================================================
+
+	//-----------------------------------------------------------------------------------------------------------------
+	// @ResponseBody(usePartSerializer), partSerializer on class
+	//-----------------------------------------------------------------------------------------------------------------
+
+	@RestResource(partSerializer=XPartSerializer.class)
+	public static class H {
+
+		@RestMethod
+		public void m01(@Response(usePartSerializer=true) Value<List<Integer>> body) {
+			body.set(AList.create(1,2));
+		}
+
+		@RestMethod
+		public void m02(Value<H01> body) {
+			body.set(new H01());
+		}
+
+		@RestMethod
+		@Response(usePartSerializer=true)
+		public List<Integer> m03() {
+			return AList.create(1,2);
+		}
+
+		@RestMethod
+		public H01 m04() {
+			return new H01();
+		}
+	}
+
+	@Response(usePartSerializer=true)
+	public static class H01 extends ArrayList<Integer> {
+		public H01() {
+			add(1);
+			add(2);
+		}
+	}
+
+	static MockRest h = MockRest.create(H.class);
+	static Swagger sh = getSwagger(new H());
+
+	@Test
+	public void h01a_basic_onParameter() throws Exception {
+		h.get("/m01").execute().assertStatus(200).assertBody("x[1, 2]x");
+	}
+	@Test
+	public void h01b_basic_onParameter_swagger() throws Exception {
+		ResponseInfo ri = sh.getResponseInfo("/m01", "get", 200);
+		assertObjectEquals("{description:'OK',schema:{type:'array',items:{type:'integer',format:'int32'}}}", ri);
+	}
+	@Test
+	public void h02a_basic_onType() throws Exception {
+		h.get("/m02").execute().assertStatus(200).assertBody("x[1, 2]x");
+	}
+	@Test
+	public void h02b_basic_onParameter_swagger() throws Exception {
+		ResponseInfo ri = sh.getResponseInfo("/m02", "get", 200);
+		assertObjectEquals("{description:'OK',schema:{type:'array',items:{type:'integer',format:'int32'}}}", ri);
+	}
+	@Test
+	public void h03a_basic_onMethod() throws Exception {
+		h.get("/m03").execute().assertStatus(200).assertBody("x[1, 2]x");
+	}
+	@Test
+	public void h03b_basic_onParameter_swagger() throws Exception {
+		ResponseInfo ri = sh.getResponseInfo("/m03", "get", 200);
+		assertObjectEquals("{description:'OK',schema:{type:'array',items:{type:'integer',format:'int32'}}}", ri);
+	}
+	@Test
+	public void h04a_basic_onReturnedType() throws Exception {
+		h.get("/m04").execute().assertStatus(200).assertBody("x[1, 2]x");
+	}
+	@Test
+	public void h04b_basic_onParameter_swagger() throws Exception {
+		ResponseInfo ri = sh.getResponseInfo("/m04", "get", 200);
+		assertObjectEquals("{description:'OK',schema:{type:'array',items:{type:'integer',format:'int32'}}}", ri);
+	}
+
+	//-----------------------------------------------------------------------------------------------------------------
+	// @ResponseBody(usePartSerializer), partSerializer on part.
+	//-----------------------------------------------------------------------------------------------------------------
+
+	@RestResource
+	public static class I {
+
+		@RestMethod
+		public void m01(@Response(partSerializer=XPartSerializer.class) Value<List<Integer>> body) {
+			body.set(AList.create(1,2));
+		}
+
+		@RestMethod
+		public void m02(Value<I01> body) {
+			body.set(new I01());
+		}
+
+		@RestMethod
+		@Response(partSerializer=XPartSerializer.class)
+		public List<Integer> m03() {
+			return AList.create(1,2);
+		}
+
+		@RestMethod
+		public I01 m04() {
+			return new I01();
+		}
+	}
+
+	@Response(partSerializer=XPartSerializer.class)
+	public static class I01 extends ArrayList<Integer> {
+		public I01() {
+			add(1);
+			add(2);
+		}
+	}
+
+	static MockRest i = MockRest.create(I.class);
+	static Swagger si = getSwagger(new I());
+
+	@Test
+	public void i01a_basic_onParameter() throws Exception {
+		i.get("/m01").execute().assertStatus(200).assertBody("x[1, 2]x");
+	}
+	@Test
+	public void i01b_basic_onParameter_swagger() throws Exception {
+		ResponseInfo ri = si.getResponseInfo("/m01", "get", 200);
+		assertObjectEquals("{description:'OK',schema:{type:'array',items:{type:'integer',format:'int32'}}}", ri);
+	}
+	@Test
+	public void i02a_basic_onType() throws Exception {
+		i.get("/m02").execute().assertStatus(200).assertBody("x[1, 2]x");
+	}
+	@Test
+	public void i02b_basic_onParameter_swagger() throws Exception {
+		ResponseInfo ri = si.getResponseInfo("/m02", "get", 200);
+		assertObjectEquals("{description:'OK',schema:{type:'array',items:{type:'integer',format:'int32'}}}", ri);
+	}
+	@Test
+	public void i03a_basic_onMethod() throws Exception {
+		i.get("/m03").execute().assertStatus(200).assertBody("x[1, 2]x");
+	}
+	@Test
+	public void i03b_basic_onParameter_swagger() throws Exception {
+		ResponseInfo ri = si.getResponseInfo("/m03", "get", 200);
+		assertObjectEquals("{description:'OK',schema:{type:'array',items:{type:'integer',format:'int32'}}}", ri);
+	}
+	@Test
+	public void i04a_basic_onReturnedType() throws Exception {
+		i.get("/m04").execute().assertStatus(200).assertBody("x[1, 2]x");
+	}
+	@Test
+	public void i04b_basic_onParameter_swagger() throws Exception {
+		ResponseInfo ri = si.getResponseInfo("/m04", "get", 200);
+		assertObjectEquals("{description:'OK',schema:{type:'array',items:{type:'integer',format:'int32'}}}", ri);
+	}
+
 	//=================================================================================================================
 	// @Response on POJO
 	//=================================================================================================================
diff --git a/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/ResponseBodyAnnotationTest.java b/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/ResponseBodyAnnotationTest.java
index 0324663..6cbbdd4 100644
--- a/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/ResponseBodyAnnotationTest.java
+++ b/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/ResponseBodyAnnotationTest.java
@@ -12,441 +12,13 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.rest.annotation;
 
-import static org.apache.juneau.testutils.TestUtils.*;
-
-import java.util.*;
-
-import org.apache.juneau.*;
-import org.apache.juneau.dto.swagger.*;
-import org.apache.juneau.http.annotation.*;
-import org.apache.juneau.httppart.*;
-import org.apache.juneau.json.*;
-import org.apache.juneau.rest.*;
-import org.apache.juneau.rest.mock.*;
-import org.apache.juneau.serializer.*;
-import org.apache.juneau.utils.*;
 import org.junit.*;
 import org.junit.runners.*;
 
 /**
  * Tests the @Response annotation.
  */
-@SuppressWarnings({"javadoc","serial"})
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 public class ResponseBodyAnnotationTest {
 
-	//=================================================================================================================
-	// Setup
-	//=================================================================================================================
-
-	private static Swagger getSwagger(Object resource) {
-		try {
-			RestContext rc = RestContext.create(resource).build();
-			RestRequest req = rc.getCallHandler().createRequest(new MockServletRequest());
-			RestInfoProvider ip = rc.getInfoProvider();
-			return ip.getSwagger(req);
-		} catch (Exception e) {
-			throw new RuntimeException(e);
-		}
-	}
-
-
-	//=================================================================================================================
-	// Basic tests
-	//=================================================================================================================
-
-	//-----------------------------------------------------------------------------------------------------------------
-	// Basic
-	//-----------------------------------------------------------------------------------------------------------------
-
-	@RestResource
-	public static class A {
-
-		@RestMethod
-		public void m01(@ResponseBody Value<A01> body) {
-			body.set(new A01());
-		}
-
-		@RestMethod
-		public void m02(Value<A02> body) {
-			body.set(new A02());
-		}
-
-		@RestMethod
-		@ResponseBody
-		public A01 m03() {
-			return new A01();
-		}
-
-		@RestMethod
-		public A02 m04() {
-			return new A02();
-		}
-	}
-
-	public static class A01 {
-		@Override
-		public String toString() {return "foo";}
-	}
-
-	@ResponseBody
-	public static class A02 {
-		@Override
-		public String toString() {return "foo";}
-	}
-
-	static MockRest a = MockRest.create(A.class);
-
-	@Test
-	public void a01_basic_onParameter() throws Exception {
-		a.get("/m01").execute().assertStatus(200).assertBody("foo");
-	}
-	@Test
-	public void a02_basic_onType() throws Exception {
-		a.get("/m02").execute().assertStatus(200).assertBody("foo");
-	}
-	@Test
-	public void a03_basic_onMethod() throws Exception {
-		a.get("/m03").execute().assertStatus(200).assertBody("foo");
-	}
-	@Test
-	public void a04_basic_onReturnedType() throws Exception {
-		a.get("/m04").execute().assertStatus(200).assertBody("foo");
-	}
-
-	//-----------------------------------------------------------------------------------------------------------------
-	// Basic swagger
-	//-----------------------------------------------------------------------------------------------------------------
-
-	@RestResource
-	public static class B {
-
-		@RestMethod
-		public void m01(@ResponseBody(schema=@Schema(description="b01", collectionFormat="pipes")) Value<List<Integer>> body) {
-			body.set(AList.create(1,2));
-		}
-
-		@RestMethod
-		public void m02(Value<B01> body) {
-			body.set(new B01());
-		}
-
-		@RestMethod
-		@ResponseBody(schema=@Schema(description="b03", collectionFormat="pipes"))
-		public List<Integer> m03() {
-			return AList.create(1,2);
-		}
-
-		@RestMethod
-		public B01 m04() {
-			return new B01();
-		}
-	}
-
-	@ResponseBody(schema=@Schema(description="b01", collectionFormat="pipes"))
-	public static class B01 extends ArrayList<Integer> {
-		public B01() {
-			add(1);
-			add(2);
-		}
-	}
-
-	static MockRest b = MockRest.create(B.class);
-	static Swagger sb = getSwagger(new B());
-
-	@Test
-	public void b01a_basic_onParameter() throws Exception {
-		b.get("/m01").execute().assertStatus(200).assertBody("1|2");
-	}
-	@Test
-	public void b01b_basic_onParameter_swagger() throws Exception {
-		ResponseInfo ri = sb.getResponseInfo("/m01", "get", 200);
-		assertObjectEquals("{description:'OK',schema:{description:'b01',collectionFormat:'pipes'}}", ri);
-	}
-	@Test
-	public void b02a_basic_onType() throws Exception {
-		b.get("/m02").execute().assertStatus(200).assertBody("1|2");
-	}
-	@Test
-	public void b02b_basic_onParameter_swagger() throws Exception {
-		ResponseInfo ri = sb.getResponseInfo("/m02", "get", 200);
-		assertObjectEquals("{description:'OK',schema:{description:'b01',collectionFormat:'pipes'}}", ri);
-	}
-	@Test
-	public void b03a_basic_onMethod() throws Exception {
-		b.get("/m03").execute().assertStatus(200).assertBody("1|2");
-	}
-	@Test
-	public void b03b_basic_onParameter_swagger() throws Exception {
-		ResponseInfo ri = sb.getResponseInfo("/m03", "get", 200);
-		assertObjectEquals("{description:'OK',schema:{description:'b03',collectionFormat:'pipes'}}", ri);
-	}
-	@Test
-	public void b04a_basic_onReturnedType() throws Exception {
-		b.get("/m04").execute().assertStatus(200).assertBody("1|2");
-	}
-	@Test
-	public void b04b_basic_onParameter_swagger() throws Exception {
-		ResponseInfo ri = sb.getResponseInfo("/m04", "get", 200);
-		assertObjectEquals("{description:'OK',schema:{description:'b01',collectionFormat:'pipes'}}", ri);
-	}
-
-	//-----------------------------------------------------------------------------------------------------------------
-	// Test JSON Accept
-	//-----------------------------------------------------------------------------------------------------------------
-
-	@RestResource(serializers=SimpleJsonSerializer.class)
-	public static class C {
-
-		@RestMethod
-		public void m01(@ResponseBody Value<List<Integer>> body) {
-			body.set(AList.create(1,2));
-		}
-
-		@RestMethod
-		public void m02(Value<C01> body) {
-			body.set(new C01());
-		}
-
-		@RestMethod
-		@ResponseBody
-		public List<Integer> m03() {
-			return AList.create(1,2);
-		}
-
-		@RestMethod
-		public C01 m04() {
-			return new C01();
-		}
-	}
-
-	@ResponseBody
-	public static class C01 extends ArrayList<Integer> {
-		public C01() {
-			add(1);
-			add(2);
-		}
-	}
-
-	static MockRest c = MockRest.create(C.class);
-	static Swagger sc = getSwagger(new C());
-
-	@Test
-	public void c01a_basic_onParameter() throws Exception {
-		c.get("/m01").json().execute().assertStatus(200).assertBody("[1,2]");
-	}
-	@Test
-	public void c01b_basic_onParameter_swagger() throws Exception {
-		ResponseInfo ri = sc.getResponseInfo("/m01", "get", 200);
-		assertObjectEquals("{description:'OK'}", ri);
-	}
-	@Test
-	public void c02a_basic_onType() throws Exception {
-		c.get("/m02").json().execute().assertStatus(200).assertBody("[1,2]");
-	}
-	@Test
-	public void c02b_basic_onParameter_swagger() throws Exception {
-		ResponseInfo ri = sc.getResponseInfo("/m02", "get", 200);
-		assertObjectEquals("{description:'OK'}", ri);
-	}
-	@Test
-	public void c03a_basic_onMethod() throws Exception {
-		c.get("/m03").json().execute().assertStatus(200).assertBody("[1,2]");
-	}
-	@Test
-	public void c03b_basic_onParameter_swagger() throws Exception {
-		ResponseInfo ri = sc.getResponseInfo("/m03", "get", 200);
-		assertObjectEquals("{description:'OK'}", ri);
-	}
-	@Test
-	public void c04a_basic_onReturnedType() throws Exception {
-		c.get("/m04").json().execute().assertStatus(200).assertBody("[1,2]");
-	}
-	@Test
-	public void c04b_basic_onParameter_swagger() throws Exception {
-		ResponseInfo ri = sc.getResponseInfo("/m04", "get", 200);
-		assertObjectEquals("{description:'OK'}", ri);
-	}
-
-
-	//=================================================================================================================
-	// PartSerializers
-	//=================================================================================================================
-
-	public static class XPartSerializer implements HttpPartSerializer {
-		@Override
-		public HttpPartSerializerSession createSession(SerializerSessionArgs args) {
-			return new HttpPartSerializerSession() {
-				@Override
-				public String serialize(HttpPartType partType, HttpPartSchema schema, Object value) throws SerializeException, SchemaValidationException {
-					return "x" + value + "x";
-				}
-			};
-		}
-
-		@Override
-		public String serialize(HttpPartType partType, HttpPartSchema schema, Object value) throws SchemaValidationException, SerializeException {
-			return createSession(null).serialize(partType, schema, value);
-		}
-
-		@Override
-		public String serialize(HttpPartSchema schema, Object value) throws SchemaValidationException, SerializeException {
-			return createSession(null).serialize(null, schema, value);
-		}
-	}
-
-	//-----------------------------------------------------------------------------------------------------------------
-	// @ResponseBody(usePartSerializer), partSerializer on class
-	//-----------------------------------------------------------------------------------------------------------------
-
-	@RestResource(partSerializer=XPartSerializer.class)
-	public static class D {
-
-		@RestMethod
-		public void m01(@ResponseBody(usePartSerializer=true) Value<List<Integer>> body) {
-			body.set(AList.create(1,2));
-		}
-
-		@RestMethod
-		public void m02(Value<D01> body) {
-			body.set(new D01());
-		}
-
-		@RestMethod
-		@ResponseBody(usePartSerializer=true)
-		public List<Integer> m03() {
-			return AList.create(1,2);
-		}
-
-		@RestMethod
-		public D01 m04() {
-			return new D01();
-		}
-	}
-
-	@ResponseBody(usePartSerializer=true)
-	public static class D01 extends ArrayList<Integer> {
-		public D01() {
-			add(1);
-			add(2);
-		}
-	}
-
-	static MockRest d = MockRest.create(D.class);
-	static Swagger sd = getSwagger(new D());
-
-	@Test
-	public void d01a_basic_onParameter() throws Exception {
-		d.get("/m01").execute().assertStatus(200).assertBody("x[1, 2]x");
-	}
-	@Test
-	public void d01b_basic_onParameter_swagger() throws Exception {
-		ResponseInfo ri = sd.getResponseInfo("/m01", "get", 200);
-		assertObjectEquals("{description:'OK',schema:{type:'array',items:{type:'integer',format:'int32'}}}", ri);
-	}
-	@Test
-	public void d02a_basic_onType() throws Exception {
-		d.get("/m02").execute().assertStatus(200).assertBody("x[1, 2]x");
-	}
-	@Test
-	public void d02b_basic_onParameter_swagger() throws Exception {
-		ResponseInfo ri = sd.getResponseInfo("/m02", "get", 200);
-		assertObjectEquals("{description:'OK',schema:{type:'array',items:{type:'integer',format:'int32'}}}", ri);
-	}
-	@Test
-	public void d03a_basic_onMethod() throws Exception {
-		d.get("/m03").execute().assertStatus(200).assertBody("x[1, 2]x");
-	}
-	@Test
-	public void d03b_basic_onParameter_swagger() throws Exception {
-		ResponseInfo ri = sd.getResponseInfo("/m03", "get", 200);
-		assertObjectEquals("{description:'OK',schema:{type:'array',items:{type:'integer',format:'int32'}}}", ri);
-	}
-	@Test
-	public void d04a_basic_onReturnedType() throws Exception {
-		d.get("/m04").execute().assertStatus(200).assertBody("x[1, 2]x");
-	}
-	@Test
-	public void d04b_basic_onParameter_swagger() throws Exception {
-		ResponseInfo ri = sd.getResponseInfo("/m04", "get", 200);
-		assertObjectEquals("{description:'OK',schema:{type:'array',items:{type:'integer',format:'int32'}}}", ri);
-	}
-
-	//-----------------------------------------------------------------------------------------------------------------
-	// @ResponseBody(usePartSerializer), partSerializer on part.
-	//-----------------------------------------------------------------------------------------------------------------
-
-	@RestResource
-	public static class E {
-
-		@RestMethod
-		public void m01(@ResponseBody(partSerializer=XPartSerializer.class) Value<List<Integer>> body) {
-			body.set(AList.create(1,2));
-		}
-
-		@RestMethod
-		public void m02(Value<E01> body) {
-			body.set(new E01());
-		}
-
-		@RestMethod
-		@ResponseBody(partSerializer=XPartSerializer.class)
-		public List<Integer> m03() {
-			return AList.create(1,2);
-		}
-
-		@RestMethod
-		public E01 m04() {
-			return new E01();
-		}
-	}
-
-	@ResponseBody(partSerializer=XPartSerializer.class)
-	public static class E01 extends ArrayList<Integer> {
-		public E01() {
-			add(1);
-			add(2);
-		}
-	}
-
-	static MockRest e = MockRest.create(E.class);
-	static Swagger se = getSwagger(new E());
-
-	@Test
-	public void e01a_basic_onParameter() throws Exception {
-		e.get("/m01").execute().assertStatus(200).assertBody("x[1, 2]x");
-	}
-	@Test
-	public void e01b_basic_onParameter_swagger() throws Exception {
-		ResponseInfo ri = se.getResponseInfo("/m01", "get", 200);
-		assertObjectEquals("{description:'OK',schema:{type:'array',items:{type:'integer',format:'int32'}}}", ri);
-	}
-	@Test
-	public void e02a_basic_onType() throws Exception {
-		e.get("/m02").execute().assertStatus(200).assertBody("x[1, 2]x");
-	}
-	@Test
-	public void e02b_basic_onParameter_swagger() throws Exception {
-		ResponseInfo ri = se.getResponseInfo("/m02", "get", 200);
-		assertObjectEquals("{description:'OK',schema:{type:'array',items:{type:'integer',format:'int32'}}}", ri);
-	}
-	@Test
-	public void e03a_basic_onMethod() throws Exception {
-		e.get("/m03").execute().assertStatus(200).assertBody("x[1, 2]x");
-	}
-	@Test
-	public void e03b_basic_onParameter_swagger() throws Exception {
-		ResponseInfo ri = se.getResponseInfo("/m03", "get", 200);
-		assertObjectEquals("{description:'OK',schema:{type:'array',items:{type:'integer',format:'int32'}}}", ri);
-	}
-	@Test
-	public void e04a_basic_onReturnedType() throws Exception {
-		e.get("/m04").execute().assertStatus(200).assertBody("x[1, 2]x");
-	}
-	@Test
-	public void e04b_basic_onParameter_swagger() throws Exception {
-		ResponseInfo ri = se.getResponseInfo("/m04", "get", 200);
-		assertObjectEquals("{description:'OK',schema:{type:'array',items:{type:'integer',format:'int32'}}}", ri);
-	}
-
 }