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 55f7473  REST refactoring.
55f7473 is described below

commit 55f74733a98dd23d457200c911f49e450a518ec7
Author: JamesBognar <[email protected]>
AuthorDate: Sat Mar 6 18:13:46 2021 -0500

    REST refactoring.
---
 .../java/org/apache/juneau/http/HttpEntities.java  | 108 +++++++++++++++---
 .../juneau/http/entity/BasicHttpEntity2.java       |  60 ++++++++--
 .../apache/juneau/http/entity/ByteArrayEntity.java |  38 ++-----
 .../org/apache/juneau/http/entity/FileEntity.java  |  24 +---
 .../juneau/http/entity/HttpEntityBuilder.java      |  47 +++++---
 .../juneau/http/entity/InputStreamEntity.java      |  36 ++----
 .../apache/juneau/http/entity/ReaderEntity.java    |  34 ++----
 .../juneau/http/entity/SerializedEntity.java       | 122 +++------------------
 .../http/entity/SerializedEntityBuilder.java       | 118 ++++++++++++++++++++
 .../apache/juneau/http/entity/StringEntity.java    |  50 ++++-----
 .../org/apache/juneau/rest/client/RestClient.java  |   3 +-
 .../org/apache/juneau/rest/client/RestRequest.java |   2 +-
 .../juneau/http/SerializedHttpEntity_Test.java     |  40 +++----
 .../juneau/rest/client/RestClient_Body_Test.java   |  16 +--
 14 files changed, 391 insertions(+), 307 deletions(-)

diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HttpEntities.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HttpEntities.java
index 3f80e18..d923360 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HttpEntities.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HttpEntities.java
@@ -17,6 +17,7 @@ import java.util.function.*;
 
 import org.apache.juneau.http.entity.*;
 import org.apache.juneau.http.header.*;
+import org.apache.juneau.httppart.*;
 import org.apache.juneau.serializer.*;
 
 /**
@@ -34,7 +35,7 @@ public class HttpEntities {
         * @return A new {@link ByteArrayEntity} builder.
         */
        public static final HttpEntityBuilder<ByteArrayEntity> 
byteArrayEntity(byte[] content) {
-               return ByteArrayEntity.of(content);
+               return ByteArrayEntity.create().content(content);
        }
 
        /**
@@ -45,7 +46,31 @@ public class HttpEntities {
         * @return A new {@link ByteArrayEntity} builder.
         */
        public static final HttpEntityBuilder<ByteArrayEntity> 
byteArrayEntity(byte[] content, ContentType contentType) {
-               return ByteArrayEntity.of(content, contentType);
+               return 
ByteArrayEntity.create().content(content).contentType(contentType);
+       }
+
+       /**
+        * Creates a new {@link ByteArrayEntity} builder.
+        *
+        * <p>
+        * Assumes no content type.
+        *
+        * @param content The entity content supplier.  Can be <jk>null<jk>.
+        * @return A new {@link ByteArrayEntity} builder.
+        */
+       public static final HttpEntityBuilder<ByteArrayEntity> 
byteArrayEntity(Supplier<byte[]> content) {
+               return ByteArrayEntity.create().contentSupplier(content);
+       }
+
+       /**
+        * Creates a new {@link ByteArrayEntity} builder.
+        *
+        * @param content The entity content supplier.  Can be <jk>null<jk>.
+        * @param contentType The entity content type, or <jk>null</jk> if not 
specified.
+        * @return A new {@link ByteArrayEntity} builder.
+        */
+       public static final HttpEntityBuilder<ByteArrayEntity> 
byteArrayEntity(Supplier<byte[]> content, ContentType contentType) {
+               return 
ByteArrayEntity.create().contentSupplier(content).contentType(contentType);
        }
 
        /**
@@ -58,7 +83,7 @@ public class HttpEntities {
         * @return A new {@link FileEntity} builder.
         */
        public static final HttpEntityBuilder<FileEntity> fileEntity(File 
content) {
-               return FileEntity.of(content);
+               return FileEntity.create().content(content);
        }
 
        /**
@@ -69,7 +94,7 @@ public class HttpEntities {
         * @return A new {@link FileEntity} builder.
         */
        public static final HttpEntityBuilder<FileEntity> fileEntity(File 
content, ContentType contentType) {
-               return FileEntity.of(content, contentType);
+               return 
FileEntity.create().content(content).contentType(contentType);
        }
 
        /**
@@ -79,7 +104,7 @@ public class HttpEntities {
         * @return A new {@link ReaderEntity} builder.
         */
        public static final HttpEntityBuilder<ReaderEntity> readerEntity(Reader 
content) {
-               return ReaderEntity.of(content);
+               return ReaderEntity.create().content(content);
        }
 
        /**
@@ -90,7 +115,7 @@ public class HttpEntities {
         * @return A new {@link ReaderEntity} builder.
         */
        public static final HttpEntityBuilder<ReaderEntity> readerEntity(Reader 
content, ContentType contentType) {
-               return ReaderEntity.of(content, -1, contentType);
+               return 
ReaderEntity.create().content(content).contentType(contentType);
        }
 
        /**
@@ -104,8 +129,8 @@ public class HttpEntities {
         *      <br>If <jk>null</jk>, POJO will be converted to a string using 
{@link Object#toString()}.
         * @return A new {@link SerializedEntity} object.
         */
-       public static final SerializedEntity serializedEntity(Object content, 
Serializer serializer) {
-               return SerializedEntity.of(content, serializer);
+       public static final SerializedEntityBuilder<SerializedEntity> 
serializedEntity(Object content, Serializer serializer) {
+               return 
SerializedEntity.create().content(content).serializer(serializer);
        }
 
        /**
@@ -119,8 +144,42 @@ public class HttpEntities {
         *      <br>If <jk>null</jk>, POJO will be converted to a string using 
{@link Object#toString()}.
         * @return A new {@link SerializedEntity} object.
         */
-       public static final SerializedEntity serializedEntity(Supplier<?> 
content, Serializer serializer) {
-               return SerializedEntity.of(content, serializer);
+       public static final SerializedEntityBuilder<SerializedEntity> 
serializedEntity(Supplier<?> content, Serializer serializer) {
+               return 
SerializedEntity.create().contentSupplier(content).serializer(serializer);
+       }
+
+       /**
+        * Creates a new {@link SerializedEntity} object.
+        *
+        * @param content
+        *      The Java POJO representing the content.
+        *      <br>Can be <jk>null<jk>.
+        * @param serializer
+        *      The serializer to use to serialize the POJO.
+        *      <br>If <jk>null</jk>, POJO will be converted to a string using 
{@link Object#toString()}.
+        * @param schema
+        *      Optional HTTP-part schema for providing instructionst to the 
serializer on the format of the entity.
+        * @return A new {@link SerializedEntity} object.
+        */
+       public static final SerializedEntityBuilder<SerializedEntity> 
serializedEntity(Object content, Serializer serializer, HttpPartSchema    
schema) {
+               return 
SerializedEntity.create().content(content).serializer(serializer).schema(schema);
+       }
+
+       /**
+        * Creates a new {@link SerializedEntity} object.
+        *
+        * @param content
+        *      The supplier of a Java POJO representing the content.
+        *      <br>Can be <jk>null<jk>.
+        * @param serializer
+        *      The serializer to use to serialize the POJO.
+        *      <br>If <jk>null</jk>, POJO will be converted to a string using 
{@link Object#toString()}.
+        * @param schema
+        *      Optional HTTP-part schema for providing instructionst to the 
serializer on the format of the entity.
+        * @return A new {@link SerializedEntity} object.
+        */
+       public static final SerializedEntityBuilder<SerializedEntity> 
serializedEntity(Supplier<?> content, Serializer serializer, HttpPartSchema 
schema) {
+               return 
SerializedEntity.create().contentSupplier(content).serializer(serializer).schema(schema);
        }
 
        /**
@@ -133,7 +192,7 @@ public class HttpEntities {
         * @return A new {@link InputStreamEntity} builder.
         */
        public static final HttpEntityBuilder<InputStreamEntity> 
streamEntity(InputStream content) {
-               return InputStreamEntity.of(content);
+               return InputStreamEntity.create().content(content);
        }
 
        /**
@@ -145,7 +204,7 @@ public class HttpEntities {
         * @return A new {@link InputStreamEntity} builder.
         */
        public static final HttpEntityBuilder<InputStreamEntity> 
streamEntity(InputStream content, long length, ContentType contentType) {
-               return InputStreamEntity.of(content, length, contentType);
+               return 
InputStreamEntity.create().content(content).contentLength(length).contentType(contentType);
        }
 
        /**
@@ -155,7 +214,7 @@ public class HttpEntities {
         * @return A new {@link StringEntity} builder.
         */
        public static final HttpEntityBuilder<StringEntity> stringEntity(String 
content) {
-               return StringEntity.of(content);
+               return StringEntity.create().content(content);
        }
 
        /**
@@ -166,6 +225,27 @@ public class HttpEntities {
         * @return A new {@link StringEntity} builder.
         */
        public static final HttpEntityBuilder<StringEntity> stringEntity(String 
content, ContentType contentType) {
-               return StringEntity.of(content, contentType);
+               return 
StringEntity.create().content(content).contentType(contentType);
+       }
+
+       /**
+        * Creates a new builder for a {@link StringEntity} builder.
+        *
+        * @param content The entity content.  Can be <jk>null</jk>.
+        * @return A new {@link StringEntity} builder.
+        */
+       public static final HttpEntityBuilder<StringEntity> 
stringEntity(Supplier<String> content) {
+               return StringEntity.create().contentSupplier(content);
+       }
+
+       /**
+        * Creates a new builder for a {@link StringEntity} builder.
+        *
+        * @param content The entity content.  Can be <jk>null</jk>.
+        * @param contentType The entity content type, or <jk>null</jk> if not 
specified.
+        * @return A new {@link StringEntity} builder.
+        */
+       public static final HttpEntityBuilder<StringEntity> 
stringEntity(Supplier<String> content, ContentType contentType) {
+               return 
StringEntity.create().contentSupplier(content).contentType(contentType);
        }
 }
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/BasicHttpEntity2.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/BasicHttpEntity2.java
index 7a32e10..8f7017c 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/BasicHttpEntity2.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/BasicHttpEntity2.java
@@ -16,6 +16,7 @@ import static org.apache.juneau.internal.IOUtils.*;
 
 import java.io.*;
 import java.nio.charset.*;
+import java.util.function.*;
 
 import org.apache.http.*;
 import org.apache.juneau.annotation.*;
@@ -33,6 +34,8 @@ import org.apache.juneau.http.header.*;
  *             Fluent setters.
  *     <li>
  *             Fluent assertions.
+ *     <li>
+ *             Externally-supplied/dynamic content.
  * </ul>
  */
 @BeanIgnore
@@ -40,6 +43,7 @@ public abstract class BasicHttpEntity2 implements HttpEntity {
 
        final boolean cached, chunked;
        final Object content;
+       final Supplier<?> contentSupplier;
        final ContentType contentType;
        final ContentEncoding contentEncoding;
        final Charset charset;
@@ -64,6 +68,7 @@ public abstract class BasicHttpEntity2 implements HttpEntity {
                this.cached = builder.cached;
                this.chunked = builder.chunked;
                this.content = builder.content;
+               this.contentSupplier = builder.contentSupplier;
                this.contentType = builder.contentType;
                this.contentEncoding = builder.contentEncoding;
                this.charset = builder.charset;
@@ -73,18 +78,23 @@ public abstract class BasicHttpEntity2 implements 
HttpEntity {
        /**
         * Creates a builder for this class initialized with the contents of 
this bean.
         *
-        * @param implClass The subclass that the builder is going to create.
+        * <p>
+        * Allows you to create a modifiable copy of this bean.
+        *
         * @return A new builder bean.
         */
-       public <T extends BasicHttpEntity2> HttpEntityBuilder<T> 
builder(Class<T> implClass) {
-               return create(implClass).copyFrom(this);
+       public HttpEntityBuilder<? extends BasicHttpEntity2> builder() {
+               return new HttpEntityBuilder<>(this);
        }
 
        /**
-        * Converts the contents of this entity as a byte array.
+        * Converts the contents of this entity as a string.
         *
-        * @return The contents of this entity as a byte array.
-        * @throws IOException If a problem occurred while trying to read the 
byte array.
+        * <p>
+        * Note that this may exhaust the content on non-repeatable, non-cached 
entities.
+        *
+        * @return The contents of this entity as a string.
+        * @throws IOException If a problem occurred while trying to read the 
content.
         */
        public String asString() throws IOException {
                return read(getContent());
@@ -93,8 +103,11 @@ public abstract class BasicHttpEntity2 implements 
HttpEntity {
        /**
         * Converts the contents of this entity as a byte array.
         *
+        * <p>
+        * Note that this may exhaust the content on non-repeatable, non-cached 
entities.
+        *
         * @return The contents of this entity as a byte array.
-        * @throws IOException If a problem occurred while trying to read the 
byte array.
+        * @throws IOException If a problem occurred while trying to read the 
content.
         */
        public byte[] asBytes() throws IOException {
                return readBytes(getContent());
@@ -103,6 +116,9 @@ public abstract class BasicHttpEntity2 implements 
HttpEntity {
        /**
         * Returns an assertion on the contents of this entity.
         *
+        * <p>
+        * Note that this may exhaust the content on non-repeatable, non-cached 
entities.
+        *
         * @return A new fluent assertion.
         * @throws IOException If a problem occurred while trying to read the 
byte array.
         */
@@ -113,6 +129,9 @@ public abstract class BasicHttpEntity2 implements 
HttpEntity {
        /**
         * Returns an assertion on the contents of this entity.
         *
+        * <p>
+        * Note that this may exhaust the content on non-repeatable, non-cached 
entities.
+        *
         * @return A new fluent assertion.
         * @throws IOException If a problem occurred while trying to read the 
byte array.
         */
@@ -120,6 +139,33 @@ public abstract class BasicHttpEntity2 implements 
HttpEntity {
                return new FluentByteArrayAssertion<>(asBytes(), this);
        }
 
+       /**
+        * Returns the content of this entity.
+        *
+        * @param def The default value if <jk>null</jk>.
+        * @return The content object.
+        */
+       @SuppressWarnings("unchecked")
+       protected <T> T contentOrElse(T def) {
+               Object o = content;
+               if (o == null && contentSupplier != null)
+                       o = contentSupplier.get();
+               return (o == null ? def : (T)o);
+       }
+
+       /**
+        * Returns <jk>true</jk> if the contents of this entity are provided 
through an external supplier.
+        * 
+        * <p>
+        * Externally supplied content generally means the content length 
cannot be reliably determined
+        * based on the content.
+        *
+        * @return <jk>true</jk> if the contents of this entity are provided 
through an external supplier.
+        */
+       protected boolean isSupplied() {
+               return contentSupplier != null;
+       }
+
        @Override /* HttpEntity */
        public long getContentLength() {
                return length;
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/ByteArrayEntity.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/ByteArrayEntity.java
index c8835e2..58883ed 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/ByteArrayEntity.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/ByteArrayEntity.java
@@ -17,37 +17,20 @@ import static org.apache.juneau.internal.IOUtils.*;
 
 import java.io.*;
 
-import org.apache.juneau.http.header.*;
-
 /**
  * A repeatable entity that obtains its content from a byte array.
  */
 public class ByteArrayEntity extends BasicHttpEntity2 {
 
-       private final byte[] content;
+       private static final byte[] EMPTY = new byte[0];
 
        /**
         * Creates a new {@link ByteArrayEntity} builder.
         *
-        * <p>
-        * Assumes no content type.
-        *
-        * @param content The entity content.  Can be <jk>null<jk>.
         * @return A new {@link ByteArrayEntity} builder.
         */
-       public static HttpEntityBuilder<ByteArrayEntity> of(byte[] content) {
-               return new 
HttpEntityBuilder<>(ByteArrayEntity.class).content(content);
-       }
-
-       /**
-        * Creates a new {@link ByteArrayEntity} builder.
-        *
-        * @param content The entity content.  Can be <jk>null<jk>.
-        * @param contentType The entity content type, or <jk>null</jk> if not 
specified.
-        * @return A new {@link ByteArrayEntity} builder.
-        */
-       public static HttpEntityBuilder<ByteArrayEntity> of(byte[] content, 
ContentType contentType) {
-               return new 
HttpEntityBuilder<>(ByteArrayEntity.class).content(content).contentType(contentType);
+       public static HttpEntityBuilder<ByteArrayEntity> create() {
+               return new HttpEntityBuilder<>(ByteArrayEntity.class);
        }
 
        /**
@@ -57,17 +40,20 @@ public class ByteArrayEntity extends BasicHttpEntity2 {
         */
        public ByteArrayEntity(HttpEntityBuilder<?> builder) {
                super(builder);
-               this.content = builder.content == null ? new byte[0] : 
(byte[])builder.content;
+       }
+
+       private byte[] bytes() {
+               return contentOrElse(EMPTY);
        }
 
        @Override /* AbstractHttpEntity */
        public String asString() throws IOException {
-               return new String(content, UTF8);
+               return new String(bytes(), UTF8);
        }
 
        @Override /* AbstractHttpEntity */
        public byte[] asBytes() throws IOException {
-               return content;
+               return bytes();
        }
 
        @Override /* HttpEntity */
@@ -77,17 +63,17 @@ public class ByteArrayEntity extends BasicHttpEntity2 {
 
        @Override /* HttpEntity */
        public long getContentLength() {
-               return content.length;
+               return isSupplied() ? super.getContentLength() : bytes().length;
        }
 
        @Override /* HttpEntity */
        public InputStream getContent() throws IOException {
-               return new ByteArrayInputStream(content);
+               return new ByteArrayInputStream(bytes());
        }
 
        @Override /* HttpEntity */
        public void writeTo(OutputStream out) throws IOException {
                assertArgNotNull("out", out);
-               out.write(content);
+               out.write(bytes());
        }
 }
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/FileEntity.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/FileEntity.java
index 355e126..9809336 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/FileEntity.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/FileEntity.java
@@ -17,7 +17,6 @@ import static org.apache.juneau.internal.IOUtils.*;
 
 import java.io.*;
 
-import org.apache.juneau.http.header.*;
 import org.apache.juneau.internal.*;
 
 /**
@@ -31,25 +30,10 @@ public class FileEntity extends BasicHttpEntity2 {
        /**
         * Creates a new {@link FileEntity} builder.
         *
-        * <p>
-        * Assumes no content type.
-        *
-        * @param content The entity content.  Can be <jk>null<jk>.
-        * @return A new {@link FileEntity} builder.
-        */
-       public static HttpEntityBuilder<FileEntity> of(File content) {
-               return new 
HttpEntityBuilder<>(FileEntity.class).content(content);
-       }
-
-       /**
-        * Creates a new {@link FileEntity} builder.
-        *
-        * @param content The entity content.  Can be <jk>null<jk>.
-        * @param contentType The entity content type, or <jk>null</jk> if not 
specified.
         * @return A new {@link FileEntity} builder.
         */
-       public static HttpEntityBuilder<FileEntity> of(File content, 
ContentType contentType) {
-               return new 
HttpEntityBuilder<>(FileEntity.class).content(content).contentType(contentType);
+       public static HttpEntityBuilder<FileEntity> create() {
+               return new HttpEntityBuilder<>(FileEntity.class);
        }
 
        /**
@@ -60,8 +44,8 @@ public class FileEntity extends BasicHttpEntity2 {
         */
        public FileEntity(HttpEntityBuilder<?> builder) throws IOException {
                super(builder);
-               this.content = (File)builder.content;
-               cache = builder.cached ? readBytes(this.content) : null;
+               content = contentOrElse(null);
+               cache = builder.cached ? readBytes(content) : null;
        }
 
        @Override /* AbstractHttpEntity */
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/HttpEntityBuilder.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/HttpEntityBuilder.java
index c8b8438..09494e7 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/HttpEntityBuilder.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/HttpEntityBuilder.java
@@ -14,6 +14,7 @@ package org.apache.juneau.http.entity;
 
 import java.io.*;
 import java.nio.charset.*;
+import java.util.function.*;
 
 import org.apache.http.*;
 import org.apache.juneau.http.header.*;
@@ -29,12 +30,14 @@ public class HttpEntityBuilder<T extends BasicHttpEntity2> {
 
        boolean cached, chunked;
        Object content;
+       Supplier<?> contentSupplier;
        ContentType contentType;
        ContentEncoding contentEncoding;
        Charset charset;
        long contentLength = -1;
 
-       private final Class<? extends BasicHttpEntity2> implClass;
+       /** The HttpEntity implementation class. */
+       protected final Class<? extends BasicHttpEntity2> implClass;
 
        /**
         * Constructor.
@@ -48,6 +51,24 @@ public class HttpEntityBuilder<T extends BasicHttpEntity2> {
        }
 
        /**
+        * Copy constructor.
+        *
+        * @param impl
+        *      The implementation object of {@link HttpEntity} to copy from.
+        *      <br>This must contain a public constructor that takes in an 
{@link HttpEntityBuilder} object.
+        */
+       public HttpEntityBuilder(T impl) {
+               implClass = impl.getClass();
+               cached = impl.cached;
+               content = impl.content;
+               contentSupplier = impl.contentSupplier;
+               contentType = impl.contentType;
+               contentEncoding = impl.contentEncoding;
+               charset = impl.charset;
+               contentLength = impl.length;
+       }
+
+       /**
         * Instantiates the entity bean from the settings in this builder.
         *
         * @return A new {@link HttpEntity} bean.
@@ -62,30 +83,30 @@ public class HttpEntityBuilder<T extends BasicHttpEntity2> {
        }
 
        /**
-        * Copies the values from the specified entity bean.
+        * Sets the content on this entity bean.
         *
-        * @param value The exception to copy from.
+        * @param value The entity content, can be <jk>null</jk>.
         * @return This object (for method chaining).
         */
-       public HttpEntityBuilder<T> copyFrom(BasicHttpEntity2 value) {
-               this.cached = value.cached;
-               this.content = value.content;
-               this.contentType = value.contentType;
-               this.contentEncoding = value.contentEncoding;
-               this.charset = value.charset;
-               this.contentLength = value.length;
+       @FluentSetter
+       public HttpEntityBuilder<T> content(Object value) {
+               this.content = value;
                return this;
        }
 
        /**
-        * Sets the content on this entity bean.
+        * Sets the content on this entity bean from a supplier.
+        *
+        * <p>
+        * Repeatable entities such as {@link StringEntity} use this to allow 
the entity content to be resolved at
+        * serialization time.
         *
         * @param value The entity content, can be <jk>null</jk>.
         * @return This object (for method chaining).
         */
        @FluentSetter
-       public HttpEntityBuilder<T> content(Object value) {
-               this.content = value;
+       public HttpEntityBuilder<T> contentSupplier(Supplier<?> value) {
+               this.contentSupplier = value == null ? ()->null : value;
                return this;
        }
 
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/InputStreamEntity.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/InputStreamEntity.java
index 6613daa..80c28d6 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/InputStreamEntity.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/InputStreamEntity.java
@@ -17,40 +17,22 @@ import static org.apache.juneau.internal.IOUtils.*;
 
 import java.io.*;
 
-import org.apache.juneau.http.header.*;
-
 /**
  * A streamed, non-repeatable entity that obtains its content from an {@link 
InputStream}.
  */
 public class InputStreamEntity extends BasicHttpEntity2 {
 
        private final InputStream content;
-       private final long length;
+       private final long maxLength;
        private final byte[] cache;
 
        /**
         * Creates a new {@link InputStreamEntity} builder.
         *
-        * <p>
-        * Assumes no content type.
-        *
-        * @param content The entity content.  Can be <jk>null<jk>.
-        * @return A new {@link InputStreamEntity} builder.
-        */
-       public static HttpEntityBuilder<InputStreamEntity> of(InputStream 
content) {
-               return new 
HttpEntityBuilder<>(InputStreamEntity.class).content(content);
-       }
-
-       /**
-        * Creates a new {@link InputStreamEntity} builder.
-        *
-        * @param content The entity content.  Can be <jk>null<jk>.
-        * @param contentType The entity content type, or <jk>null</jk> if not 
specified.
-        * @param length The content length, or <c>-1</c> if not known.
         * @return A new {@link InputStreamEntity} builder.
         */
-       public static HttpEntityBuilder<InputStreamEntity> of(InputStream 
content, long length, ContentType contentType) {
-               return new 
HttpEntityBuilder<>(InputStreamEntity.class).content(content).contentLength(length).contentType(contentType);
+       public static HttpEntityBuilder<InputStreamEntity> create() {
+               return new HttpEntityBuilder<>(InputStreamEntity.class);
        }
 
        /**
@@ -61,9 +43,9 @@ public class InputStreamEntity extends BasicHttpEntity2 {
         */
        public InputStreamEntity(HttpEntityBuilder<?> builder) throws 
IOException {
                super(builder);
-               this.content = builder.content == null ? EMPTY_INPUT_STREAM : 
(InputStream)builder.content;
-               this.cache = builder.cached ? readBytes(this.content) : null;
-               this.length = builder.contentLength == -1 && cache != null ? 
cache.length : builder.contentLength;
+               content = contentOrElse(EMPTY_INPUT_STREAM);
+               cache = builder.cached ? readBytes(content) : null;
+               maxLength = builder.contentLength == -1 && cache != null ? 
cache.length : builder.contentLength;
        }
 
        @Override /* AbstractHttpEntity */
@@ -83,7 +65,7 @@ public class InputStreamEntity extends BasicHttpEntity2 {
 
        @Override /* HttpEntity */
        public long getContentLength() {
-               return length;
+               return maxLength;
        }
 
        @Override /* HttpEntity */
@@ -102,10 +84,10 @@ public class InputStreamEntity extends BasicHttpEntity2 {
                assertArgNotNull("out", out);
 
                if (cache != null) {
-                       pipe(cache, out, (int)length);
+                       pipe(cache, out, (int)maxLength);
                } else {
                        try (InputStream is = getContent()) {
-                               pipe(is, out, length);
+                               pipe(is, out, maxLength);
                        }
                }
        }
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/ReaderEntity.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/ReaderEntity.java
index 3db0482..ca733b1 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/ReaderEntity.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/ReaderEntity.java
@@ -14,11 +14,11 @@ package org.apache.juneau.http.entity;
 
 import static org.apache.juneau.assertions.Assertions.*;
 import static org.apache.juneau.internal.IOUtils.*;
+import static org.apache.juneau.internal.ObjectUtils.*;
 
 import java.io.*;
 import java.nio.charset.*;
 
-import org.apache.juneau.http.header.*;
 import org.apache.juneau.internal.*;
 
 /**
@@ -27,33 +27,17 @@ import org.apache.juneau.internal.*;
 public class ReaderEntity extends BasicHttpEntity2 {
 
        private final Reader content;
-       private final long length;
+       private final long contentLength;
        private final Charset charset;
        private final byte[] cache;
 
        /**
         * Creates a new {@link ReaderEntity} builder.
         *
-        * <p>
-        * Assumes no content type.
-        *
-        * @param content The entity content.  Can be <jk>null<jk>.
-        * @return A new {@link ReaderEntity} builder.
-        */
-       public static HttpEntityBuilder<ReaderEntity> of(Reader content) {
-               return new 
HttpEntityBuilder<>(ReaderEntity.class).content(content);
-       }
-
-       /**
-        * Creates a new {@link ReaderEntity} builder.
-        *
-        * @param content The entity builder.  Can be <jk>null<jk>.
-        * @param contentType The entity content type, or <jk>null</jk> if not 
specified.
-        * @param length The content length, or <c>-1</c> if not known.
         * @return A new {@link ReaderEntity} builder.
         */
-       public static HttpEntityBuilder<ReaderEntity> of(Reader content, long 
length, ContentType contentType) {
-               return new 
HttpEntityBuilder<>(ReaderEntity.class).content(content).contentLength(length).contentType(contentType);
+       public static HttpEntityBuilder<ReaderEntity> create() {
+               return new HttpEntityBuilder<>(ReaderEntity.class);
        }
 
        /**
@@ -64,10 +48,10 @@ public class ReaderEntity extends BasicHttpEntity2 {
         */
        public ReaderEntity(HttpEntityBuilder<?> builder) throws IOException {
                super(builder);
-               this.content = builder.content == null ? EMPTY_READER : 
(Reader)builder.content;
-               this.charset = builder.charset == null ? UTF8 : builder.charset;
-               this.cache = builder.cached ? readBytes(this.content) : null;
-               this.length = builder.contentLength == -1 && cache != null ? 
cache.length : builder.contentLength;
+               content = contentOrElse(EMPTY_READER);
+               charset = firstNonNull(builder.charset, UTF8);
+               cache = builder.cached ? readBytes(this.content) : null;
+               contentLength = builder.contentLength == -1 && cache != null ? 
cache.length : builder.contentLength;
        }
 
        @Override /* AbstractHttpEntity */
@@ -87,7 +71,7 @@ public class ReaderEntity extends BasicHttpEntity2 {
 
        @Override /* HttpEntity */
        public long getContentLength() {
-               return length;
+               return contentLength;
        }
 
        @Override /* HttpEntity */
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/SerializedEntity.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/SerializedEntity.java
index 950c89a..1650cc9 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/SerializedEntity.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/SerializedEntity.java
@@ -15,11 +15,7 @@ package org.apache.juneau.http.entity;
 import static org.apache.juneau.internal.IOUtils.*;
 
 import java.io.*;
-import java.util.function.*;
-
-import org.apache.http.*;
 import org.apache.juneau.*;
-import org.apache.juneau.http.header.*;
 import org.apache.juneau.httppart.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.serializer.*;
@@ -27,63 +23,28 @@ import org.apache.juneau.serializer.*;
 /**
  * HttpEntity for serializing POJOs as the body of HTTP requests.
  */
-@FluentSetters
-public class SerializedEntity extends AbstractHttpEntity {
-       private final Supplier<?> content;
-       private final Serializer serializer;
-       private HttpPartSchema schema;
-
-       /**
-        * Creates a new {@link SerializedEntity} object.
-        *
-        * @param content
-        *      The Java POJO representing the content.
-        *      <br>Can be <jk>null<jk>.
-        * @param serializer
-        *      The serializer to use to serialize the POJO.
-        *      <br>If <jk>null</jk>, POJO will be converted to a string using 
{@link Object#toString()}.
-        * @return A new {@link SerializedEntity} object.
-        */
-       public static SerializedEntity of(Object content, Serializer 
serializer) {
-               return new SerializedEntity(content, serializer);
-       }
+public class SerializedEntity extends BasicHttpEntity2 {
+       final Serializer serializer;
+       HttpPartSchema schema;
 
        /**
-        * Creates a new {@link SerializedEntity} object.
+        * Creates a new {@link SerializedEntity} builder.
         *
-        * @param content
-        *      The supplier for a Java POJO representing the content.
-        *      <br>Can be <jk>null<jk>.
-        * @param serializer
-        *      The serializer to use to serialize the POJO.
-        *      <br>If <jk>null</jk>, POJO will be converted to a string using 
{@link Object#toString()}.
-        * @return A new {@link SerializedEntity} object.
+        * @return A new {@link SerializedEntity} builder.
         */
-       public static SerializedEntity of(Supplier<?> content, Serializer 
serializer) {
-               return new SerializedEntity(content == null ? ()->null : 
content, serializer);
+       public static SerializedEntityBuilder<SerializedEntity> create() {
+               return new SerializedEntityBuilder<>(SerializedEntity.class);
        }
 
        /**
         * Constructor.
         *
-        * @param content The POJO to serialize.  Can also be a {@link Reader} 
or {@link InputStream}.
-        * @param serializer The serializer to use to serialize this response.
+        * @param builder The builder for this bean.
         */
-       public SerializedEntity(Object content, Serializer serializer) {
-               this(()->content, serializer);
-       }
-
-       /**
-        * Constructor.
-        *
-        * @param content The POJO to serialize.  Can also be a {@link Reader} 
or {@link InputStream}.
-        * @param serializer The serializer to use to serialize this response.
-        */
-       public SerializedEntity(Supplier<?> content, Serializer serializer) {
-               this.content = content;
-               this.serializer = serializer;
-               if (serializer != null)
-                       
setContentType(ContentType.of(serializer.getPrimaryMediaType()));
+       public SerializedEntity(SerializedEntityBuilder<?> builder) {
+               super(builder);
+               serializer = builder.serializer;
+               schema = builder.schema;
        }
 
        /**
@@ -95,7 +56,6 @@ public class SerializedEntity extends AbstractHttpEntity {
         * @param value The schema.
         * @return This object (for method chaining).
         */
-       @FluentSetter
        public SerializedEntity schema(HttpPartSchema value) {
                this.schema = value;
                return this;
@@ -105,7 +65,7 @@ public class SerializedEntity extends AbstractHttpEntity {
        public void writeTo(OutputStream os) throws IOException {
                try {
                        os = new NoCloseOutputStream(os);
-                       Object o = content.get();
+                       Object o = contentOrElse(null);
                        if (serializer == null) {
                                try (Writer w = new OutputStreamWriter(os, 
UTF8)) {
                                        w.write(o.toString());
@@ -142,60 +102,4 @@ public class SerializedEntity extends AbstractHttpEntity {
                        throw new RuntimeException(e);
                }
        }
-
-       // <FluentSetters>
-
-       @Override /* AbstractHttpEntity */
-       public SerializedEntity cache() {
-               return this;
-       }
-
-       @Override /* GENERATED - BasicHttpEntity */
-       public SerializedEntity chunked() {
-               super.chunked();
-               return this;
-       }
-
-       @Override /* GENERATED - BasicHttpEntity */
-       public SerializedEntity chunked(boolean value) {
-               super.chunked(value);
-               return this;
-       }
-
-       @Override /* GENERATED - BasicHttpEntity */
-       public SerializedEntity contentEncoding(String value) {
-               super.contentEncoding(value);
-               return this;
-       }
-
-       @Override /* GENERATED - BasicHttpEntity */
-       public SerializedEntity contentEncoding(Header value) {
-               super.contentEncoding(value);
-               return this;
-       }
-
-       @Override /* GENERATED - BasicHttpEntity */
-       public SerializedEntity contentLength(long value) {
-               super.contentLength(value);
-               return this;
-       }
-
-       @Override /* GENERATED - BasicHttpEntity */
-       public SerializedEntity contentType(String value) {
-               super.contentType(value);
-               return this;
-       }
-
-       @Override /* GENERATED - BasicHttpEntity */
-       public SerializedEntity contentType(Header value) {
-               super.contentType(value);
-               return this;
-       }
-
-       @Override
-       public boolean isStreaming() {
-               return false;
-       }
-
-       // </FluentSetters>
 }
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/SerializedEntityBuilder.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/SerializedEntityBuilder.java
new file mode 100644
index 0000000..aa2905f
--- /dev/null
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/SerializedEntityBuilder.java
@@ -0,0 +1,118 @@
+// 
***************************************************************************************************************************
+// * 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.http.entity;
+
+import java.util.function.*;
+
+import org.apache.http.*;
+import org.apache.juneau.httppart.*;
+import org.apache.juneau.internal.*;
+import org.apache.juneau.serializer.*;
+import org.apache.juneau.http.HttpHeaders;
+
+
+/**
+ * Builder for {@link SerializedEntity} beans.
+ *
+ * @param <T> The bean type to create for this builder.
+ */
+@FluentSetters(returns="SerializedEntityBuilder<T>")
+public class SerializedEntityBuilder<T extends SerializedEntity> extends 
HttpEntityBuilder<T> {
+
+       Serializer serializer;
+       HttpPartSchema schema;
+
+       /**
+        * Constructor.
+        *
+        * @param implClass
+        *      The subclass of {@link HttpResponse} to create.
+        *      <br>This must contain a public constructor that takes in an 
{@link HttpEntityBuilder} object.
+        */
+       public SerializedEntityBuilder(Class<T> implClass) {
+               super(implClass);
+       }
+
+       /**
+        * Copy constructor.
+        *
+        * @param impl
+        *      The implementation object of {@link HttpEntity} to copy from.
+        *      <br>This must contain a public constructor that takes in an 
{@link HttpEntityBuilder} object.
+        */
+       public SerializedEntityBuilder(T impl) {
+               super(impl);
+               this.serializer = impl.serializer;
+               this.schema = impl.schema;
+       }
+
+       /**
+        * Instantiates the entity bean from the settings in this builder.
+        *
+        * @return A new {@link SerializedEntity} bean.
+        */
+       @Override
+       @SuppressWarnings("unchecked")
+       public T build() {
+               try {
+                       return (T) 
implClass.getConstructor(SerializedEntityBuilder.class).newInstance(this);
+               } catch (Exception e) {
+                       throw new RuntimeException(e);
+               }
+       }
+
+       /**
+        * Sets the serializer on this entity bean.
+        *
+        * @param value The entity serializer, can be <jk>null</jk>.
+        * @return This object (for method chaining).
+        */
+       @FluentSetter
+       public SerializedEntityBuilder<T> serializer(Serializer value) {
+               this.serializer = value;
+               if (value != null)
+                       
contentType(HttpHeaders.contentType(value.getPrimaryMediaType()));
+               return this;
+       }
+
+       /**
+        * Sets the schema on this entity bean.
+        *
+        * <p>
+        * Used to provide instructions to the serializer on how to serialize 
this object.
+        *
+        * @param value The entity schema, can be <jk>null</jk>.
+        * @return This object (for method chaining).
+        */
+       @FluentSetter
+       public SerializedEntityBuilder<T> schema(HttpPartSchema value) {
+               this.schema = value;
+               return this;
+       }
+
+       // <FluentSetters>
+
+       @Override
+       public SerializedEntityBuilder<T> content(Object value) {
+               super.content(value);
+               return this;
+       }
+
+       @Override
+       public SerializedEntityBuilder<T> contentSupplier(Supplier<?> value) {
+               super.contentSupplier(value);
+               return this;
+       }
+
+       // </FluentSetters>
+}
\ No newline at end of file
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/StringEntity.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/StringEntity.java
index 904fec9..a199507 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/StringEntity.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/StringEntity.java
@@ -14,11 +14,11 @@ package org.apache.juneau.http.entity;
 
 import static org.apache.juneau.assertions.Assertions.*;
 import static org.apache.juneau.internal.IOUtils.*;
+import static org.apache.juneau.internal.ObjectUtils.*;
 
 import java.io.*;
 import java.nio.charset.Charset;
 
-import org.apache.juneau.http.header.*;
 import org.apache.juneau.internal.*;
 
 /**
@@ -26,29 +26,18 @@ import org.apache.juneau.internal.*;
  */
 public class StringEntity extends BasicHttpEntity2 {
 
-       private final String content;
+       private static final String EMPTY = "";
+
        private final byte[] cache;
        private final Charset charset;
 
        /**
         * Creates a new {@link StringEntity} builder.
         *
-        * @param content The entity content.  Can be <jk>null</jk>.
         * @return A new {@link StringEntity} builder.
         */
-       public static HttpEntityBuilder<StringEntity> of(String content) {
-               return new 
HttpEntityBuilder<>(StringEntity.class).content(content);
-       }
-
-       /**
-        * Creates a new {@link StringEntity} builder.
-        *
-        * @param content The entity content.  Can be <jk>null</jk>.
-        * @param contentType The entity content type, or <jk>null</jk> if not 
specified.
-        * @return A new {@link StringEntity} builder.
-        */
-       public static HttpEntityBuilder<StringEntity> of(String content, 
ContentType contentType) {
-               return new 
HttpEntityBuilder<>(StringEntity.class).content(content).contentType(contentType);
+       public static HttpEntityBuilder<StringEntity> create() {
+               return new HttpEntityBuilder<>(StringEntity.class);
        }
 
        /**
@@ -58,14 +47,22 @@ public class StringEntity extends BasicHttpEntity2 {
         */
        public StringEntity(HttpEntityBuilder<?> builder) {
                super(builder);
-               content = builder.content == null ? "" : 
(String)builder.content;
-               charset = builder.charset == null ? UTF8 : builder.charset;
-               cache = builder.cached ? this.content.getBytes(charset) : null;
+               charset = firstNonNull(builder.charset, UTF8);
+               cache = builder.cached ? string().getBytes(charset) : null;
+       }
+
+       @Override
+       public HttpEntityBuilder<StringEntity> builder() {
+               return new HttpEntityBuilder<>(this);
+       }
+
+       private String string() {
+               return contentOrElse(EMPTY);
        }
 
        @Override
        public byte[] asBytes() throws IOException {
-               return cache == null ? content.getBytes() : cache;
+               return cache == null ? string().getBytes() : cache;
        }
 
        @Override /* HttpEntity */
@@ -78,18 +75,19 @@ public class StringEntity extends BasicHttpEntity2 {
                if (cache != null)
                        return cache.length;
                long l = super.getContentLength();
-               if (l != -1)
+               if (l != -1 || isSupplied())
                        return l;
+               String s = string();
                if (charset == UTF8)
-                       for (int i = 0; i < content.length(); i++)
-                               if (content.charAt(i) > 127)
+                       for (int i = 0; i < s.length(); i++)
+                               if (s.charAt(i) > 127)
                                        return -1;
-               return content.length();
+               return s.length();
        }
 
        @Override /* HttpEntity */
        public InputStream getContent() throws IOException {
-               return cache == null ? new ReaderInputStream(new 
StringReader(content), charset) : new ByteArrayInputStream(cache);
+               return cache == null ? new ReaderInputStream(new 
StringReader(string()), charset) : new ByteArrayInputStream(cache);
        }
 
        @Override /* HttpEntity */
@@ -99,7 +97,7 @@ public class StringEntity extends BasicHttpEntity2 {
                        out.write(cache);
                } else {
                        OutputStreamWriter osw = new OutputStreamWriter(out, 
charset);
-                       osw.write(content);
+                       osw.write(string());
                        osw.flush();
                }
        }
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 8ecb2b7..77935db 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
@@ -18,6 +18,7 @@ import static org.apache.juneau.httppart.HttpPartType.*;
 import static org.apache.juneau.http.HttpMethod.*;
 import static org.apache.juneau.http.HttpHeaders.*;
 import static org.apache.juneau.http.HttpParts.*;
+import static org.apache.juneau.http.HttpEntities.*;
 import static java.util.logging.Level.*;
 import static org.apache.juneau.internal.StateMachineState.*;
 import static java.lang.Character.*;
@@ -2543,7 +2544,7 @@ public class RestClient extends BeanContext implements 
HttpClient, Closeable, Re
                        }
                        if (body instanceof Reader || body instanceof 
InputStream)
                                return 
req.contentType("application/x-www-form-urlencoded").body(body);
-                       return req.body(SerializedEntity.of(body, 
urlEncodingSerializer));
+                       return req.body(serializedEntity(body, 
urlEncodingSerializer, null).build());
                } catch (IOException e) {
                        throw new RestCallException(null, e, "Could not read 
form post body.");
                }
diff --git 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestRequest.java
 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestRequest.java
index 6a22569..ce96771 100644
--- 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestRequest.java
+++ 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestRequest.java
@@ -2909,7 +2909,7 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
                                else if (input2 instanceof InputStream)
                                        entity = 
streamEntity((InputStream)input2, -1, 
getRequestContentType(ContentType.APPLICATION_OCTET_STREAM)).build();
                                else if (serializer != null)
-                                       entity = SerializedEntity.of(input2, 
serializer).schema(requestBodySchema).contentType(contentType);
+                                       entity = serializedEntity(input2, 
serializer, requestBodySchema).contentType(contentType).build();
                                else {
                                        if (client.hasSerializers()) {
                                                if (contentType == null)
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/http/SerializedHttpEntity_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/http/SerializedHttpEntity_Test.java
index d143d6c..b062c72 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/http/SerializedHttpEntity_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/http/SerializedHttpEntity_Test.java
@@ -17,9 +17,9 @@ import static org.junit.runners.MethodSorters.*;
 import java.io.*;
 
 import static org.apache.juneau.httppart.HttpPartSchema.*;
+import static org.apache.juneau.http.HttpEntities.*;
 
 import org.apache.juneau.collections.*;
-import org.apache.juneau.http.entity.*;
 import org.apache.juneau.httppart.*;
 import org.apache.juneau.json.*;
 import org.apache.juneau.msgpack.*;
@@ -31,8 +31,6 @@ import org.apache.juneau.rest.mock.*;
 import org.apache.juneau.testutils.pojos.*;
 
 import static org.apache.juneau.assertions.Assertions.*;
-import static org.apache.juneau.http.entity.SerializedEntity.*;
-
 import org.junit.*;
 
 @FixMethodOrder(NAME_ASCENDING)
@@ -52,70 +50,62 @@ public class SerializedHttpEntity_Test {
 
        @Test
        public void a01_basic() throws Exception {
-               
of(ABean.get(),JsonSerializer.DEFAULT).assertString().is("{\"a\":1,\"b\":\"foo\"}");
-               
of(()->ABean.get(),JsonSerializer.DEFAULT).assertString().is("{\"a\":1,\"b\":\"foo\"}");
-               of(ABean.get(),null).assertString().is("{a:1,b:'foo'}");
-               of(null,JsonSerializer.DEFAULT).assertString().is("null");
+               
serializedEntity(ABean.get(),JsonSerializer.DEFAULT).build().assertString().is("{\"a\":1,\"b\":\"foo\"}");
+               
serializedEntity(()->ABean.get(),JsonSerializer.DEFAULT).build().assertString().is("{\"a\":1,\"b\":\"foo\"}");
+               
serializedEntity(ABean.get(),null).build().assertString().is("{a:1,b:'foo'}");
+               
serializedEntity(null,JsonSerializer.DEFAULT).build().assertString().is("null");
        }
 
        @Test
        public void a02_schema() throws Exception {
-               
of(AList.of("foo","bar"),OpenApiSerializer.DEFAULT).schema(T_ARRAY_PIPES).assertString().is("foo|bar");
+               
serializedEntity(AList.of("foo","bar"),OpenApiSerializer.DEFAULT).schema(T_ARRAY_PIPES).build().assertString().is("foo|bar");
        }
 
        @Test
        public void a03_serializer_streaming() throws Exception {
-               
of(ABean.get(),MsgPackSerializer.DEFAULT).assertBytes().asSpacedHex().is("82 A1 
61 01 A1 62 A3 66 6F 6F");
+               
serializedEntity(ABean.get(),MsgPackSerializer.DEFAULT).build().assertBytes().asSpacedHex().is("82
 A1 61 01 A1 62 A3 66 6F 6F");
        }
 
        @Test
        public void a04_serializer_bad() throws Exception {
-               
assertThrown(()->of(null,OpenApiSerializer.DEFAULT).schema(schema().required().build()).asString()).contains("Required
 value not provided.");
+               
assertThrown(()->serializedEntity(null,OpenApiSerializer.DEFAULT).schema(schema().required().build()).build().asString()).contains("Required
 value not provided.");
        }
 
        @Test
        public void a05_writeTo() throws Exception {
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
-               of("foo", null).writeTo(baos);
+               serializedEntity("foo", null).build().writeTo(baos);
                assertBytes(baos.toByteArray()).asString().is("foo");
        }
 
        @Test
        public void a06_isRepeatable() throws Exception {
-               assertBoolean(of(ABean.get(),null).isRepeatable()).isTrue();
+               
assertBoolean(serializedEntity(ABean.get(),null).build().isRepeatable()).isTrue();
        }
 
        @Test
        public void a07_getContentLength() throws Exception {
-               assertLong(of(ABean.get(),null).getContentLength()).is(-1);
+               
assertLong(serializedEntity(ABean.get(),null).build().getContentLength()).is(-1);
        }
 
        @Test
        public void a08_getContent() throws Exception {
-               assertStream(of("foo",null).getContent()).asString().is("foo");
-
-               SerializedEntity x = new SerializedEntity("foo", null) {
-                       @Override
-                       public void writeTo(OutputStream os) throws IOException 
{
-                               throw new IOException("Bad");
-                       }
-               };
-               assertThrown(()->x.getContent()).contains("Bad");
+               
assertStream(serializedEntity("foo",null).build().getContent()).asString().is("foo");
        }
 
        @Test
        public void a09_chunked() throws Exception {
-               
checkHeaderClient("Transfer-Encoding").post("/",of(ABean.get(),null).chunked()).run().assertBody().is("['chunked']");
+               
checkHeaderClient("Transfer-Encoding").post("/",serializedEntity(ABean.get(),null).chunked().build()).run().assertBody().is("['chunked']");
        }
 
        @Test
        public void a10_contentEncoding() throws Exception {
-               
checkHeaderClient("Content-Encoding").post("/",of(ABean.get(),null).contentEncoding("identity")).run().assertBody().is("['identity']");
+               
checkHeaderClient("Content-Encoding").post("/",serializedEntity(ABean.get(),null).contentEncoding("identity").build()).run().assertBody().is("['identity']");
        }
 
        @Test
        public void a12_contentType() throws Exception {
-               checkHeaderClient("Content-Type").post("/",of(new 
StringReader("foo"),null).contentType("text/foo")).run().assertBody().is("['text/foo']");
+               checkHeaderClient("Content-Type").post("/",serializedEntity(new 
StringReader("foo"),null).contentType("text/foo").build()).run().assertBody().is("['text/foo']");
        }
 
        
//------------------------------------------------------------------------------------------------------------------
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 240bde0..80353d0 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
@@ -12,7 +12,6 @@
 // 
***************************************************************************************************************************
 package org.apache.juneau.rest.client;
 
-import static org.apache.juneau.assertions.Assertions.*;
 import static org.apache.juneau.http.HttpHeaders.*;
 import static org.apache.juneau.http.HttpEntities.*;
 import static org.junit.runners.MethodSorters.*;
@@ -157,7 +156,7 @@ public class RestClient_Body_Test {
        public void a03_SerializedHttpEntity() throws Exception {
                Serializer js = JsonSerializer.DEFAULT;
 
-               SerializedEntity x1 = serializedEntity(ABean.get(),null);
+               SerializedEntity x1 = 
serializedEntity(ABean.get(),null,null).build();
                client().build().post("/",x1).run()
                        .assertHeader("X-Content-Length").doesNotExist()
                        .assertHeader("X-Content-Encoding").doesNotExist()
@@ -165,28 +164,19 @@ public class RestClient_Body_Test {
                        .assertHeader("X-Transfer-Encoding").is("chunked")  // 
Because content length is -1.
                ;
 
-               SerializedEntity x2 = serializedEntity(ABean.get(),js);
+               SerializedEntity x2 = 
serializedEntity(ABean.get(),js,null).build();
                client().build().post("/",x2).run()
                        .assertHeader("X-Content-Length").doesNotExist()
                        .assertHeader("X-Content-Encoding").doesNotExist()
                        .assertHeader("X-Content-Type").is("application/json")
                        
.assertBody().asType(ABean.class).asJson().is("{a:1,b:'foo'}");
 
-               SerializedEntity x3 = SerializedEntity.of(()->ABean.get(),js);
+               SerializedEntity x3 = 
serializedEntity(()->ABean.get(),js,null).build();
                client().build().post("/",x3).run()
                        .assertHeader("X-Content-Length").doesNotExist()
                        .assertHeader("X-Content-Encoding").doesNotExist()
                        .assertHeader("X-Content-Type").is("application/json")
                        
.assertBody().asType(ABean.class).asJson().is("{a:1,b:'foo'}");
-
-               SerializedEntity x12 = new SerializedEntity(ABean.get(), null) {
-                       @Override
-                       public void writeTo(OutputStream os) throws IOException 
{
-                               throw new IOException("bad");
-                       }
-               };
-
-               assertThrown(()->x12.getContent()).contains("bad");
        }
 
        
//------------------------------------------------------------------------------------------------------------------

Reply via email to