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 1eaf420  REST refactoring
1eaf420 is described below

commit 1eaf420b896f105e3d7c6eae6765fe24308823f9
Author: JamesBognar <james.bog...@salesforce.com>
AuthorDate: Wed Feb 17 09:56:56 2021 -0500

    REST refactoring
---
 .../org/apache/juneau/assertions/Assertion.java    |  16 +-
 .../juneau/assertions/FluentStringAssertion.java   |   2 +-
 .../apache/juneau/rest/client/ResponseBody.java    | 299 +-------------------
 .../apache/juneau/rest/client/ResponseHeader.java  | 179 +-----------
 .../org/apache/juneau/rest/client/RestClient.java  |  13 +-
 .../apache/juneau/rest/client/RestResponse.java    |  66 +----
 .../assertion/FluentResponseBodyAssertion.java     | 306 +++++++++++++++++++++
 .../rest/client/RestClient_BasicCalls_Test.java    |   2 +-
 .../juneau/rest/client/RestClient_Body_Test.java   |  26 +-
 .../client/RestClient_Config_BeanContext_Test.java |   4 +-
 .../client/RestClient_Config_OpenApi_Test.java     |   6 +-
 .../rest/client/RestClient_FormData_Test.java      |  34 +--
 .../juneau/rest/client/RestClient_Query_Test.java  |  24 +-
 .../rest/client/RestClient_Response_Body_Test.java |  44 +--
 .../client/RestClient_Response_Headers_Test.java   |  30 +-
 .../rest/client/RestClient_Response_Test.java      |  18 +-
 16 files changed, 425 insertions(+), 644 deletions(-)

diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/assertions/Assertion.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/assertions/Assertion.java
index a73ab24..46171f0 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/assertions/Assertion.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/assertions/Assertion.java
@@ -86,14 +86,26 @@ public class Assertion {
         * @return A new {@link BasicAssertionError}.
         */
        protected BasicAssertionError error(String msg, Object...args) {
+               return error(null, msg, args);
+       }
+
+       /**
+        * Creates a new {@link BasicAssertionError}.
+        *
+        * @param cause Optional caused-by throwable.
+        * @param msg The message.
+        * @param args The message arguments.
+        * @return A new {@link BasicAssertionError}.
+        */
+       protected BasicAssertionError error(Throwable cause, String msg, 
Object...args) {
                msg = format(msg, args);
                if (this.msg != null)
-                       msg = format(this.msg, 
this.msgArgs).replace("<<<MSG>>>", msg);
+                       msg = format(this.msg, 
this.msgArgs).replace("<<<MSG>>>", msg).replace("<<<CAUSED-BY>>>", cause == 
null ? "" : "Caused by: " + cause.getMessage());
                if (stdout)
                        System.out.println(msg);  // NOT DEBUG
                if (stderr)
                        System.err.println(msg);  // NOT DEBUG
-               return new BasicAssertionError(msg);
+               return new BasicAssertionError(cause, msg);
        }
 
        /**
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/assertions/FluentStringAssertion.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/assertions/FluentStringAssertion.java
index 1438798..56ec3dd 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/assertions/FluentStringAssertion.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/assertions/FluentStringAssertion.java
@@ -360,7 +360,7 @@ public class FluentStringAssertion<R> extends 
FluentBaseAssertion<String,R> {
        }
 
        /**
-        * Asserts that the text is not empty.
+        * Asserts that the text is empty.
         *
         * @return The response object (for method chaining).
         * @throws AssertionError If assertion failed.
diff --git 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/ResponseBody.java
 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/ResponseBody.java
index 5b414b1..fee02de 100644
--- 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/ResponseBody.java
+++ 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/ResponseBody.java
@@ -24,7 +24,6 @@ import java.util.regex.*;
 import org.apache.http.*;
 import org.apache.http.conn.*;
 import org.apache.juneau.*;
-import org.apache.juneau.assertions.*;
 import org.apache.juneau.collections.*;
 import org.apache.juneau.http.*;
 import org.apache.juneau.httppart.*;
@@ -33,6 +32,7 @@ import org.apache.juneau.oapi.*;
 import org.apache.juneau.parser.*;
 import org.apache.juneau.parser.ParseException;
 import org.apache.juneau.reflect.*;
+import org.apache.juneau.rest.client.assertion.*;
 import org.apache.juneau.utils.*;
 
 /**
@@ -908,32 +908,6 @@ public class ResponseBody implements HttpEntity {
        }
 
        /**
-        * Same as {@link #as(Mutable,Class)} but allows you to run the call 
asynchronously.
-        *
-        * <ul class='notes'>
-        *      <li>
-        *              If {@link #cache()} or {@link RestResponse#cacheBody()} 
has been called, this method can be can be called multiple times and/or 
combined with
-        *              other methods that retrieve the content of the 
response.  Otherwise a {@link RestCallException}
-        *              with an inner {@link IllegalStateException} will be 
thrown.
-        *      <li>
-        *              The input stream is automatically closed after the 
execution of the future.
-        * </ul>
-        *
-        * @param <T> The class type of the object being created.
-        * @param m The mutable to set the parsed value in.
-        * @param type The object type to create.
-        * @return The response object (for method chaining).
-        * @throws RestCallException If the executor service was not defined.
-        * @see
-        *      RestClientBuilder#executorService(ExecutorService, boolean) for 
defining the executor service for creating
-        *      {@link Future Futures}.
-        */
-       public <T> RestResponse asFuture(Mutable<Future<T>> m, Class<T> type) 
throws RestCallException {
-               m.set(asFuture(type));
-               return response;
-       }
-
-       /**
         * Same as {@link #as(ClassMeta)} but allows you to run the call 
asynchronously.
         *
         * <ul class='notes'>
@@ -967,34 +941,6 @@ public class ResponseBody implements HttpEntity {
        }
 
        /**
-        * Same as {@link #as(Mutable,ClassMeta)} but allows you to run the 
call asynchronously.
-        *
-        * <ul class='notes'>
-        *      <li>
-        *              If {@link #cache()} or {@link RestResponse#cacheBody()} 
has been called, this method can be can be called multiple times and/or 
combined with
-        *              other methods that retrieve the content of the 
response.  Otherwise a {@link RestCallException}
-        *              with an inner {@link IllegalStateException} will be 
thrown.
-        *      <li>
-        *              The input stream is automatically closed after the 
execution of the future.
-        * </ul>
-        *
-        * @param <T>
-        *      The class type of the object being created.
-        *      See {@link #as(Type, Type...)} for details.
-        * @param m The mutable to set the parsed value in.
-        * @param type The object type to create.
-        * @return The response object (for method chaining).
-        * @throws RestCallException If the executor service was not defined.
-        * @see
-        *      RestClientBuilder#executorService(ExecutorService, boolean) for 
defining the executor service for creating
-        *      {@link Future Futures}.
-        */
-       public <T> RestResponse asFuture(Mutable<Future<T>>m, ClassMeta<T> 
type) throws RestCallException {
-               m.set(asFuture(type));
-               return response;
-       }
-
-       /**
         * Same as {@link #as(Type,Type...)} but allows you to run the call 
asynchronously.
         *
         * <ul class='notes'>
@@ -1034,40 +980,6 @@ public class ResponseBody implements HttpEntity {
        }
 
        /**
-        * Same as {@link #as(Mutable,Type,Type...)} but allows you to run the 
call asynchronously.
-        *
-        * <ul class='notes'>
-        *      <li>
-        *              If {@link #cache()} or {@link RestResponse#cacheBody()} 
has been called, this method can be can be called multiple times and/or 
combined with
-        *              other methods that retrieve the content of the 
response.  Otherwise a {@link RestCallException}
-        *              with an inner {@link IllegalStateException} will be 
thrown.
-        *      <li>
-        *              The input stream is automatically closed after the 
execution of the future.
-        * </ul>
-        *
-        * @param <T>
-        *      The class type of the object being created.
-        *      See {@link #as(Type, Type...)} for details.
-        * @param m The mutable to set the parsed value in.
-        * @param type
-        *      The object type to create.
-        *      <br>Can be any of the following: {@link ClassMeta}, {@link 
Class}, {@link ParameterizedType}, {@link GenericArrayType}
-        * @param args
-        *      The type arguments of the class if it's a collection or map.
-        *      <br>Can be any of the following: {@link ClassMeta}, {@link 
Class}, {@link ParameterizedType}, {@link GenericArrayType}
-        *      <br>Ignored if the main type is not a map or collection.
-        * @return The response object (for method chaining).
-        * @throws RestCallException If the executor service was not defined.
-        * @see
-        *      RestClientBuilder#executorService(ExecutorService, boolean) for 
defining the executor service for creating
-        *      {@link Future Futures}.
-        */
-       public <T> RestResponse asFuture(Mutable<Future<T>> m, Type type, 
Type...args) throws RestCallException {
-               m.set(asFuture(type, args));
-               return response;
-       }
-
-       /**
         * Returns the contents of this body as a string.
         *
         * <ul class='notes'>
@@ -1313,45 +1225,6 @@ public class ResponseBody implements HttpEntity {
        }
 
        /**
-        * Same as {@link #asMatcher(Pattern)} but sets the value in a mutable 
for fluent calls.
-        *
-        * <h5 class='section'>Example:</h5>
-        * <p class='bcode w800'>
-        *      <jc>// Parse response using a regular expression.</jc>
-        *      Mutable&lt;Matcher&gt; <jv>mutable</jv> = 
Mutable.<jsm>create</jsm>();
-        *
-        *      <jv>client</jv>
-        *              .get(<jsf>URI</jsf>)
-        *              .run()
-        *              .getBody().asMatcher(<jv>mutable</jv>, 
Pattern.<jsm>compile</jsm>(<js>"foo=(.*)"</js>))
-        *              .assertStatus().is(200);
-        *
-        *      <jk>if</jk> (<jv>matcher</jv>.get().matches()) {
-        *              String <jv>foo</jv> = <jv>matcher</jv>.get().group(1);
-        *      }
-        * </p>
-        *
-        *
-        * <ul class='notes'>
-        *      <li>
-        *              If no charset was found on the 
<code>Content-Type</code> response header, <js>"UTF-8"</js> is assumed.
-        *  <li>
-        *              This method automatically calls {@link #cache()} so 
that the body can be retrieved multiple times.
-        *      <li>
-        *              The input stream is automatically closed after this 
call.
-        * </ul>
-        *
-        * @param m The mutable to set the value in.
-        * @param pattern The regular expression pattern to match.
-        * @return The response object (for method chaining).
-        * @throws RestCallException If a connection error occurred.
-        */
-       public RestResponse asMatcher(Mutable<Matcher> m, Pattern pattern) 
throws RestCallException {
-               m.set(pattern.matcher(asString()));
-               return response;
-       }
-
-       /**
         * Converts the contents of the response body to a string and then 
matches the specified pattern against it.
         *
         * <h5 class='section'>Example:</h5>
@@ -1388,46 +1261,6 @@ public class ResponseBody implements HttpEntity {
        }
 
        /**
-        * Same as {@link #asMatcher(String)} but sets the value in a mutable 
for fluent calls.
-        *
-        * <h5 class='section'>Example:</h5>
-        * <p class='bcode w800'>
-        *      <jc>// Parse response using a regular expression.</jc>
-        *      Mutable&lt;Matcher&gt; <jv>mutable</jv> = 
Mutable.<jsm>create</jsm>();
-        *
-        *      <jv>client</jv>
-        *              .get(<jsf>URI</jsf>)
-        *              .run()
-        *              .getBody().asMatcher(<jv>mutable</jv>, 
<js>"foo=(.*)"</js>)
-        *              .assertStatus().is(200);
-        *
-        *      <jk>if</jk> (<jv>mutable</jv>.get().matches()) {
-        *              String <jv>foo</jv> = <jv>mutable</jv>.get().group(1);
-        *      }
-        *
-        *
-        * <ul class='notes'>
-        *      <li>
-        *              If no charset was found on the 
<code>Content-Type</code> response header, <js>"UTF-8"</js> is assumed.
-        *  <li>
-        *              If {@link #cache()} or {@link RestResponse#cacheBody()} 
has been called, this method can be can be called multiple times and/or 
combined with
-        *              other methods that retrieve the content of the 
response.  Otherwise a {@link RestCallException}
-        *              with an inner {@link IllegalStateException} will be 
thrown.
-        *      <li>
-        *              The input stream is automatically closed after this 
call.
-        * </ul>
-        *
-        * @param m The mutable to set the value in.
-        * @param regex The regular expression pattern to match.
-        * @return The response object (for method chaining).
-        * @throws RestCallException If a connection error occurred.
-        */
-       public RestResponse asMatcher(Mutable<Matcher> m, String regex) throws 
RestCallException {
-               asMatcher(m, regex, 0);
-               return response;
-       }
-
-       /**
         * Converts the contents of the response body to a string and then 
matches the specified pattern against it.
         *
         * <h5 class='section'>Example:</h5>
@@ -1465,48 +1298,6 @@ public class ResponseBody implements HttpEntity {
        }
 
        /**
-        * Same as {@link #asMatcher(String,int)} but sets the value in a 
mutable for fluent calls.
-        *
-        * <h5 class='section'>Example:</h5>
-        * <p class='bcode w800'>
-        *      <jc>// Parse response using a regular expression.</jc>
-        *      Mutable&lt;Matcher&gt; <jv>mutable</jv> = 
Mutable.<jsm>create</jsm>();
-        *
-        *      <jv>client</jv>
-        *              .get(<jsf>URI</jsf>)
-        *              .run()
-        *              .getBody().asMatcher(<jv>mutable</jv>, 
<js>"foo=(.*)"</js>, <jsf>MULTILINE</jsf> &amp; <jsf>CASE_INSENSITIVE</jsf>)
-        *              .assertStatus().is(200);
-        *
-        *      <jk>if</jk> (<jv>mutable</jv>.get().matches()) {
-        *              String <jv>foo</jv> = <jv>mutable</jv>.get().group(1);
-        *      }
-        * </p>
-        *
-        *
-        * <ul class='notes'>
-        *      <li>
-        *              If no charset was found on the 
<code>Content-Type</code> response header, <js>"UTF-8"</js> is assumed.
-        *  <li>
-        *              If {@link #cache()} or {@link RestResponse#cacheBody()} 
has been called, this method can be can be called multiple times and/or 
combined with
-        *              other methods that retrieve the content of the 
response.  Otherwise a {@link RestCallException}
-        *              with an inner {@link IllegalStateException} will be 
thrown.
-        *      <li>
-        *              The input stream is automatically closed after this 
call.
-        * </ul>
-        *
-        * @param m The mutable to set the value in.
-        * @param regex The regular expression pattern to match.
-        * @param flags Pattern match flags.  See {@link 
Pattern#compile(String, int)}.
-        * @return The response object (for method chaining).
-        * @throws RestCallException If a connection error occurred.
-        */
-       public RestResponse asMatcher(Mutable<Matcher> m, String regex, int 
flags) throws RestCallException {
-               asMatcher(m, Pattern.compile(regex, flags));
-               return response;
-       }
-
-       /**
         * Returns the response that created this object.
         *
         * @return The response that created this object.
@@ -1531,38 +1322,38 @@ public class ResponseBody implements HttpEntity {
         *      <jv>client</jv>
         *              .get(<jsf>URI</jsf>)
         *              .run()
-        *              .assertBody().equals(<js>"OK"</js>);
+        *              .getBody().assertValue().equals(<js>"OK"</js>);
         *
         *      <jc>// Validates the response body contains the text "OK".</jc>
         *      <jv>client</jv>
         *              .get(<jsf>URI</jsf>)
         *              .run()
-        *              .assertBody().contains(<js>"OK"</js>);
+        *              .getBody().assertValue().contains(<js>"OK"</js>);
         *
         *      <jc>// Validates the response body passes a predicate test.</jc>
         *      <jv>client</jv>
         *              .get(<jsf>URI</jsf>)
         *              .run()
-        *              .assertBody().passes(<jv>x</jv> -&gt; 
<jv>x</jv>.contains(<js>"OK"</js>));
+        *              .getBody().assertValue().passes(<jv>x</jv> -&gt; 
<jv>x</jv>.contains(<js>"OK"</js>));
         *
         *      <jc>// Validates the response body matches a regular 
expression.</jc>
         *      <jv>client</jv>
         *              .get(<jsf>URI</jsf>)
         *              .run()
-        *              .assertBody().matches(<js>".*OK.*"</js>);
+        *              .getBody().assertValue().matches(<js>".*OK.*"</js>);
         *
         *      <jc>// Validates the response body matches a regular expression 
using regex flags.</jc>
         *      <jv>client</jv>
         *              .get(<jsf>URI</jsf>)
         *              .run()
-        *              .assertBody().matches(<js>".*OK.*"</js>,  
<jsf>MULTILINE</jsf> &amp; <jsf>CASE_INSENSITIVE</jsf>);
+        *              .getBody().assertValue().matches(<js>".*OK.*"</js>,  
<jsf>MULTILINE</jsf> &amp; <jsf>CASE_INSENSITIVE</jsf>);
         *
         *      <jc>// Validates the response body matches a regular expression 
in the form of an existing Pattern.</jc>
         *      Pattern <jv>p</jv> = 
Pattern.<jsm>compile</jsm>(<js>".*OK.*"</js>);
         *      <jv>client</jv>
         *              .get(<jsf>URI</jsf>)
         *              .run()
-        *              .assertBody().matches(<jv>p</jv>);
+        *              .getBody().assertValue().matches(<jv>p</jv>);
         * </p>
         *
         * <p>
@@ -1572,8 +1363,8 @@ public class ResponseBody implements HttpEntity {
         *      MyBean <jv>bean</jv> = <jv>client</jv>
         *              .get(<jsf>URI</jsf>)
         *              .run()
-        *              .assertBody().matches(<js>".*OK.*"</js>);
-        *              .assertBody().doesNotMatch(<js>".*ERROR.*"</js>)
+        *              .getBody().assertValue().matches(<js>".*OK.*"</js>);
+        *              
.getBody().assertValue().doesNotMatch(<js>".*ERROR.*"</js>)
         *              .getBody().as(MyBean.<jk>class</jk>);
         * </p>
         *
@@ -1589,76 +1380,8 @@ public class ResponseBody implements HttpEntity {
         * @return A new fluent assertion object.
         * @throws RestCallException If REST call failed.
         */
-       public FluentStringAssertion<RestResponse> assertString() throws 
RestCallException {
-               return new FluentStringAssertion<>(asString(), response);
-       }
-
-       /**
-        * Provides the ability to perform fluent-style assertions on the bytes 
of the response body.
-        *
-        * <p>
-        * This method is called directly from the {@link 
RestResponse#assertBodyBytes()} method to instantiate a fluent assertions 
object.
-        *
-        * <h5 class='section'>Examples:</h5>
-        * <p class='bcode w800'>
-        *      <jc>// Validates the response body equals the text "foo".</jc>
-        *      <jv>client</jv>
-        *              .get(<jsf>URI</jsf>)
-        *              .run()
-        *              .assertBodyBytes().hex().is(<js>"666F6F"</js>);
-        * </p>
-        *
-        * <ul class='notes'>
-        *      <li>
-        *              If no charset was found on the 
<code>Content-Type</code> response header, <js>"UTF-8"</js> is assumed.
-        *  <li>
-        *              When using this method, the body is automatically 
cached by calling the {@link ResponseBody#cache()}.
-        *      <li>
-        *              The input stream is automatically closed after this 
call.
-        * </ul>
-        *
-        * @return A new fluent assertion object.
-        * @throws RestCallException If REST call failed.
-        */
-       public FluentByteArrayAssertion<RestResponse> assertBytes() throws 
RestCallException {
-               return new FluentByteArrayAssertion<>(asBytes(), response);
-       }
-
-       /**
-        * Provides the ability to perform fluent-style assertions on this 
response body.
-        *
-        * <p>
-        * This method is called directly from the {@link 
RestResponse#assertBody(Class)} method to instantiate a fluent assertions 
object.
-        *
-        * <p>
-        * Converts the body of the response to the specified object using 
{@link #as(Class)} and returns it as a fluent assertions object.
-        *
-        * <h5 class='section'>Examples:</h5>
-        * <p class='bcode w800'>
-        *      <jc>// Validates the response body bean is the expected 
value.</jc>
-        *      <jv>client</jv>
-        *              .get(<js>"/myBean"</js>)
-        *              .run()
-        *              
.assertBody(MyBean.<jk>class</jk>).json().is(<js>"{foo:'bar'}"</js>);
-        * </p>
-        *
-        * <ul class='notes'>
-        *      <li>
-        *              If no charset was found on the 
<code>Content-Type</code> response header, <js>"UTF-8"</js> is assumed.
-        *  <li>
-        *              If {@link #cache()} or {@link RestResponse#cacheBody()} 
has been called, this method can be can be called multiple times and/or 
combined with
-        *              other methods that retrieve the content of the 
response.  Otherwise a {@link RestCallException}
-        *              with an inner {@link IllegalStateException} will be 
thrown.
-        *      <li>
-        *              The input stream is automatically closed after this 
call.
-        * </ul>
-        *
-        * @param type The object type to create.
-        * @return A new fluent assertion object.
-        * @throws RestCallException If REST call failed.
-        */
-       public <T> FluentObjectAssertion<T,RestResponse> assertObject(Class<T> 
type) throws RestCallException {
-               return new FluentObjectAssertion<>(as(type), response);
+       public FluentResponseBodyAssertion<RestResponse> assertValue() throws 
RestCallException {
+               return new FluentResponseBodyAssertion<>(this, response);
        }
 
        
//------------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/ResponseHeader.java
 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/ResponseHeader.java
index 3d4a079..b16f81b 100644
--- 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/ResponseHeader.java
+++ 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/ResponseHeader.java
@@ -22,13 +22,13 @@ import java.util.regex.*;
 
 import org.apache.http.*;
 import org.apache.juneau.*;
-import org.apache.juneau.assertions.*;
 import org.apache.juneau.http.*;
 import org.apache.juneau.http.header.*;
 import org.apache.juneau.httppart.*;
 import org.apache.juneau.oapi.*;
 import org.apache.juneau.parser.ParseException;
 import org.apache.juneau.reflect.*;
+import org.apache.juneau.rest.client.assertion.*;
 import org.apache.juneau.utils.*;
 
 /**
@@ -421,34 +421,6 @@ public class ResponseHeader implements Header {
        }
 
        /**
-        * Same as {@link #asMatcher(Pattern)} but sets the value in a mutable 
for fluent calls.
-        *
-        * <h5 class='section'>Example:</h5>
-        * <p class='bcode w800'>
-        *      <jc>// Parse header using a regular expression.</jc>
-        *      Mutable&lt;Matcher&gt; <jv>mutable</jv> = 
Mutable.<jsm>create</jsm>();
-        *
-        *      <jv>client</jv>
-        *              .get(<jsf>URI</jsf>)
-        *              .run()
-        *              
.getHeader(<js>"Content-Type"</js>).asMatcher(<jv>mutable</jv>, 
Pattern.<jsm>compile</jsm>(<js>"application/(.*)"</js>));
-        *
-        *      <jk>if</jk> (<jv>mutable</jv>.get().matches()) {
-        *              String <jv>mediaType</jv> = 
<jv>mutable</jv>.get().group(1);
-        *      }
-        * </p>
-        *
-        * @param m The mutable to set the value in.
-        * @param pattern The regular expression pattern to match.
-        * @return The response object (for method chaining).
-        * @throws RestCallException If a connection error occurred.
-        */
-       public RestResponse asMatcher(Mutable<Matcher> m, Pattern pattern) 
throws RestCallException {
-               m.set(pattern.matcher(asString().orElse("")));
-               return response;
-       }
-
-       /**
         * Matches the specified pattern against this header value.
         *
         * <h5 class='section'>Example:</h5>
@@ -473,34 +445,6 @@ public class ResponseHeader implements Header {
        }
 
        /**
-        * Same as {@link #asMatcher(String)} but sets the value in a mutable 
for fluent calls.
-        *
-        * <h5 class='section'>Example:</h5>
-        * <p class='bcode w800'>
-        *      <jc>// Parse header using a regular expression.</jc>
-        *      Mutable&lt;Matcher&gt; <jv>mutable</jv> = 
Mutable.<jsm>create</jsm>();
-        *
-        *      <jv>client</jv>
-        *              .get(<jsf>URI</jsf>)
-        *              .run()
-        *              
.getHeader(<js>"Content-Type"</js>).asMatcher(<jv>mutable</jv>, 
<js>"application/(.*)"</js>);
-        *
-        *      <jk>if</jk> (<jv>mutable</jv>.get().matches()) {
-        *              String <jv>mediaType</jv> = 
<jv>mutable</jv>.get().group(1);
-        *      }
-        * </p>
-        *
-        * @param m The mutable to set the value in.
-        * @param regex The regular expression pattern to match.
-        * @return The response object (for method chaining).
-        * @throws RestCallException If a connection error occurred.
-        */
-       public RestResponse asMatcher(Mutable<Matcher> m, String regex) throws 
RestCallException {
-               m.set(asMatcher(regex, 0));
-               return response;
-       }
-
-       /**
         * Matches the specified pattern against this header value.
         *
         * <h5 class='section'>Example:</h5>
@@ -526,35 +470,6 @@ public class ResponseHeader implements Header {
        }
 
        /**
-        * Same as {@link #asMatcher(String,int)} but sets the value in a 
mutable for fluent calls.
-        *
-        * <h5 class='section'>Example:</h5>
-        * <p class='bcode w800'>
-        *      <jc>// Parse header using a regular expression.</jc>
-        *      Mutable&lt;Matcher&gt; <jv>mutable</jv> = 
Mutable.<jsm>create</jsm>();
-        *
-        *      client
-        *              .get(<jsf>URI</jsf>)
-        *              .run()
-        *              
.getHeader(<js>"Content-Type"</js>).asMatcher(<jv>mutable</jv>, 
<js>"application/(.*)"</js>, <jsf>CASE_INSENSITIVE</jsf>);
-        *
-        *      <jk>if</jk> (<jv>mutable</jv>.get().matches()) {
-        *              String <jv>mediaType</jv> = 
<jv>mutable</jv>.get().group(1);
-        *      }
-        * </p>
-        *
-        * @param m The mutable to set the value in.
-        * @param regex The regular expression pattern to match.
-        * @param flags Pattern match flags.  See {@link 
Pattern#compile(String, int)}.
-        * @return The response object (for method chaining).
-        * @throws RestCallException If a connection error occurred.
-        */
-       public RestResponse asMatcher(Mutable<Matcher> m, String regex, int 
flags) throws RestCallException {
-               m.set(asMatcher(Pattern.compile(regex, flags)));
-               return response;
-       }
-
-       /**
         * Returns the response that created this object.
         *
         * @return The response that created this object.
@@ -576,37 +491,37 @@ public class ResponseHeader implements Header {
         *      <jv>client</jv>
         *              .get(<jsf>URI</jsf>)
         *              .run()
-        *              .assertHeader(<js>"Content-Type"</js>).exists();
+        *              
.getHeader(<js>"Content-Type"</js>).assertValue().exists();
         *
         *      <jc>// Validates the content type is JSON.</jc>
         *      <jv>client</jv>
         *              .get(<jsf>URI</jsf>)
         *              .run()
-        *              
.assertHeader(<js>"Content-Type"</js>).equals(<js>"application/json"</js>);
+        *              
.getHeader(<js>"Content-Type"</js>).equals(<js>"application/json"</js>);
         *
         *      <jc>// Validates the content type is JSON using test 
predicate.</jc>
         *      <jv>client</jv>
         *              .get(<jsf>URI</jsf>)
         *              .run()
-        *              
.assertHeader(<js>"Content-Type"</js>).passes(<jv>x</jv> -&gt; 
<jv>x</jv>.equals(<js>"application/json"</js>));
+        *              
.getHeader(<js>"Content-Type"</js>).assertValue().passes(<jv>x</jv> -&gt; 
<jv>x</jv>.equals(<js>"application/json"</js>));
         *
         *      <jc>// Validates the content type is JSON by just checking for 
substring.</jc>
         *      <jv>client</jv>
         *              .get(<jsf>URI</jsf>)
         *              .run()
-        *              
.assertHeader(<js>"Content-Type"</js>).contains(<js>"json"</js>);
+        *              
.getHeader(<js>"Content-Type"</js>).assertValue().contains(<js>"json"</js>);
         *
         *      <jc>// Validates the content type is JSON using regular 
expression.</jc>
         *      <jv>client</jv>
         *              .get(<jsf>URI</jsf>)
         *              .run()
-        *              
.assertHeader(<js>"Content-Type"</js>).matches(<js>".*json.*"</js>);
+        *              
.getHeader(<js>"Content-Type"</js>).assertValue().matches(<js>".*json.*"</js>);
         *
         *      <jc>// Validates the content type is JSON using 
case-insensitive regular expression.</jc>
         *      <jv>client</jv>
         *              .get(<jsf>URI</jsf>)
         *              .run()
-        *              
.assertHeader(<js>"Content-Type"</js>).matches(<js>".*json.*"</js>, 
<jsf>CASE_INSENSITIVE</jsf>);
+        *              
.getHeader(<js>"Content-Type"</js>).assertValue().matches(<js>".*json.*"</js>, 
<jsf>CASE_INSENSITIVE</jsf>);
         * </p>
         *
         * <p>
@@ -616,87 +531,15 @@ public class ResponseHeader implements Header {
         *      MediaType <jv>mediaType</jv> = <jv>client</jv>
         *              .get(<jsf>URI</jsf>)
         *              .run()
-        *              .assertHeader(<js>"Content-Type"</js>).exists()
-        *              
.assertHeader(<js>"Content-Type"</js>).matches(<js>".*json.*"</js>)
+        *              
.getHeader(<js>"Content-Type"</js>).assertValue().exists()
+        *              
.getHeader(<js>"Content-Type"</js>).assertValue().matches(<js>".*json.*"</js>)
         *              
.getHeader(<js>"Content-Type"</js>).as(MediaType.<jk>class</jk>);
         * </p>
         *
         * @return A new fluent assertion object.
         */
-       public FluentStringAssertion<RestResponse> assertString() {
-               return new FluentStringAssertion<>(asString().orElse(null), 
response);
-       }
-
-       /**
-        * Provides the ability to perform fluent-style assertions on an 
integer response header.
-        *
-        * <h5 class='section'>Examples:</h5>
-        * <p class='bcode w800'>
-        *      <jc>// Validates that the response content age is greater than 
1.</jc>
-        *      <jv>client</jv>
-        *              .get(<jsf>URI</jsf>)
-        *              .run()
-        *              .assertIntegerHeader(<js>"Age"</js>).isGreaterThan(1);
-        * </p>
-        *
-        * @return A new fluent assertion object.
-        */
-       public FluentIntegerAssertion<RestResponse> assertInteger() {
-               return new 
FluentIntegerAssertion<>(asIntegerHeader().asInteger().orElse(null), response);
-       }
-
-       /**
-        * Provides the ability to perform fluent-style assertions on a long 
response header.
-        *
-        * <h5 class='section'>Examples:</h5>
-        * <p class='bcode w800'>
-        *      <jc>// Validates that the response body is not too long.</jc>
-        *      <jv>client</jv>
-        *              .get(<jsf>URI</jsf>)
-        *              .run()
-        *              .assertLongHeader(<js>"Length"</js>).isLessThan(100000);
-        * </p>
-        *
-        * @return A new fluent assertion object.
-        */
-       public FluentLongAssertion<RestResponse> assertLong() {
-               return new 
FluentLongAssertion<>(asLongHeader().asLong().orElse(null), response);
-       }
-
-       /**
-        * Provides the ability to perform fluent-style assertions on a date 
response header.
-        *
-        * <h5 class='section'>Examples:</h5>
-        * <p class='bcode w800'>
-        *      <jc>// Validates that the response content is not expired.</jc>
-        *      <jv>client</jv>
-        *              .get(<jsf>URI</jsf>)
-        *              .run()
-        *              
.getHeader(<js>"Expires"</js>).assertDate().isAfterNow();
-        * </p>
-        *
-        * @return A new fluent assertion object.
-        */
-       public FluentZonedDateTimeAssertion<RestResponse> assertDate() {
-               return new 
FluentZonedDateTimeAssertion<>(asDateHeader().asZonedDateTime().orElse(null), 
response);
-       }
-
-       /**
-        * Provides the ability to perform fluent-style assertions on 
comma-separated string headers.
-        *
-        * <h5 class='section'>Examples:</h5>
-        * <p class='bcode w800'>
-        *      <jc>// Validates that the response content is not expired.</jc>
-        *      <jv>client</jv>
-        *              .get(<jsf>URI</jsf>)
-        *              .run()
-        *              
.getHeader(<js>"Allow"</js>).assertCsvArray().contains(<js>"GET"</js>);
-        * </p>
-        *
-        * @return A new fluent assertion object.
-        */
-       public FluentListAssertion<RestResponse> assertCsvArray() {
-               return new 
FluentListAssertion<>(asCsvArrayHeader().asList().orElse(null), response);
+       public FluentResponseHeaderAssertion<RestResponse> assertValue() {
+               return new FluentResponseHeaderAssertion<>(this, response);
        }
 
        
//------------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
index a35243d..81cb4eb 100644
--- 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
+++ 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
@@ -48,7 +48,6 @@ import org.apache.http.params.*;
 import org.apache.http.protocol.*;
 import org.apache.juneau.*;
 import org.apache.juneau.annotation.*;
-import org.apache.juneau.assertions.*;
 import org.apache.juneau.collections.*;
 import org.apache.juneau.cp.*;
 import org.apache.juneau.http.remote.RemoteReturn;
@@ -63,6 +62,7 @@ import org.apache.juneau.oapi.*;
 import org.apache.juneau.parser.*;
 import org.apache.juneau.parser.ParseException;
 import org.apache.juneau.reflect.*;
+import org.apache.juneau.rest.client.assertion.*;
 import org.apache.juneau.rest.client.remote.*;
 import org.apache.juneau.serializer.*;
 import org.apache.juneau.urlencoding.*;
@@ -639,10 +639,7 @@ import org.apache.juneau.utils.*;
  * <ul class='javatree'>
  *     <li class='jc'>{@link ResponseHeader}
  *     <ul>
- *             <li class='jm'><c>{@link ResponseHeader#assertString() 
assertString()} <jk>returns</jk> {@link FluentStringAssertion}</c>
- *             <li class='jm'><c>{@link ResponseHeader#assertInteger() 
assertInteger()} <jk>returns</jk> {@link FluentIntegerAssertion}</c>
- *             <li class='jm'><c>{@link ResponseHeader#assertLong() 
assertLong()} <jk>returns</jk> {@link FluentLongAssertion}</c>
- *             <li class='jm'><c>{@link ResponseHeader#assertDate() 
assertDate()} <jk>returns</jk> {@link FluentDateAssertion}</c>
+ *             <li class='jm'><c>{@link ResponseHeader#assertValue() 
assertValue()} <jk>returns</jk> {@link FluentResponseHeaderAssertion}</c>
  *     </ul>
  * </ul>
  *
@@ -655,7 +652,7 @@ import org.apache.juneau.utils.*;
  *     <jc>// Assert the response content type is any sort of JSON.</jc>
  *     String <jv>body</jv> = <jv>client</jv>.get(<jsf>URI</jsf>)
  *             .run()
- *             
.getHeader(<js>"Content-Type"</js>).assertString().matchesSimple(<js>"application/json*"</js>)
+ *             
.getHeader(<js>"Content-Type"</js>).assertValue().matchesSimple(<js>"application/json*"</js>)
  *             .getBody().asString();
  * </p>
  *
@@ -756,9 +753,7 @@ import org.apache.juneau.utils.*;
  * <ul class='javatree'>
  *     <li class='jc'>{@link ResponseBody}
  *     <ul>
- *             <li class='jm'><c>{@link ResponseBody#assertString() 
assertString()} <jk>returns</jk> {@link FluentStringAssertion}</c>
- *             <li class='jm'><c>{@link ResponseBody#assertObject(Class) 
assertObject(Class&lt;?&gt;)} <jk>returns</jk> {@link FluentObjectAssertion}</c>
- *             <li class='jm'><c>{@link ResponseBody#assertBytes() 
assertBytes()} <jk>returns</jk> {@link FluentByteArrayAssertion}</c>
+ *             <li class='jm'><c>{@link ResponseBody#assertValue() 
assertValue()} <jk>returns</jk> {@link FluentResponseBodyAssertion}</c>
  *     </ul>
  * </ul>
  *
diff --git 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestResponse.java
 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestResponse.java
index 78b44e8..1c1a4bf 100644
--- 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestResponse.java
+++ 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestResponse.java
@@ -417,70 +417,8 @@ public class RestResponse implements HttpResponse {
         * @return A new fluent assertion object.
         * @throws RestCallException If REST call failed.
         */
-       public FluentStringAssertion<RestResponse> assertBody() throws 
RestCallException {
-               return responseBody.cache().assertString();
-       }
-
-       /**
-        * Provides the ability to perform fluent-style assertions on the bytes 
of the response body.
-        *
-        * <h5 class='section'>Examples:</h5>
-        * <p class='bcode w800'>
-        *      <jc>// Validates the response body equals the text "foo".</jc>
-        *      <jv>client</jv>
-        *              .get(<jsf>URI</jsf>)
-        *              .run()
-        *              .assertBodyBytes().hex().is(<js>"666F6F"</js>);
-        * </p>
-        *
-        * <ul class='notes'>
-        *      <li>
-        *              If no charset was found on the 
<code>Content-Type</code> response header, <js>"UTF-8"</js> is assumed.
-        *  <li>
-        *              When using this method, the body is automatically 
cached by calling the {@link ResponseBody#cache()}.
-        *      <li>
-        *              The input stream is automatically closed after this 
call.
-        * </ul>
-        *
-        * @return A new fluent assertion object.
-        * @throws RestCallException If REST call failed.
-        */
-       public FluentByteArrayAssertion<RestResponse> assertBodyBytes() throws 
RestCallException {
-               return responseBody.cache().assertBytes();
-       }
-
-       /**
-        * Provides the ability to perform fluent-style assertions on this 
response body.
-        *
-        * <p>
-        * <p>
-        * Combines the functionality of {@link ResponseBody#as(Class)} with 
{@link #assertBody()} by converting the body to the specified
-        * bean and then serializing it to simplified JSON for easy string 
comparison.
-        *
-        * <h5 class='section'>Examples:</h5>
-        * <p class='bcode w800'>
-        *      <jc>// Validates the response body bean is the expected 
value.</jc>
-        *      <jv>client</jv>
-        *              .get(<js>"/myBean"</js>)
-        *              .run()
-        *              
.assertBody(MyBean.<jk>class</jk>).json().is(<js>"{foo:'bar'}"</js>);
-        * </p>
-        *
-        * <ul class='notes'>
-        *      <li>
-        *              If no charset was found on the 
<code>Content-Type</code> response header, <js>"UTF-8"</js> is assumed.
-        *  <li>
-        *              When using this method, the body is automatically 
cached by calling the {@link ResponseBody#cache()}.
-        *      <li>
-        *              The input stream is automatically closed after this 
call.
-        * </ul>
-        *
-        * @param type The object type to create.
-        * @return A new fluent assertion object.
-        * @throws RestCallException If REST call failed.
-        */
-       public <V> FluentObjectAssertion<V,RestResponse> assertBody(Class<V> 
type) throws RestCallException {
-               return responseBody.cache().assertObject(type);
+       public FluentResponseBodyAssertion<RestResponse> assertBody() throws 
RestCallException {
+               return new FluentResponseBodyAssertion<>(responseBody, this);
        }
 
        /**
diff --git 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/assertion/FluentResponseBodyAssertion.java
 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/assertion/FluentResponseBodyAssertion.java
new file mode 100644
index 0000000..d113748
--- /dev/null
+++ 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/assertion/FluentResponseBodyAssertion.java
@@ -0,0 +1,306 @@
+// 
***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright 
ownership.  The ASF licenses this file        *
+// * to you 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.apache.juneau.rest.client.assertion;
+
+import java.util.function.*;
+
+import org.apache.juneau.assertions.*;
+import org.apache.juneau.internal.*;
+import org.apache.juneau.rest.client.*;
+
+/**
+ * Used for fluent assertion calls against {@link ResponseBody} objects.
+ *
+ * @param <R> The return type.
+ */
+@FluentSetters(returns="FluentResponseBodyAssertion<R>")
+public class FluentResponseBodyAssertion<R> extends FluentAssertion<R> {
+
+       private final ResponseBody value;
+
+       /**
+        * Constructor.
+        *
+        * @param value The object being tested.
+        * @param returns The object to return after the test.
+        */
+       public FluentResponseBodyAssertion(ResponseBody value, R returns) {
+               this(null, value, returns);
+       }
+
+       /**
+        * Constructor.
+        *
+        * @param creator The assertion that created this assertion.
+        * @param value The object being tested.
+        * @param returns The object to return after the test.
+        */
+       public FluentResponseBodyAssertion(Assertion creator, ResponseBody 
value, R returns) {
+               super(creator, returns);
+               this.value = value;
+       }
+
+       /**
+        * Provides the ability to perform fluent-style assertions on this 
response body.
+        *
+        * <h5 class='section'>Examples:</h5>
+        * <p class='bcode w800'>
+        *      <jc>// Validates the response body equals the text "OK".</jc>
+        *      <jv>client</jv>
+        *              .get(<jsf>URI</jsf>)
+        *              .run()
+        *              .assertBody().is(<js>"OK"</js>);
+        *
+        *      <jc>// Validates the response body contains the text "OK".</jc>
+        *      <jv>client</jv>
+        *              .get(<jsf>URI</jsf>)
+        *              .run()
+        *              .assertBody().contains(<js>"OK"</js>);
+        *
+        *      <jc>// Validates the response body passes a predicate test.</jc>
+        *      <jv>client</jv>
+        *              .get(<jsf>URI</jsf>)
+        *              .run()
+        *              .assertBody().passes(<jv>x</jv> -&gt; 
<jv>x</jv>.contains(<js>"OK"</js>));
+        *
+        *      <jc>// Validates the response body matches a regular 
expression.</jc>
+        *      <jv>client</jv>
+        *              .get(<jsf>URI</jsf>)
+        *              .run()
+        *              .assertBody().matches(<js>".*OK.*"</js>);
+        *
+        *      <jc>// Validates the response body matches a regular expression 
using regex flags.</jc>
+        *      <jv>client</jv>
+        *              .get(<jsf>URI</jsf>)
+        *              .run()
+        *              .assertBody().matches(<js>".*OK.*"</js>, 
<jsf>MULTILINE</jsf> &amp; <jsf>CASE_INSENSITIVE</jsf>);
+        *
+        *      <jc>// Validates the response body matches a regular expression 
in the form of an existing Pattern.</jc>
+        *      Pattern <jv>p</jv> = 
Pattern.<jsm>compile</jsm>(<js>".*OK.*"</js>);
+        *      <jv>client</jv>
+        *              .get(<jsf>URI</jsf>)
+        *              .run()
+        *              .assertBody().matches(<jv>p</jv>);
+        * </p>
+        *
+        * <p>
+        * The assertion test returns the original response object allowing you 
to chain multiple requests like so:
+        * <p class='bcode w800'>
+        *      <jc>// Validates the response body matches a regular 
expression.</jc>
+        *      MyBean <jv>bean</jv> = <jv>client</jv>
+        *              .get(<jsf>URI</jsf>)
+        *              .run()
+        *              .assertBody().matches(<js>".*OK.*"</js>);
+        *              .assertBody().doesNotMatch(<js>".*ERROR.*"</js>)
+        *              .getBody().as(MyBean.<jk>class</jk>);
+        * </p>
+        *
+        * <ul class='notes'>
+        *      <li>
+        *              If no charset was found on the 
<code>Content-Type</code> response header, <js>"UTF-8"</js> is assumed.
+        *  <li>
+        *              When using this method, the body is automatically 
cached by calling the {@link ResponseBody#cache()}.
+        *      <li>
+        *              The input stream is automatically closed after this 
call.
+        * </ul>
+        *
+        * @return A new fluent assertion object.
+        */
+       public FluentStringAssertion<R> asString() {
+               return new FluentStringAssertion<>(valueAsString(), returns());
+       }
+
+       /**
+        * Provides the ability to perform fluent-style assertions on the bytes 
of the response body.
+        *
+        * <h5 class='section'>Examples:</h5>
+        * <p class='bcode w800'>
+        *      <jc>// Validates the response body equals the text "foo".</jc>
+        *      <jv>client</jv>
+        *              .get(<jsf>URI</jsf>)
+        *              .run()
+        *              .assertBodyBytes().hex().is(<js>"666F6F"</js>);
+        * </p>
+        *
+        * <ul class='notes'>
+        *      <li>
+        *              If no charset was found on the 
<code>Content-Type</code> response header, <js>"UTF-8"</js> is assumed.
+        *  <li>
+        *              When using this method, the body is automatically 
cached by calling the {@link ResponseBody#cache()}.
+        *      <li>
+        *              The input stream is automatically closed after this 
call.
+        * </ul>
+        *
+        * @return A new fluent assertion object.
+        * @throws RestCallException If REST call failed.
+        */
+       public FluentByteArrayAssertion<R> asBytes() throws RestCallException {
+               return new FluentByteArrayAssertion<>(valueAsBytes(), 
returns());
+       }
+
+       /**
+        * Provides the ability to perform fluent-style assertions on this 
response body.
+        *
+        * <p>
+        * Converts the body to a type using {@link ResponseBody#as(Class)} and 
then returns the value as an object assertion.
+        *
+        * <h5 class='section'>Examples:</h5>
+        * <p class='bcode w800'>
+        *      <jc>// Validates the response body bean is the expected 
value.</jc>
+        *      <jv>client</jv>
+        *              .get(<js>"/myBean"</js>)
+        *              .run()
+        *              
.assertBody().asType(MyBean.<jk>class</jk>).json().is(<js>"{foo:'bar'}"</js>);
+        * </p>
+        *
+        * <ul class='notes'>
+        *      <li>
+        *              If no charset was found on the 
<code>Content-Type</code> response header, <js>"UTF-8"</js> is assumed.
+        *  <li>
+        *              When using this method, the body is automatically 
cached by calling the {@link ResponseBody#cache()}.
+        *      <li>
+        *              The input stream is automatically closed after this 
call.
+        * </ul>
+        *
+        * @param type The object type to create.
+        * @return A new fluent assertion object.
+        * @throws RestCallException If REST call failed.
+        */
+       public <V> FluentObjectAssertion<V,R> asType(Class<V> type) throws 
RestCallException {
+               return new FluentObjectAssertion<>(valueAsType(type), 
returns());
+       }
+
+       /**
+        * Asserts that the value equals the specified value.
+        *
+        * @param value The value to check against.
+        * @return The response object (for method chaining).
+        * @throws AssertionError If assertion failed.
+        */
+       public R isEqual(String value) throws AssertionError {
+               return asString().isEqual(value);
+       }
+
+       /**
+        * Asserts that the body contains the specified value.
+        *
+        * @param values The value to check against.
+        * @return The response object (for method chaining).
+        * @throws AssertionError If assertion failed.
+        */
+       public R is(String values) throws AssertionError {
+               return asString().is(values);
+       }
+
+       /**
+        * Asserts that the text contains all of the specified substrings.
+        *
+        * @param values The values to check against.
+        * @return The response object (for method chaining).
+        * @throws AssertionError If assertion failed.
+        */
+       public R contains(String...values) throws AssertionError {
+               return asString().contains(values);
+       }
+
+       /**
+        * Asserts that the body doesn't contain any of the specified 
substrings.
+        *
+        * @param values The values to check against.
+        * @return The response object (for method chaining).
+        * @throws AssertionError If assertion failed.
+        */
+       public R doesNotContain(String...values) throws AssertionError {
+               return asString().doesNotContain(values);
+       }
+
+       /**
+        * Asserts that the body is empty.
+        *
+        * @return The response object (for method chaining).
+        * @throws AssertionError If assertion failed.
+        */
+       public R isEmpty() {
+               return asString().isEmpty();
+       }
+
+       /**
+        * Asserts that the body is not empty.
+        *
+        * @return The response object (for method chaining).
+        * @throws AssertionError If assertion failed.
+        */
+       public R isNotEmpty() {
+               return asString().isNotEmpty();
+       }
+
+       /**
+        * Asserts that the value passes the specified predicate test.
+        *
+        * @param test The predicate to use to test the value.
+        * @return The response object (for method chaining).
+        * @throws AssertionError If assertion failed.
+        */
+       public R passes(Predicate<String> test) throws AssertionError {
+               if (! test.test(valueAsString()))
+                       throw error("Value did not pass predicate 
test.\n\tValue=[{0}]", value);
+               return returns();
+       }
+
+       private String valueAsString() throws AssertionError {
+               try {
+                       return value.cache().asString();
+               } catch (RestCallException e) {
+                       throw error(e, "Exception occurred during call.");
+               }
+       }
+
+       private byte[] valueAsBytes() throws AssertionError {
+               try {
+                       return value.cache().asBytes();
+               } catch (RestCallException e) {
+                       throw error(e, "Exception occurred during call.");
+               }
+       }
+
+       private <T> T valueAsType(Class<T> c) throws AssertionError {
+               try {
+                       return value.cache().as(c);
+               } catch (RestCallException e) {
+                       throw error(e, "Exception occurred during call.");
+               }
+       }
+
+       // <FluentSetters>
+
+       @Override /* GENERATED - Assertion */
+       public FluentResponseBodyAssertion<R> msg(String msg, Object...args) {
+               super.msg(msg, args);
+               return this;
+       }
+
+       @Override /* GENERATED - Assertion */
+       public FluentResponseBodyAssertion<R> stderr() {
+               super.stderr();
+               return this;
+       }
+
+       @Override /* GENERATED - Assertion */
+       public FluentResponseBodyAssertion<R> stdout() {
+               super.stdout();
+               return this;
+       }
+
+
+       // </FluentSetters>
+}
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_BasicCalls_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_BasicCalls_Test.java
index 648b1b3..0df76cc 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_BasicCalls_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_BasicCalls_Test.java
@@ -320,7 +320,7 @@ public class RestClient_BasicCalls_Test {
                        /*[15]*/ s2
                );
                for (int i = 0; i < bodies.size(); i++) {
-                       
client().header("Check","Content-Type").accept("application/json+simple").build().formPost("/checkHeader",bodies.get(i)).run().assertBody().msg("Body
 {0} failed",i).matchesSimple("['application/x-www-form-urlencoded*']");
+                       
client().header("Check","Content-Type").accept("application/json+simple").build().formPost("/checkHeader",bodies.get(i)).run().assertBody().msg("Body
 {0} 
failed",i).asString().matchesSimple("['application/x-www-form-urlencoded*']");
                        
client().build().formPost("/bean",bodies.get(i)).accept("application/json+simple").run().assertBody().msg("Body
 {0} failed","#"+i).is("{f:1}");
                }
        }
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Body_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Body_Test.java
index a76f72a..f694ebf 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Body_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Body_Test.java
@@ -93,14 +93,14 @@ public class RestClient_Body_Test {
                ;
 
                BasicHttpResource x7 = httpResource(new StringReader("foo"));
-               
client().build().post("/",x7).run().getBody().assertString().is("foo");
+               client().build().post("/",x7).run().assertBody().is("foo");
 
                BasicHttpResource x8 = httpResource(new 
StringReader("foo")).cache();
-               
client().build().post("/",x8).run().getBody().assertString().is("foo");
-               
client().build().post("/",x8).run().getBody().assertString().is("foo");
+               client().build().post("/",x8).run().assertBody().is("foo");
+               client().build().post("/",x8).run().assertBody().is("foo");
 
                BasicHttpResource x9 = httpResource(null);
-               
client().build().post("/",x9).run().getBody().assertString().isEmpty();
+               client().build().post("/",x9).run().assertBody().isEmpty();
        }
 
        @Test
@@ -138,14 +138,14 @@ public class RestClient_Body_Test {
                ;
 
                BasicHttpEntity x7 = httpEntity(new StringReader("foo"));
-               
client().build().post("/",x7).run().getBody().assertString().is("foo");
+               client().build().post("/",x7).run().assertBody().is("foo");
 
                BasicHttpEntity x8 = httpEntity(new 
StringReader("foo")).cache();
-               
client().build().post("/",x8).run().getBody().assertString().is("foo");
-               
client().build().post("/",x8).run().getBody().assertString().is("foo");
+               client().build().post("/",x8).run().assertBody().is("foo");
+               client().build().post("/",x8).run().assertBody().is("foo");
 
                BasicHttpEntity x9 = httpEntity(null);
-               
client().build().post("/",x9).run().getBody().assertString().isEmpty();
+               client().build().post("/",x9).run().assertBody().isEmpty();
 
                BasicHttpEntity x12 = httpEntity("foo");
                x12.assertString().is("foo");
@@ -170,35 +170,35 @@ public class RestClient_Body_Test {
                        .assertHeader("X-Content-Length").doesNotExist()
                        .assertHeader("X-Content-Encoding").doesNotExist()
                        .assertHeader("X-Content-Type").is("application/json")
-                       
.getBody().assertObject(ABean.class).asJson().is("{a:1,b:'foo'}");
+                       
.assertBody().asType(ABean.class).asJson().is("{a:1,b:'foo'}");
 
                SerializedHttpEntity x3 = 
SerializedHttpEntity.of(()->ABean.get(),js);
                client().build().post("/",x3).run()
                        .assertHeader("X-Content-Length").doesNotExist()
                        .assertHeader("X-Content-Encoding").doesNotExist()
                        .assertHeader("X-Content-Type").is("application/json")
-                       
.getBody().assertObject(ABean.class).asJson().is("{a:1,b:'foo'}");
+                       
.assertBody().asType(ABean.class).asJson().is("{a:1,b:'foo'}");
 
                SerializedHttpEntity x4 = serializedHttpEntity(new 
StringReader("{a:1,b:'foo'}"),null);
                client().build().post("/",x4).run()
                        .assertHeader("X-Content-Length").doesNotExist()
                        .assertHeader("X-Content-Encoding").doesNotExist()
                        .assertHeader("X-Content-Type").doesNotExist()
-                       
.getBody().assertObject(ABean.class).asJson().is("{a:1,b:'foo'}");
+                       
.assertBody().asType(ABean.class).asJson().is("{a:1,b:'foo'}");
 
                SerializedHttpEntity x5 = serializedHttpEntity(new 
ByteArrayInputStream("{a:1,b:'foo'}".getBytes()),null);
                client().build().post("/",x5).run()
                        .assertHeader("X-Content-Length").doesNotExist()
                        .assertHeader("X-Content-Encoding").doesNotExist()
                        .assertHeader("X-Content-Type").doesNotExist()
-                       
.getBody().assertObject(ABean.class).asJson().is("{a:1,b:'foo'}");
+                       
.assertBody().asType(ABean.class).asJson().is("{a:1,b:'foo'}");
 
                SerializedHttpEntity x6 = serializedHttpEntity(f,null);
                client().build().post("/",x6).run()
                        .assertHeader("X-Content-Length").is("0")
                        .assertHeader("X-Content-Encoding").doesNotExist()
                        .assertHeader("X-Content-Type").doesNotExist()
-                       
.getBody().assertObject(ABean.class).asJson().is("{a:0}");
+                       .assertBody().asType(ABean.class).asJson().is("{a:0}");
 
                InputStream x7 = new ByteArrayInputStream("foo".getBytes()) {
                        @Override
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_BeanContext_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_BeanContext_Test.java
index 9040cf4..023670d 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_BeanContext_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_BeanContext_Test.java
@@ -69,9 +69,9 @@ public class RestClient_Config_BeanContext_Test {
                x1.post("/echoBody",new A1()).run().assertBody().is("'O1'");
                x2.post("/echoBody",new A1()).run().assertBody().is("{f:1}");
                x1.get("/checkQuery").query("foo",new 
A1()).run().assertBody().is("foo=O1");
-               x2.get("/checkQuery").query("foo",new 
A1()).run().assertBody().is("foo=f%3D1").assertBody().urlDecode().is("foo=f=1");
+               x2.get("/checkQuery").query("foo",new 
A1()).run().assertBody().is("foo=f%3D1").assertBody().asString().urlDecode().is("foo=f=1");
                x1.formPost("/checkFormData").formData("foo",new 
A1()).run().assertBody().is("foo=O1");
-               x2.formPost("/checkFormData").formData("foo",new 
A1()).run().assertBody().is("foo=f%3D1").assertBody().urlDecode().is("foo=f=1");
+               x2.formPost("/checkFormData").formData("foo",new 
A1()).run().assertBody().is("foo=f%3D1").assertBody().asString().urlDecode().is("foo=f=1");
                x1.get("/checkHeader").header("foo",new 
A1()).header("Check","foo").run().assertBody().is("['O1']");
                x2.get("/checkHeader").header("foo",new 
A1()).header("Check","foo").run().assertBody().is("['f=1']");
        }
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_OpenApi_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_OpenApi_Test.java
index c23e276..455ea2a 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_OpenApi_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_OpenApi_Test.java
@@ -50,15 +50,15 @@ public class RestClient_Config_OpenApi_Test {
 
        @Test
        public void a01_oapiFormat() throws Exception {
-               
client().oapiFormat(HttpPartFormat.UON).build().get("/checkQuery").query("Foo","bar
 baz").run().assertBody().urlDecode().is("Foo='bar baz'");
+               
client().oapiFormat(HttpPartFormat.UON).build().get("/checkQuery").query("Foo","bar
 baz").run().assertBody().asString().urlDecode().is("Foo='bar baz'");
        }
 
        @Test
        public void a02_oapiCollectionFormat() throws Exception {
                String[] a = {"bar","baz"};
                RestClient x = client().oapiCollectionFormat(PIPES).build();
-               
x.get("/checkQuery").query("Foo",a).run().assertBody().urlDecode().is("Foo=bar|baz");
-               
x.post("/checkFormData").formData("Foo",a).run().assertBody().urlDecode().is("Foo=bar|baz");
+               
x.get("/checkQuery").query("Foo",a).run().assertBody().asString().urlDecode().is("Foo=bar|baz");
+               
x.post("/checkFormData").formData("Foo",a).run().assertBody().asString().urlDecode().is("Foo=bar|baz");
                
x.get("/checkHeader").header("Check","Foo").header("Foo",a).accept("text/json+simple").run().assertBody().is("['bar|baz']");
        }
 
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_FormData_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_FormData_Test.java
index 94fdfe6..5eb3695 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_FormData_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_FormData_Test.java
@@ -115,10 +115,10 @@ public class RestClient_FormData_Test {
                List<String> l1 = AList.of("bar1","bar2"), l2 = 
AList.of("qux1","qux2");
 
                
client().formDataPairs("foo","bar","baz","qux").build().post("/formData").run().assertBody().is("foo=bar&baz=qux");
-               
client().formDataPairs("foo",l1,"baz",l2).build().post("/formData").run().assertBody().urlDecode().is("foo=bar1,bar2&baz=qux1,qux2");
+               
client().formDataPairs("foo",l1,"baz",l2).build().post("/formData").run().assertBody().asString().urlDecode().is("foo=bar1,bar2&baz=qux1,qux2");
 
                
client().build().post("/formData").formDataPairs("foo","bar","baz","qux").run().assertBody().is("foo=bar&baz=qux");
-               
client().build().post("/formData").formDataPairs("foo",l1,"baz",l2).run().assertBody().urlDecode().is("foo=bar1,bar2&baz=qux1,qux2");
+               
client().build().post("/formData").formDataPairs("foo",l1,"baz",l2).run().assertBody().asString().urlDecode().is("foo=bar1,bar2&baz=qux1,qux2");
 
                
assertThrown(()->client().formDataPairs("foo","bar","baz")).is("Odd number of 
parameters passed into formDataPairs()");
                
assertThrown(()->client().build().post("").formDataPairs("foo","bar","baz")).is("Odd
 number of parameters passed into formDataPairs()");
@@ -127,21 +127,21 @@ public class RestClient_FormData_Test {
        @Test
        public void a06_formData_String_Object_Schema() throws Exception {
                List<String> l = AList.of("bar","baz"), l2 = 
AList.of("qux","quux");
-               
client().formData("foo",l,T_ARRAY_PIPES).build().post("/formData").formData("foo",l2,T_ARRAY_PIPES).run().assertBody().urlDecode().is("foo=bar|baz&foo=qux|quux");
+               
client().formData("foo",l,T_ARRAY_PIPES).build().post("/formData").formData("foo",l2,T_ARRAY_PIPES).run().assertBody().asString().urlDecode().is("foo=bar|baz&foo=qux|quux");
        }
 
        @Test
        public void a07_formData_String_Object_Schema_Serializer() throws 
Exception {
                List<String> l = AList.of("bar","baz");
-               
client().formData("foo",l,T_ARRAY_PIPES,UonSerializer.DEFAULT).build().post("/formData").run().assertBody().urlDecode().is("foo=@(bar,baz)");
+               
client().formData("foo",l,T_ARRAY_PIPES,UonSerializer.DEFAULT).build().post("/formData").run().assertBody().asString().urlDecode().is("foo=@(bar,baz)");
        }
 
        @Test
        public void a08_formData_AddFlag_String_Object_Schema() throws 
Exception {
                List<String> l = AList.of("qux","quux");
-               
client().formData("foo","bar").build().post("/formData").formData(APPEND,"foo",l,T_ARRAY_PIPES).run().assertBody().urlDecode().is("foo=bar&foo=qux|quux");
-               
client().formData("foo","bar").build().post("/formData").formData(PREPEND,"foo",l,T_ARRAY_PIPES).run().assertBody().urlDecode().is("foo=qux|quux&foo=bar");
-               
client().formData("foo","bar").build().post("/formData").formData(REPLACE,"foo",l,T_ARRAY_PIPES).run().assertBody().urlDecode().is("foo=qux|quux");
+               
client().formData("foo","bar").build().post("/formData").formData(APPEND,"foo",l,T_ARRAY_PIPES).run().assertBody().asString().urlDecode().is("foo=bar&foo=qux|quux");
+               
client().formData("foo","bar").build().post("/formData").formData(PREPEND,"foo",l,T_ARRAY_PIPES).run().assertBody().asString().urlDecode().is("foo=qux|quux&foo=bar");
+               
client().formData("foo","bar").build().post("/formData").formData(REPLACE,"foo",l,T_ARRAY_PIPES).run().assertBody().asString().urlDecode().is("foo=qux|quux");
        }
 
        @Test
@@ -150,15 +150,15 @@ public class RestClient_FormData_Test {
 
                RestClient x1 = client().formData("foo",s).build();
                s.set(OList.of("foo","bar"));
-               
x1.post("/formData").run().assertBody().urlDecode().is("foo=foo,bar");
+               
x1.post("/formData").run().assertBody().asString().urlDecode().is("foo=foo,bar");
                s.set(OList.of("bar","baz"));
-               
x1.post("/formData").run().assertBody().urlDecode().is("foo=bar,baz");
+               
x1.post("/formData").run().assertBody().asString().urlDecode().is("foo=bar,baz");
 
                RestClient x2 = client().build();
                s.set(OList.of("foo","bar"));
-               
x2.post("/formData").formData("foo",s).run().assertBody().urlDecode().is("foo=foo,bar");
+               
x2.post("/formData").formData("foo",s).run().assertBody().asString().urlDecode().is("foo=foo,bar");
                s.set(OList.of("bar","baz"));
-               
x2.post("/formData").formData("foo",s).run().assertBody().urlDecode().is("foo=bar,baz");
+               
x2.post("/formData").formData("foo",s).run().assertBody().asString().urlDecode().is("foo=bar,baz");
        }
 
        public static class A8 extends SimplePartSerializer {
@@ -177,9 +177,9 @@ public class RestClient_FormData_Test {
        public void a10_formData_String_Supplier_Schema_Serializer() throws 
Exception {
                TestSupplier s = TestSupplier.of(OList.of("foo","bar"));
                RestClient x = client().formData("foo",s,T_ARRAY_PIPES,new 
A8()).build();
-               
x.post("/formData").run().assertBody().urlDecode().is("foo=x['foo','bar']");
+               
x.post("/formData").run().assertBody().asString().urlDecode().is("foo=x['foo','bar']");
                s.set(OList.of("bar","baz"));
-               
x.post("/formData").run().assertBody().urlDecode().is("foo=x['bar','baz']");
+               
x.post("/formData").run().assertBody().asString().urlDecode().is("foo=x['bar','baz']");
        }
 
        @Test
@@ -189,15 +189,15 @@ public class RestClient_FormData_Test {
 
                RestClient x1 = 
client().formData("foo",s,T_ARRAY_PIPES).build();
                s.set(l1);
-               
x1.post("/formData").run().assertBody().urlDecode().is("foo=foo|bar");
+               
x1.post("/formData").run().assertBody().asString().urlDecode().is("foo=foo|bar");
                s.set(l2);
-               
x1.post("/formData").run().assertBody().urlDecode().is("foo=bar|baz");
+               
x1.post("/formData").run().assertBody().asString().urlDecode().is("foo=bar|baz");
 
                RestClient x2 = client().build();
                s.set(l1);
-               
x2.post("/formData").formData("foo",s,T_ARRAY_PIPES).run().assertBody().urlDecode().is("foo=foo|bar");
+               
x2.post("/formData").formData("foo",s,T_ARRAY_PIPES).run().assertBody().asString().urlDecode().is("foo=foo|bar");
                s.set(l2);
-               
x2.post("/formData").formData("foo",s,T_ARRAY_PIPES).run().assertBody().urlDecode().is("foo=bar|baz");
+               
x2.post("/formData").formData("foo",s,T_ARRAY_PIPES).run().assertBody().asString().urlDecode().is("foo=bar|baz");
        }
 
        public static class A12 implements HttpPartSerializer {
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Query_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Query_Test.java
index 285b8aa..499f958 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Query_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Query_Test.java
@@ -57,14 +57,14 @@ public class RestClient_Query_Test {
        @Test
        public void a02_query_String_Object_Schema() throws Exception {
                List<String> l = AList.of("bar","baz");
-               
client().build().get("/query").query("foo",l,T_ARRAY_PIPES).run().assertBody().urlDecode().is("foo=bar|baz");
-               
client().query("foo",l,T_ARRAY_PIPES).build().get("/query").run().assertBody().urlDecode().is("foo=bar|baz");
+               
client().build().get("/query").query("foo",l,T_ARRAY_PIPES).run().assertBody().asString().urlDecode().is("foo=bar|baz");
+               
client().query("foo",l,T_ARRAY_PIPES).build().get("/query").run().assertBody().asString().urlDecode().is("foo=bar|baz");
        }
 
        @Test
        public void a03_query_String_Object_Schema_Serializer() throws 
Exception {
                List<String> l = AList.of("bar","baz");
-               
client().query("foo",l,T_ARRAY_PIPES,UonSerializer.DEFAULT).build().get("/query").run().assertBody().urlDecode().is("foo=@(bar,baz)");
+               
client().query("foo",l,T_ARRAY_PIPES,UonSerializer.DEFAULT).build().get("/query").run().assertBody().asString().urlDecode().is("foo=@(bar,baz)");
        }
 
        @Test
@@ -81,7 +81,7 @@ public class RestClient_Query_Test {
        @Test
        public void a05_query_AddFlag_String_Object_Schema() throws Exception {
                List<String> l = AList.of("baz","qux");
-               
client().query("foo","bar").build().get("/query").query(PREPEND,"foo",l,T_ARRAY_PIPES).run().assertBody().urlDecode().is("foo=baz|qux&foo=bar");
+               
client().query("foo","bar").build().get("/query").query(PREPEND,"foo",l,T_ARRAY_PIPES).run().assertBody().asString().urlDecode().is("foo=baz|qux&foo=bar");
        }
 
        @Test
@@ -89,9 +89,9 @@ public class RestClient_Query_Test {
                List<String> l1 = AList.of("foo","bar"), l2 = 
AList.of("bar","baz");
                TestSupplier s = TestSupplier.of(l1);
                RestClient x = client().query("foo",s).build();
-               
x.get("/query").run().assertBody().urlDecode().is("foo=foo,bar");
+               
x.get("/query").run().assertBody().asString().urlDecode().is("foo=foo,bar");
                s.set(l2);
-               
x.get("/query").run().assertBody().urlDecode().is("foo=bar,baz");
+               
x.get("/query").run().assertBody().asString().urlDecode().is("foo=bar,baz");
        }
 
        @Test
@@ -99,9 +99,9 @@ public class RestClient_Query_Test {
                String[] l1 = new String[]{"foo","bar"},l2 = new 
String[]{"bar","baz"};
                TestSupplier s = TestSupplier.of(l1);
                RestClient x = client().query("foo",s,T_ARRAY_PIPES).build();
-               
x.get("/query").query("bar",s,T_ARRAY_PIPES).run().assertBody().urlDecode().is("foo=foo|bar&bar=foo|bar");
+               
x.get("/query").query("bar",s,T_ARRAY_PIPES).run().assertBody().asString().urlDecode().is("foo=foo|bar&bar=foo|bar");
                s.set(l2);
-               
x.get("/query").query("bar",s,T_ARRAY_PIPES).run().assertBody().urlDecode().is("foo=bar|baz&bar=bar|baz");
+               
x.get("/query").query("bar",s,T_ARRAY_PIPES).run().assertBody().asString().urlDecode().is("foo=bar|baz&bar=bar|baz");
        }
 
        public static class A8 extends SimplePartSerializer {
@@ -121,9 +121,9 @@ public class RestClient_Query_Test {
                List<String> l1 = AList.of("foo","bar"), l2 = 
AList.of("bar","baz");
                TestSupplier s = TestSupplier.of(l1);
                RestClient x = client().query("foo",s,T_ARRAY_PIPES,new 
A8()).build();
-               
x.get("/query").run().assertBody().urlDecode().is("foo=x['foo','bar']");
+               
x.get("/query").run().assertBody().asString().urlDecode().is("foo=x['foo','bar']");
                s.set(l2);
-               
x.get("/query").run().assertBody().urlDecode().is("foo=x['bar','baz']");
+               
x.get("/query").run().assertBody().asString().urlDecode().is("foo=x['bar','baz']");
        }
 
        @Test
@@ -167,8 +167,8 @@ public class RestClient_Query_Test {
                List<String> l1 = AList.of("bar1","bar2"), l2 = 
AList.of("qux1","qux2");
                
client().queryPairs("foo","bar","baz","qux").build().get("/query").run().assertBody().is("foo=bar&baz=qux");
                
client().build().get("/query").queryPairs("foo","bar","baz","qux").run().assertBody().is("foo=bar&baz=qux");
-               
client().queryPairs("foo",l1,"baz",l2).build().get("/query").run().assertBody().urlDecode().is("foo=bar1,bar2&baz=qux1,qux2");
-               
client().build().get("/query").queryPairs("foo",l1,"baz",l2).run().assertBody().urlDecode().is("foo=bar1,bar2&baz=qux1,qux2");
+               
client().queryPairs("foo",l1,"baz",l2).build().get("/query").run().assertBody().asString().urlDecode().is("foo=bar1,bar2&baz=qux1,qux2");
+               
client().build().get("/query").queryPairs("foo",l1,"baz",l2).run().assertBody().asString().urlDecode().is("foo=bar1,bar2&baz=qux1,qux2");
                
assertThrown(()->client().queryPairs("foo","bar","baz")).contains("Odd number 
of parameters");
                
assertThrown(()->client().build().get().queryPairs("foo","bar","baz")).contains("Odd
 number of parameters");
        }
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Response_Body_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Response_Body_Test.java
index 70f01b0..6d42d29 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Response_Body_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Response_Body_Test.java
@@ -93,8 +93,8 @@ public class RestClient_Response_Body_Test {
 
        @Test
        public void a01_basic() throws Exception {
-               
client().build().post("/echo",bean).run().assertBody(ABean.class).asJson().is("{f:1}");
-               
client().build().post("/echo",bean).run().assertBodyBytes().asString().is("{f:1}");
+               
client().build().post("/echo",bean).run().assertBody().asType(ABean.class).asJson().is("{f:1}");
+               
client().build().post("/echo",bean).run().assertBody().asBytes().asString().is("{f:1}");
        }
 
        @Test
@@ -103,7 +103,7 @@ public class RestClient_Response_Body_Test {
                ABean b = 
x.post("/echo",bean).run().getBody().parser(JsonParser.DEFAULT).as(ABean.class);
                assertObject(b).asJson().is("{f:1}");
                
assertThrown(()->x.post("/echo",bean).run().getBody().parser(XmlParser.DEFAULT).as(ABean.class)).contains("ParseError
 at [row,col]:[1,1]");
-               
assertThrown(()->x.post("/echo",bean).run().getBody().parser(XmlParser.DEFAULT).assertObject(ABean.class)).contains("ParseError
 at [row,col]:[1,1]");
+               
assertThrown(()->x.post("/echo",bean).run().getBody().parser(XmlParser.DEFAULT).assertValue().asType(ABean.class)).contains("ParseError
 at [row,col]:[1,1]");
        }
 
        @Test
@@ -162,7 +162,7 @@ public class RestClient_Response_Body_Test {
                byte[] x = 
client().build().get("/bean").run().getBody().asBytes();
                assertBytes(x).asString().is("{f:1}");
 
-               x = 
client().build().get("/bean").run().getBody().cache().assertBytes().asString().is("{f:1}").getBody().asBytes();
+               x = 
client().build().get("/bean").run().assertBody().asBytes().asString().is("{f:1}").getBody().asBytes();
                assertBytes(x).asString().is("{f:1}");
 
                assertThrown(()->testClient().entity(new 
InputStreamEntity(badStream())).get().run().getBody().asBytes()).contains("foo");
@@ -229,8 +229,8 @@ public class RestClient_Response_Body_Test {
                HttpEntity x6 = 
testClient().entity(stringEntity("{f:1}")).get().run().getBody().as(HttpEntity.class);
                assertTrue(x6 instanceof ResponseBody);
 
-               
plainTestClient().entity(stringEntity("foo")).get().run().getBody().assertObject(A7a.class).passes(x->((A7a)x).x.equals("foo"));
-               
plainTestClient().entity(stringEntity("foo")).get().run().getBody().assertObject(A7b.class).passes(x->((A7b)x).x.equals("foo"));
+               
plainTestClient().entity(stringEntity("foo")).get().run().assertBody().asType(A7a.class).passes(x->((A7a)x).x.equals("foo"));
+               
plainTestClient().entity(stringEntity("foo")).get().run().assertBody().asType(A7b.class).passes(x->((A7b)x).x.equals("foo"));
                
assertThrown(()->plainTestClient().entity(stringEntity("foo")).headers(header("Content-Type","foo")).get().run().getBody().as(A7c.class)).exists().contains("Unsupported
 media-type","'foo'");
                
assertThrown(()->testClient().entity(stringEntity("")).get().run().getBody().as(A7c.class)).contains("foo");
 
@@ -241,24 +241,12 @@ public class RestClient_Response_Body_Test {
                Future<ABean> x8 = 
testClient().entity(stringEntity("{f:1}")).get().run().getBody().asFuture(ABean.class);
                assertObject(x8.get()).asJson().is("{f:1}");
 
-               Mutable<Future<ABean>> x9 = mutable();
-               
testClient().entity(stringEntity("{f:1}")).get().run().getBody().asFuture(x9,ABean.class);
-               assertObject(x9.get().get()).asJson().is("{f:1}");
-
                Future<ABean> x10 = 
testClient().entity(stringEntity("{f:1}")).get().run().getBody().asFuture(cm(ABean.class));
                assertObject(x10.get()).asJson().is("{f:1}");
 
-               Mutable<Future<ABean>> x11 = mutable();
-               
testClient().entity(stringEntity("{f:1}")).get().run().getBody().asFuture(x11,cm(ABean.class));
-               assertObject(x11.get().get()).asJson().is("{f:1}");
-
                Future<List<Integer>> x12 = 
testClient().entity(stringEntity("[1,2]")).get().run().getBody().asFuture(List.class,Integer.class);
                assertObject(x12.get()).asJson().is("[1,2]");
 
-               Mutable<Future<List<Integer>>> x13 = mutable();
-               
testClient().entity(stringEntity("[1,2]")).get().run().getBody().asFuture(x13,List.class,Integer.class);
-               assertObject(x13.get().get()).asJson().is("[1,2]");
-
                String x14 = 
testClient().entity(stringEntity("{f:1}")).get().run().getBody().asString();
                assertString(x14).is("{f:1}");
 
@@ -300,19 +288,9 @@ public class RestClient_Response_Body_Test {
                assertTrue(x24.matches());
                assertString(x24.group(1)).is("123");
 
-               Mutable<Matcher> x25 = mutable();
-               
testClient().entity(stringEntity("foo=123")).get().run().getBody().asMatcher(x25,Pattern.compile("foo=(.*)"));
-               assertTrue(x25.get().matches());
-               assertString(x25.get().group(1)).is("123");
-
                Matcher x26 = 
testClient().entity(stringEntity("foo=123")).get().run().getBody().asMatcher("foo=(.*)");
                assertTrue(x26.matches());
                assertString(x26.group(1)).is("123");
-
-               Mutable<Matcher> x27 = mutable();
-               
testClient().entity(stringEntity("foo=123")).get().run().getBody().asMatcher(x27,"foo=(.*)");
-               assertTrue(x27.get().matches());
-               assertString(x27.get().group(1)).is("123");
        }
 
        
//------------------------------------------------------------------------------------------------------------------
@@ -334,14 +312,14 @@ public class RestClient_Response_Body_Test {
 
                assertFalse(x2.isChunked());
 
-               
testClient().entity(inputStreamEntity("foo")).get().run().getBody().getContentEncoding().assertString().isNull();
+               
testClient().entity(inputStreamEntity("foo")).get().run().getBody().getContentEncoding().assertValue().isNull();
 
                InputStreamEntity x3 = inputStreamEntity("foo");
                x3.setContentType("text/foo");
                x3.setContentEncoding("identity");
                testClient().entity(x3).get().run().getBody().toResponse()
-                       
.getBody().getContentType().assertString().is("text/foo")
-                       
.getBody().getContentEncoding().assertString().is("identity");
+                       .getBody().getContentType().assertValue().is("text/foo")
+                       
.getBody().getContentEncoding().assertValue().is("identity");
 
                InputStream x4 = 
testClient().entity(inputStreamEntity("foo")).get().run().getBody().asInputStream();
                assertStream(x4).asString().is("foo");
@@ -363,8 +341,8 @@ public class RestClient_Response_Body_Test {
                
assertFalse(client().build().head("").run().getBody().isRepeatable());
                
assertFalse(client().build().head("").run().getBody().isChunked());
                
assertLong(client().build().head("").run().getBody().getContentLength()).is(-1l);
-               
client().build().head("").run().getBody().getContentType().assertString().isNull();
-               
client().build().head("").run().getBody().getContentEncoding().assertString().isNull();
+               
client().build().head("").run().getBody().getContentType().assertValue().isNull();
+               
client().build().head("").run().getBody().getContentEncoding().assertValue().isNull();
                client().build().head("").run().getBody().writeTo(new 
ByteArrayOutputStream());
                
assertFalse(client().build().head("").run().getBody().isStreaming());
                client().build().head("").run().getBody().consumeContent();
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Response_Headers_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Response_Headers_Test.java
index d9b40f5..4eb867a 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Response_Headers_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Response_Headers_Test.java
@@ -149,20 +149,6 @@ public class RestClient_Response_Headers_Test {
                
assertFalse(checkFooClient().build().get("/echo").header("Foo","foo").run().getResponseHeader("Bar").asMatcher("foo").matches());
                
assertTrue(checkFooClient().build().get("/echo").header("Foo","foo").run().getResponseHeader("Foo").asMatcher("FOO",Pattern.CASE_INSENSITIVE).matches());
                
assertFalse(checkFooClient().build().get("/echo").header("Foo","foo").run().getResponseHeader("Bar").asMatcher("FOO",Pattern.CASE_INSENSITIVE).matches());
-
-               Mutable<Matcher> m6 = Mutable.create();
-               
checkFooClient().build().get("/echo").header("Foo","foo").run().getResponseHeader("Foo").asMatcher(m6,"foo");
-               assertTrue(m6.get().matches());
-               
checkFooClient().build().get("/echo").header("Foo","foo").run().getResponseHeader("Bar").asMatcher(m6,"foo");
-               assertFalse(m6.get().matches());
-               
checkFooClient().build().get("/echo").header("Foo","foo").run().getResponseHeader("Foo").asMatcher(m6,"FOO",Pattern.CASE_INSENSITIVE);
-               assertTrue(m6.get().matches());
-               
checkFooClient().build().get("/echo").header("Foo","foo").run().getResponseHeader("Bar").asMatcher(m6,"FOO",Pattern.CASE_INSENSITIVE);
-               assertFalse(m6.get().matches());
-               
checkFooClient().build().get("/echo").header("Foo","foo").run().getResponseHeader("Foo").asMatcher(m6,Pattern.compile("FOO",Pattern.CASE_INSENSITIVE));
-               assertTrue(m6.get().matches());
-               
checkFooClient().build().get("/echo").header("Foo","foo").run().getResponseHeader("Bar").asMatcher(m6,Pattern.compile("FOO",Pattern.CASE_INSENSITIVE));
-               assertFalse(m6.get().matches());
        }
 
        @Test
@@ -177,14 +163,14 @@ public class RestClient_Response_Headers_Test {
 
        @Test
        public void b01_assertions() throws Exception {
-               
checkFooClient().build().get("/echo").header("Foo","bar").run().getResponseHeader("Foo").assertString().is("bar");
-               
checkFooClient().build().get("/echo").header("Foo","bar").run().getResponseHeader("Bar").assertString().doesNotExist();
-               
checkFooClient().build().get("/echo").header("Foo","123").run().getResponseHeader("Foo").assertInteger().is(123);
-               
checkFooClient().build().get("/echo").header("Foo","123").run().getResponseHeader("Bar").assertInteger().doesNotExist();
-               
checkFooClient().build().get("/echo").header("Foo","123").run().getResponseHeader("Foo").assertLong().is(123l);
-               
checkFooClient().build().get("/echo").header("Foo","123").run().getResponseHeader("Bar").assertLong().doesNotExist();
-               
checkFooClient().build().get("/echo").header(BasicDateHeader.of("Foo",CALENDAR)).run().getResponseHeader("Foo").assertDate().exists();
-               
checkFooClient().build().get("/echo").header(BasicDateHeader.of("Foo",CALENDAR)).run().getResponseHeader("Bar").assertDate().doesNotExist();
+               
checkFooClient().build().get("/echo").header("Foo","bar").run().getResponseHeader("Foo").assertValue().is("bar");
+               
checkFooClient().build().get("/echo").header("Foo","bar").run().getResponseHeader("Bar").assertValue().doesNotExist();
+               
checkFooClient().build().get("/echo").header("Foo","123").run().getResponseHeader("Foo").assertValue().asInteger().is(123);
+               
checkFooClient().build().get("/echo").header("Foo","123").run().getResponseHeader("Bar").assertValue().doesNotExist();
+               
checkFooClient().build().get("/echo").header("Foo","123").run().getResponseHeader("Foo").assertValue().asLong().is(123l);
+               
checkFooClient().build().get("/echo").header("Foo","123").run().getResponseHeader("Bar").assertValue().asLong().doesNotExist();
+               
checkFooClient().build().get("/echo").header(BasicDateHeader.of("Foo",CALENDAR)).run().getResponseHeader("Foo").assertValue().asDate().exists();
+               
checkFooClient().build().get("/echo").header(BasicDateHeader.of("Foo",CALENDAR)).run().getResponseHeader("Bar").assertValue().asDate().doesNotExist();
        }
 
        
//------------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Response_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Response_Test.java
index 36686b4..14ab963 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Response_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Response_Test.java
@@ -194,18 +194,18 @@ public class RestClient_Response_Test {
                r.addHeader(BasicStringHeader.of("Foo","qux"));
                assertEquals(3, r.getHeaders("Foo").length);
                assertEquals(0, r.getHeaders("Bar").length);
-               r.getFirstHeader("Foo").assertString().is("bar");
+               r.getFirstHeader("Foo").assertValue().is("bar");
                assertFalse(r.getFirstHeader("Bar").exists());
-               r.getLastHeader("Foo").assertString().is("qux");
+               r.getLastHeader("Foo").assertValue().is("qux");
                assertFalse(r.getLastHeader("Bar").exists());
 
                r.setHeaders(new Header[]{BasicHeader.of("Foo", "quux")});
-               r.getFirstHeader("Foo").assertString().is("quux");
-               r.getLastHeader("Foo").assertString().is("quux");
+               r.getFirstHeader("Foo").assertValue().is("quux");
+               r.getLastHeader("Foo").assertValue().is("quux");
 
                r.removeHeader(BasicHeader.of("Foo","bar"));
-               r.getFirstHeader("Foo").assertString().is("quux");
-               r.getLastHeader("Foo").assertString().is("quux");
+               r.getFirstHeader("Foo").assertValue().is("quux");
+               r.getLastHeader("Foo").assertValue().is("quux");
 
                HeaderIterator i = r.headerIterator();
                assertEquals("quux", i.nextHeader().getValue());
@@ -217,7 +217,7 @@ public class RestClient_Response_Test {
                assertFalse(r.getFirstHeader("Foo").exists());
 
                r.setHeader(BasicHeader.of("Foo","quuux"));
-               r.getResponseHeader("Foo").assertString().is("quuux");
+               r.getResponseHeader("Foo").assertValue().is("quuux");
        }
 
        
//------------------------------------------------------------------------------------------------------------------
@@ -234,14 +234,14 @@ public class RestClient_Response_Test {
 
        @Test
        public void d01_response_assertBody() throws Exception {
-               
client(D.class).build().post("/bean",bean).run().assertBody(ABean.class).asJson().is("{f:1}");
+               
client(D.class).build().post("/bean",bean).run().assertBody().asType(ABean.class).asJson().is("{f:1}");
        }
 
        @Test
        public void d02_response_setEntity() throws Exception {
                RestResponse x = 
client(D.class).build().post("/bean",bean).run();
                x.setEntity(new StringEntity("{f:2}"));
-               x.assertBody(ABean.class).asJson().is("{f:2}");
+               x.assertBody().asType(ABean.class).asJson().is("{f:2}");
        }
 
        
//------------------------------------------------------------------------------------------------------------------

Reply via email to