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 2e0d823 org.apache.juneau.http tests.
2e0d823 is described below
commit 2e0d8235e0edfb34f526513f99b09311e3960dc5
Author: JamesBognar <[email protected]>
AuthorDate: Sat Jul 11 13:26:00 2020 -0400
org.apache.juneau.http tests.
---
.../org/apache/juneau/http/BasicHttpEntity.java | 344 +++++++++++++++++++++
.../org/apache/juneau/http/BasicHttpResource.java | 198 +++++-------
.../org/apache/juneau/http/ReaderResource.java | 62 +++-
.../juneau/http/ResolvingReaderResource.java | 123 +++++++-
.../org/apache/juneau/http/SerializedHeader.java | 20 ++
.../apache/juneau/http/SerializedHttpEntity.java | 79 +++--
.../juneau/http/SerializedNameValuePair.java | 19 ++
.../org/apache/juneau/http/StreamResource.java | 68 +++-
.../main/ConfigurablePropertyCodeGenerator.java | 1 +
.../apache/juneau/http/BasicHttpResource_Test.java | 16 +
.../rest/client2/RestClient_FormData_Test.java | 24 +-
.../rest/client2/RestClient_Headers_Test.java | 19 ++
12 files changed, 807 insertions(+), 166 deletions(-)
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/BasicHttpEntity.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/BasicHttpEntity.java
new file mode 100644
index 0000000..c2341f0
--- /dev/null
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/BasicHttpEntity.java
@@ -0,0 +1,344 @@
+//
***************************************************************************************************************************
+// * 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;
+
+import java.io.*;
+import java.util.function.*;
+
+import org.apache.http.*;
+import org.apache.juneau.internal.*;
+
+/**
+ * An extension of {@link org.apache.http.entity.BasicHttpEntity} with fluent
setters.
+ *
+ * <p>
+ * Includes automatic support for a variety of content types.
+ */
+public class BasicHttpEntity extends org.apache.http.entity.BasicHttpEntity {
+ private Object content;
+ private boolean cache;
+
+ /**
+ * Creator.
+ *
+ * @param content
+ * The content.
+ * <br>Can be any of the following:
+ * <ul>
+ * <li><c>InputStream</c>
+ * <li><c>Reader</c> - Converted to UTF-8 bytes.
+ * <li><c>File</c>
+ * <li><c>CharSequence</c> - Converted to UTF-8 bytes.
+ * <li><c><jk>byte</jk>[]</c>.
+ * <li>A {@link Supplier} of anything on this list.
+ * </ul>
+ * </ul>
+ * @return A new empty {@link ReaderResource} object.
+ */
+ public static BasicHttpEntity of(Object content) {
+ return new BasicHttpEntity().content(content);
+ }
+
+ /**
+ * Creator.
+ *
+ * @param content
+ * The content.
+ * <br>Can be any of the following:
+ * <ul>
+ * <li><c>InputStream</c>
+ * <li><c>Reader</c> - Converted to UTF-8 bytes.
+ * <li><c>File</c>
+ * <li><c>CharSequence</c> - Converted to UTF-8 bytes.
+ * <li><c><jk>byte</jk>[]</c>.
+ * <li>A {@link Supplier} of anything on this list.
+ * </ul>
+ * </ul>
+ * @return A new empty {@link ReaderResource} object.
+ */
+ public static BasicHttpEntity of(Supplier<?> content) {
+ return new BasicHttpEntity().content(content);
+ }
+
+ /**
+ * Creates a new basic entity.
+ * The content is initially missing, the content length
+ * is set to a negative number.
+ */
+ public BasicHttpEntity() {
+ super();
+ }
+
+ /**
+ * Sets the content on this entity.
+ *
+ * @param value
+ * The content.
+ * <br>Can be any of the following:
+ * <ul>
+ * <li><c>InputStream</c>
+ * <li><c>Reader</c> - Converted to UTF-8 bytes.
+ * <li><c>File</c>
+ * <li><c>CharSequence</c> - Converted to UTF-8 bytes.
+ * <li><c><jk>byte</jk>[]</c>.
+ * <li>A {@link Supplier} of anything on this list.
+ * </ul>
+ * </ul>
+ * @return This object (for method chaining).
+ */
+ @FluentSetter
+ public BasicHttpEntity content(Object value) {
+ this.content = value;
+ return this;
+ }
+
+ /**
+ * Sets the content on this entity.
+ *
+ * @param value
+ * The content.
+ * <br>Can be any of the following:
+ * <ul>
+ * <li><c>InputStream</c>
+ * <li><c>Reader</c> - Converted to UTF-8 bytes.
+ * <li><c>File</c>
+ * <li><c>CharSequence</c> - Converted to UTF-8 bytes.
+ * <li><c><jk>byte</jk>[]</c>.
+ * <li>A {@link Supplier} of anything on this list.
+ * </ul>
+ * </ul>
+ * @return This object (for method chaining).
+ */
+ @FluentSetter
+ public BasicHttpEntity content(Supplier<?> value) {
+ this.content = value;
+ return this;
+ }
+
+ /**
+ * Shortcut for calling {@link #setContentType(String)}.
+ *
+ * @param value The new <c>Content-Type</ header, or <jk>null</jk> to
unset.
+ * @return This object (for method chaining).
+ */
+ @FluentSetter
+ public BasicHttpEntity contentType(String value) {
+ super.setContentType(value);
+ return this;
+ }
+
+ /**
+ * Shortcut for calling {@link #setContentType(Header)}.
+ *
+ * @param value The new <c>Content-Type</ header, or <jk>null</jk> to
unset.
+ * @return This object (for method chaining).
+ */
+ @FluentSetter
+ public BasicHttpEntity contentType(Header value) {
+ super.setContentType(value);
+ return this;
+ }
+
+ /**
+ * Shortcut for calling {@link #setContentLength(long)}.
+ *
+ * @param value The new <c>Content-Length</c> header value.
+ * @return This object (for method chaining).
+ */
+ @FluentSetter
+ public BasicHttpEntity contentLength(long value) {
+ super.setContentLength(value);
+ return this;
+ }
+
+ /**
+ * Shortcut for calling {@link #setContentEncoding(String)}.
+ *
+ * @param value The new <c>Content-Encoding</ header, or <jk>null</jk>
to unset.
+ * @return This object (for method chaining).
+ */
+ @FluentSetter
+ public BasicHttpEntity contentEncoding(String value) {
+ super.setContentEncoding(value);
+ return this;
+ }
+
+ /**
+ * Shortcut for calling {@link #setContentEncoding(Header)}.
+ *
+ * @param value The new <c>Content-Encoding</ header, or <jk>null</jk>
to unset.
+ * @return This object (for method chaining).
+ */
+ @FluentSetter
+ public BasicHttpEntity contentEncoding(Header value) {
+ super.setContentEncoding(value);
+ return this;
+ }
+
+ /**
+ * Shortcut for calling {@link #setChunked(boolean)} with <jk>true</jk>.
+ *
+ * @return This object (for method chaining).
+ */
+ @FluentSetter
+ public BasicHttpEntity chunked() {
+ super.setChunked(true);
+ return this;
+ }
+
+ /**
+ * Shortcut for calling {@link #setChunked(boolean)}.
+ *
+ * @param value The new value for this flag.
+ * @return This object (for method chaining).
+ */
+ @FluentSetter
+ public BasicHttpEntity chunked(boolean value) {
+ super.setChunked(value);
+ return this;
+ }
+
+ /**
+ * Specifies that the contents of this resource should be cached into
an internal byte array so that it can
+ * be read multiple times.
+ *
+ * @return This object (for method chaining).
+ */
+ @FluentSetter
+ public BasicHttpEntity cache() {
+ return cache(true);
+ }
+
+ /**
+ * Specifies that the contents of this resource should be cached into
an internal byte array so that it can
+ * be read multiple times.
+ *
+ * @param value The new value for this flag.
+ * @return This object (for method chaining).
+ */
+ @FluentSetter
+ public BasicHttpEntity cache(boolean value) {
+ this.cache = value;
+ return this;
+ }
+
+ @Override
+ public boolean isRepeatable() {
+ return cache || content instanceof File || content instanceof
CharSequence || content instanceof byte[];
+ }
+
+ @Override
+ public long getContentLength() {
+ try {
+ tryCache();
+ } catch (IOException e) {}
+ if (content instanceof byte[])
+ return ((byte[])content).length;
+ if (content instanceof File)
+ return ((File)content).length();
+ if (content instanceof CharSequence)
+ return ((CharSequence)content).length();
+ return -1;
+ }
+
+ @Override
+ public InputStream getContent() {
+ try {
+ tryCache();
+ if (content == null)
+ return null;
+ if (content instanceof File)
+ return new FileInputStream((File)content);
+ if (content instanceof byte[])
+ return new
ByteArrayInputStream((byte[])content);
+ if (content instanceof Reader)
+ return new ReaderInputStream((Reader)content,
IOUtils.UTF8);
+ if (content instanceof InputStream)
+ return (InputStream)content;
+ return new ReaderInputStream(new
StringReader(content.toString()),IOUtils.UTF8);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public void writeTo(OutputStream os) throws IOException {
+ tryCache();
+ if (content != null)
+ IOUtils.pipe(content, os);
+ os.flush();
+ }
+
+ @Override
+ public boolean isStreaming() {
+ return (content instanceof InputStream || content instanceof
Reader);
+ }
+
+ /**
+ * Returns the raw content of this resource.
+ *
+ * @return The raw content of this resource.
+ */
+ protected Object getRawContent() {
+ return unwrap(content);
+ }
+
+ private void tryCache() throws IOException {
+ if (cache && isCacheable(content))
+ content = readBytes(content);
+ }
+
+ /**
+ * Returns <jk>true</jk> if the specified object is cachable as a byte
array.
+ *
+ * <p>
+ * The default implementation returns <jk>true</jk> for the following
types:
+ * <ul>
+ * <li>{@link File}
+ * <li>{@link InputStream}
+ * <li>{@link Reader}
+ *
+ * @param o The object to check.
+ * @return <jk>true</jk> if the specified object is cachable as a byte
array.
+ */
+ protected boolean isCacheable(Object o) {
+ return (o instanceof File || o instanceof InputStream || o
instanceof Reader);
+ }
+
+ /**
+ * Reads the contents of the specified object as a byte array.
+ *
+ * @param o The object to read.
+ * @return The byte array contents.
+ * @throws IOException If object could not be read.
+ */
+ protected byte[] readBytes(Object o) throws IOException {
+ return IOUtils.readBytes(o);
+ }
+
+ /**
+ * If the specified object is a {@link Supplier}, returns the supplied
value, otherwise the same value.
+ *
+ * @param o The object to unwrap.
+ * @return The unwrapped object.
+ */
+ protected Object unwrap(Object o) {
+ while (o instanceof Supplier)
+ o = ((Supplier<?>)o).get();
+ return o;
+ }
+
+ // <FluentSetters>
+
+ // </FluentSetters>
+}
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/BasicHttpResource.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/BasicHttpResource.java
index cea51c9..76a454a 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/BasicHttpResource.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/BasicHttpResource.java
@@ -12,24 +12,21 @@
//
***************************************************************************************************************************
package org.apache.juneau.http;
-import java.io.*;
import java.util.*;
+import java.util.function.*;
import org.apache.http.*;
-import org.apache.http.entity.*;
import org.apache.juneau.collections.*;
import org.apache.juneau.internal.*;
import org.apache.juneau.http.header.*;
import org.apache.juneau.http.header.ContentType;
/**
- * An abstract subclass of all {@link HttpResource} objects.
+ * An extension of an {@link HttpEntity} with support for arbitrary headers.
*/
-public class BasicHttpResource extends AbstractHttpEntity implements
HttpResource {
+public class BasicHttpResource extends BasicHttpEntity implements HttpResource
{
private final List<Header> headers = AList.of();
- private Object content;
- private boolean cache;
/**
* Creator.
@@ -52,6 +49,7 @@ public class BasicHttpResource extends AbstractHttpEntity
implements HttpResourc
* <li><c>File</c>
* <li><c>CharSequence</c> - Converted to UTF-8 bytes.
* <li><c><jk>byte</jk>[]</c>.
+ * <li>A {@link Supplier} of anything on this list.
* </ul>
* </ul>
* @return A new empty {@link ReaderResource} object.
@@ -61,6 +59,27 @@ public class BasicHttpResource extends AbstractHttpEntity
implements HttpResourc
}
/**
+ * Creator.
+ *
+ * @param content
+ * The content.
+ * <br>Can be any of the following:
+ * <ul>
+ * <li><c>InputStream</c>
+ * <li><c>Reader</c> - Converted to UTF-8 bytes.
+ * <li><c>File</c>
+ * <li><c>CharSequence</c> - Converted to UTF-8 bytes.
+ * <li><c><jk>byte</jk>[]</c>.
+ * <li>A {@link Supplier} of anything on this list.
+ * </ul>
+ * </ul>
+ * @return A new empty {@link ReaderResource} object.
+ */
+ public static BasicHttpResource of(Supplier<?> content) {
+ return new BasicHttpResource().content(content);
+ }
+
+ /**
* Constructor.
*/
public BasicHttpResource() {
@@ -85,67 +104,15 @@ public class BasicHttpResource extends AbstractHttpEntity
implements HttpResourc
* <li><c>File</c>
* <li><c>CharSequence</c> - Converted to UTF-8 bytes.
* <li><c><jk>byte</jk>[]</c>.
+ * <li>A {@link Supplier} of anything on this list.
* </ul>
* </ul>
*/
public BasicHttpResource(ContentType contentType, ContentEncoding
contentEncoding, Object content) {
- setContentType(contentType);
- setContentEncoding(contentEncoding);
- this.content = content;
- }
-
- /**
- * Returns the raw content of this resource.
- *
- * @return The raw content of this resource.
- */
- protected Object getRawContent() {
- return content;
- }
-
- @Override
- @FluentSetter
- public BasicHttpResource chunked() {
- super.setChunked(true);
- return this;
- }
-
- @Override
- @FluentSetter
- public BasicHttpResource contentType(Header value) {
- super.setContentType(value);
- return this;
- }
-
- /**
- * Shortcut for calling {@link #contentType(String)}.
- *
- * @param value The new <c>Content-Type</ header, or <jk>null</jk> to
unset.
- * @return This object (for method chaining).
- */
- @FluentSetter
- public BasicHttpResource contentType(String value) {
- super.setContentType(value);
- return this;
- }
-
- @Override
- @FluentSetter
- public BasicHttpResource contentEncoding(Header value) {
- super.setContentEncoding(value);
- return this;
- }
-
- /**
- * Shortcut for calling {@link #setContentEncoding(String)}.
- *
- * @param value The new <c>Content-Encoding</ header, or <jk>null</jk>
to unset.
- * @return This object (for method chaining).
- */
- @FluentSetter
- public BasicHttpResource contentEncoding(String value) {
- super.setContentEncoding(value);
- return this;
+ super();
+ content(content);
+ contentType(contentType);
+ contentEncoding(contentEncoding);
}
/**
@@ -233,79 +200,78 @@ public class BasicHttpResource extends AbstractHttpEntity
implements HttpResourc
return null;
}
- @Override
- @FluentSetter
- public BasicHttpResource content(Object value) {
- this.content = value;
- return this;
+ @Override /* Resource */
+ public List<Header> getHeaders() {
+ return Collections.unmodifiableList(headers);
}
- @Override
- @FluentSetter
+ // <FluentSetters>
+
+ @Override /* GENERATED - BasicHttpEntity */
public BasicHttpResource cache() {
- this.cache = true;
+ super.cache();
return this;
}
- @Override /* Resource */
- public List<Header> getHeaders() {
- return Collections.unmodifiableList(headers);
+ @Override /* GENERATED - BasicHttpEntity */
+ public BasicHttpResource cache(boolean value) {
+ super.cache(value);
+ return this;
}
- @Override
- public boolean isRepeatable() {
- return cache || content instanceof File || content instanceof
CharSequence || content instanceof byte[];
+ @Override /* GENERATED - BasicHttpEntity */
+ public BasicHttpResource chunked() {
+ super.chunked();
+ return this;
}
- @Override
- public long getContentLength() {
- try {
- tryCache();
- } catch (IOException e) {}
- if (content instanceof byte[])
- return ((byte[])content).length;
- if (content instanceof File)
- return ((File)content).length();
- if (content instanceof CharSequence)
- return ((CharSequence)content).length();
- return -1;
+ @Override /* GENERATED - BasicHttpEntity */
+ public BasicHttpResource chunked(boolean value) {
+ super.chunked(value);
+ return this;
}
- @Override
- public InputStream getContent() throws IOException,
UnsupportedOperationException {
- tryCache();
- if (content == null)
- return null;
- if (content instanceof File)
- return new FileInputStream((File)content);
- if (content instanceof byte[])
- return new ByteArrayInputStream((byte[])content);
- if (content instanceof Reader)
- return new ReaderInputStream((Reader)content,
IOUtils.UTF8);
- if (content instanceof InputStream)
- return (InputStream)content;
- return new ReaderInputStream(new
StringReader(content.toString()),IOUtils.UTF8);
+ @Override /* GENERATED - BasicHttpEntity */
+ public BasicHttpResource content(Object value) {
+ super.content(value);
+ return this;
}
- @Override
- public void writeTo(OutputStream os) throws IOException {
- if (content != null)
- IOUtils.pipe(content, os);
- os.flush();
+ @Override /* GENERATED - BasicHttpEntity */
+ public BasicHttpResource content(Supplier<?> value) {
+ super.content(value);
+ return this;
}
- @Override
- public boolean isStreaming() {
- return (content instanceof InputStream || content instanceof
Reader);
+ @Override /* GENERATED - BasicHttpEntity */
+ public BasicHttpResource contentEncoding(String value) {
+ super.contentEncoding(value);
+ return this;
}
- private void tryCache() throws IOException {
- if (cache)
- if (content instanceof File || content instanceof
InputStream || content instanceof Reader)
- content = IOUtils.readBytes(content);
+ @Override /* GENERATED - BasicHttpEntity */
+ public BasicHttpResource contentEncoding(Header value) {
+ super.contentEncoding(value);
+ return this;
}
- // <FluentSetters>
+ @Override /* GENERATED - BasicHttpEntity */
+ public BasicHttpResource contentLength(long value) {
+ super.contentLength(value);
+ return this;
+ }
+
+ @Override /* GENERATED - BasicHttpEntity */
+ public BasicHttpResource contentType(String value) {
+ super.contentType(value);
+ return this;
+ }
+
+ @Override /* GENERATED - BasicHttpEntity */
+ public BasicHttpResource contentType(Header value) {
+ super.contentType(value);
+ return this;
+ }
// </FluentSetters>
}
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ReaderResource.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ReaderResource.java
index 86148fd..0fda49a 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ReaderResource.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ReaderResource.java
@@ -14,6 +14,7 @@ package org.apache.juneau.http;
import java.io.*;
import java.util.*;
+import java.util.function.*;
import org.apache.http.Header;
import org.apache.juneau.assertions.*;
@@ -60,6 +61,7 @@ public class ReaderResource extends BasicHttpResource {
* <li><c>File</c>
* <li><c>CharSequence</c> - Converted to UTF-8 bytes.
* <li><c><jk>byte</jk>[]</c>.
+ * <li>A {@link Supplier} of anything on this list.
* </ul>
* </ul>
* @return A new empty {@link ReaderResource} object.
@@ -69,6 +71,27 @@ public class ReaderResource extends BasicHttpResource {
}
/**
+ * Creator.
+ *
+ * @param content
+ * The content.
+ * <br>Can be any of the following:
+ * <ul>
+ * <li><c>InputStream</c>
+ * <li><c>Reader</c> - Converted to UTF-8 bytes.
+ * <li><c>File</c>
+ * <li><c>CharSequence</c> - Converted to UTF-8 bytes.
+ * <li><c><jk>byte</jk>[]</c>.
+ * <li>A {@link Supplier} of anything on this list.
+ * </ul>
+ * </ul>
+ * @return A new empty {@link ReaderResource} object.
+ */
+ public static ReaderResource of(Supplier<?> content) {
+ return new ReaderResource().content(content);
+ }
+
+ /**
* Constructor.
*/
public ReaderResource() {
@@ -93,6 +116,7 @@ public class ReaderResource extends BasicHttpResource {
* <li><c>File</c>
* <li><c>CharSequence</c> - Converted to UTF-8 bytes.
* <li><c><jk>byte</jk>[]</c>.
+ * <li>A {@link Supplier} of anything on this list.
* </ul>
* </ul>
*/
@@ -122,43 +146,67 @@ public class ReaderResource extends BasicHttpResource {
// <FluentSetters>
- @Override /* GENERATED - BasicHttpResource */
+ @Override /* GENERATED - BasicHttpEntity */
public ReaderResource cache() {
super.cache();
return this;
}
- @Override /* GENERATED - BasicHttpResource */
+ @Override /* GENERATED - BasicHttpEntity */
+ public ReaderResource cache(boolean value) {
+ super.cache(value);
+ return this;
+ }
+
+ @Override /* GENERATED - BasicHttpEntity */
public ReaderResource chunked() {
super.chunked();
return this;
}
- @Override /* GENERATED - BasicHttpResource */
+ @Override /* GENERATED - BasicHttpEntity */
+ public ReaderResource chunked(boolean value) {
+ super.chunked(value);
+ return this;
+ }
+
+ @Override /* GENERATED - BasicHttpEntity */
public ReaderResource content(Object value) {
super.content(value);
return this;
}
- @Override /* GENERATED - BasicHttpResource */
+ @Override /* GENERATED - BasicHttpEntity */
+ public ReaderResource content(Supplier<?> value) {
+ super.content(value);
+ return this;
+ }
+
+ @Override /* GENERATED - BasicHttpEntity */
public ReaderResource contentEncoding(String value) {
super.contentEncoding(value);
return this;
}
- @Override /* GENERATED - BasicHttpResource */
+ @Override /* GENERATED - BasicHttpEntity */
public ReaderResource contentEncoding(Header value) {
super.contentEncoding(value);
return this;
}
- @Override /* GENERATED - BasicHttpResource */
+ @Override /* GENERATED - BasicHttpEntity */
+ public ReaderResource contentLength(long value) {
+ super.contentLength(value);
+ return this;
+ }
+
+ @Override /* GENERATED - BasicHttpEntity */
public ReaderResource contentType(String value) {
super.contentType(value);
return this;
}
- @Override /* GENERATED - BasicHttpResource */
+ @Override /* GENERATED - BasicHttpEntity */
public ReaderResource contentType(Header value) {
super.contentType(value);
return this;
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ResolvingReaderResource.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ResolvingReaderResource.java
index e4c9673..b7ff536 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ResolvingReaderResource.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ResolvingReaderResource.java
@@ -14,6 +14,7 @@ package org.apache.juneau.http;
import java.io.*;
import java.util.*;
+import java.util.function.*;
import org.apache.http.*;
import org.apache.juneau.http.header.*;
@@ -25,6 +26,7 @@ import org.apache.juneau.svl.*;
*/
public class ResolvingReaderResource extends ReaderResource {
+ private VarResolver varResolver;
private VarResolverSession varSession;
/**
@@ -37,6 +39,48 @@ public class ResolvingReaderResource extends ReaderResource {
}
/**
+ * Creator.
+ *
+ * @param content
+ * The content.
+ * <br>Can be any of the following:
+ * <ul>
+ * <li><c>InputStream</c>
+ * <li><c>Reader</c> - Converted to UTF-8 bytes.
+ * <li><c>File</c>
+ * <li><c>CharSequence</c> - Converted to UTF-8 bytes.
+ * <li><c><jk>byte</jk>[]</c>.
+ * <li>A {@link Supplier} of anything on this list.
+ * </ul>
+ * </ul>
+ * @return A new empty {@link ResolvingReaderResource} object.
+ */
+ public static ResolvingReaderResource of(Object content) {
+ return new ResolvingReaderResource().content(content);
+ }
+
+ /**
+ * Creator.
+ *
+ * @param content
+ * The content.
+ * <br>Can be any of the following:
+ * <ul>
+ * <li><c>InputStream</c>
+ * <li><c>Reader</c> - Converted to UTF-8 bytes.
+ * <li><c>File</c>
+ * <li><c>CharSequence</c> - Converted to UTF-8 bytes.
+ * <li><c><jk>byte</jk>[]</c>.
+ * <li>A {@link Supplier} of anything on this list.
+ * </ul>
+ * </ul>
+ * @return A new empty {@link ResolvingReaderResource} object.
+ */
+ public static ResolvingReaderResource of(Supplier<?> content) {
+ return new ResolvingReaderResource().content(content);
+ }
+
+ /**
* Constructor.
*/
public ResolvingReaderResource() {
@@ -52,7 +96,12 @@ public class ResolvingReaderResource extends ReaderResource {
* @param contentEncoding
* The content encoding of the contents.
* <br>Can be <jk>null</jk>.
- * @param varSession Var resolver session for resolving SVL variables.
+ * @param varResolver
+ * The var resolver for resolving SVL variables.
+ * <br>Only one of <c>varResolver</c> and <c>varSession</c> needs
to be specified.
+ * @param varSession
+ * Var resolver session for resolving SVL variables.
+ * <br>Only one of <c>varResolver</c> and <c>varSession</c> needs
to be specified.
* @param content
* The content.
* <br>Can be any of the following:
@@ -62,11 +111,13 @@ public class ResolvingReaderResource extends
ReaderResource {
* <li><c>File</c>
* <li><c>CharSequence</c> - Converted to UTF-8 bytes.
* <li><c><jk>byte</jk>[]</c>.
+ * <li>A {@link Supplier} of anything on this list.
* </ul>
* </ul>
*/
- public ResolvingReaderResource(ContentType contentType, ContentEncoding
contentEncoding, VarResolverSession varSession, Object content) {
+ public ResolvingReaderResource(ContentType contentType, ContentEncoding
contentEncoding, VarResolver varResolver, VarResolverSession varSession, Object
content) {
super(contentType, contentEncoding, content);
+ this.varResolver = varResolver;
this.varSession = varSession;
}
@@ -78,22 +129,24 @@ public class ResolvingReaderResource extends
ReaderResource {
*/
@Override
public String asString() throws IOException {
- if (varSession == null)
+ VarResolverSession vr = getVarSession();
+ if (vr == null)
return super.asString();
StringWriter sw = new StringWriter();
String s = IOUtils.read(getRawContent());
- varSession.resolveTo(s, sw);
+ vr.resolveTo(s, sw);
return sw.toString();
}
@Override
public void writeTo(OutputStream os) throws IOException {
- if (varSession == null)
+ VarResolverSession vr = getVarSession();
+ if (vr == null)
super.writeTo(os);
else {
try (OutputStreamWriter osw = new
OutputStreamWriter(os, IOUtils.UTF8)) {
String s = IOUtils.read(getRawContent());
- varSession.resolveTo(s, osw);
+ vr.resolveTo(s, osw);
osw.flush();
}
}
@@ -103,6 +156,18 @@ public class ResolvingReaderResource extends
ReaderResource {
/**
* Sets the var resolver for resolving SVL variables.
*
+ * @param varResolver - The var resolver.
+ * @return This object (for method chaining).
+ */
+ @FluentSetter
+ public ResolvingReaderResource varResolver(VarResolver varResolver) {
+ this.varResolver = varResolver;
+ return this;
+ }
+
+ /**
+ * Sets the var resolver session for resolving SVL variables.
+ *
* @param varSession - The var resolver session.
* @return This object (for method chaining).
*/
@@ -112,45 +177,77 @@ public class ResolvingReaderResource extends
ReaderResource {
return this;
}
+ private VarResolverSession getVarSession() {
+ if (varSession != null)
+ return varSession;
+ if (varResolver != null)
+ return varResolver.createSession();
+ return null;
+ }
+
// <FluentSetters>
- @Override /* GENERATED - BasicHttpResource */
+ @Override /* GENERATED - BasicHttpEntity */
public ResolvingReaderResource cache() {
super.cache();
return this;
}
- @Override /* GENERATED - BasicHttpResource */
+ @Override /* GENERATED - BasicHttpEntity */
+ public ResolvingReaderResource cache(boolean value) {
+ super.cache(value);
+ return this;
+ }
+
+ @Override /* GENERATED - BasicHttpEntity */
public ResolvingReaderResource chunked() {
super.chunked();
return this;
}
- @Override /* GENERATED - BasicHttpResource */
+ @Override /* GENERATED - BasicHttpEntity */
+ public ResolvingReaderResource chunked(boolean value) {
+ super.chunked(value);
+ return this;
+ }
+
+ @Override /* GENERATED - BasicHttpEntity */
public ResolvingReaderResource content(Object value) {
super.content(value);
return this;
}
- @Override /* GENERATED - BasicHttpResource */
+ @Override /* GENERATED - BasicHttpEntity */
+ public ResolvingReaderResource content(Supplier<?> value) {
+ super.content(value);
+ return this;
+ }
+
+ @Override /* GENERATED - BasicHttpEntity */
public ResolvingReaderResource contentEncoding(String value) {
super.contentEncoding(value);
return this;
}
- @Override /* GENERATED - BasicHttpResource */
+ @Override /* GENERATED - BasicHttpEntity */
public ResolvingReaderResource contentEncoding(Header value) {
super.contentEncoding(value);
return this;
}
- @Override /* GENERATED - BasicHttpResource */
+ @Override /* GENERATED - BasicHttpEntity */
+ public ResolvingReaderResource contentLength(long value) {
+ super.contentLength(value);
+ return this;
+ }
+
+ @Override /* GENERATED - BasicHttpEntity */
public ResolvingReaderResource contentType(String value) {
super.contentType(value);
return this;
}
- @Override /* GENERATED - BasicHttpResource */
+ @Override /* GENERATED - BasicHttpEntity */
public ResolvingReaderResource contentType(Header value) {
super.contentType(value);
return this;
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/SerializedHeader.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/SerializedHeader.java
index d3409d7..387c278 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/SerializedHeader.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/SerializedHeader.java
@@ -131,6 +131,26 @@ public class SerializedHeader extends BasicStringHeader {
return this;
}
+ /**
+ * Don't serialize this header if the value is <jk>null</jk> or an
empty string.
+ *
+ * @return This object (for method chaining).
+ */
+ public SerializedHeader skipIfEmpty() {
+ return skipIfEmpty(true);
+ }
+
+ /**
+ * Don't serialize this header if the value is <jk>null</jk> or an
empty string.
+ *
+ * @param value The new value of this setting.
+ * @return This object (for method chaining).
+ */
+ public SerializedHeader skipIfEmpty(boolean value) {
+ this.skipIfEmpty = value;
+ return this;
+ }
+
@Override /* NameValuePair */
public String getValue() {
try {
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/SerializedHttpEntity.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/SerializedHttpEntity.java
index b0bdefb..76ce356 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/SerializedHttpEntity.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/SerializedHttpEntity.java
@@ -16,7 +16,6 @@ import static org.apache.juneau.internal.IOUtils.*;
import java.io.*;
-import org.apache.http.entity.*;
import org.apache.juneau.*;
import org.apache.juneau.httppart.*;
import org.apache.juneau.internal.*;
@@ -27,36 +26,72 @@ import org.apache.juneau.utils.*;
* HttpEntity for serializing POJOs as the body of HTTP requests.
*/
public class SerializedHttpEntity extends BasicHttpEntity {
- final Object output;
- final Serializer serializer;
- final HttpPartSchema schema;
- byte[] outputBytes;
+ private Serializer serializer;
+ private HttpPartSchema schema;
+ private byte[] cache;
+
+ /**
+ * Creator.
+ *
+ * @param content The POJO to serialize. Can also be a {@link Reader}
or {@link InputStream}.
+ * @return A new {@link SerializedHttpEntity} with uninitialized
serializer and schema.
+ */
+ public static SerializedHttpEntity of(Object content) {
+ return new SerializedHttpEntity(content, null, null, null);
+ }
/**
* Constructor.
*
- * @param input The POJO to serialize. Can also be a {@link Reader} or
{@link InputStream}.
+ * @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 schema The optional schema information about the serialized
part.
* @param contentType Override the content type defined on the
serializer.
*/
- public SerializedHttpEntity(Object input, Serializer serializer,
HttpPartSchema schema, String contentType) {
- this.output = input;
+ public SerializedHttpEntity(Object content, Serializer serializer,
HttpPartSchema schema, String contentType) {
+ content(content);
this.serializer = serializer;
this.schema = schema;
if (serializer != null && serializer.getResponseContentType()
!= null)
setContentType(new BasicHeader("Content-Type",
contentType != null ? contentType :
serializer.getResponseContentType().toString()));
}
+ /**
+ * Sets the serializer to use to serialize the content.
+ *
+ * <p>
+ * Value is ignored if the content is a stream or reader.
+ *
+ * @param value The serializer.
+ * @return This object (for method chaining).
+ */
+ @FluentSetter
+ public SerializedHttpEntity serializer(Serializer value) {
+ this.serializer = value;
+ return this;
+ }
+
+ /**
+ * Sets the schema to use to serialize the content.
+ *
+ * <p>
+ * Value is ignored if the serializer is not schema-aware.
+ *
+ * @param value The schema.
+ * @return This object (for method chaining).
+ */
+ @FluentSetter
+ public SerializedHttpEntity schema(HttpPartSchema value) {
+ this.schema = value;
+ return this;
+ }
+
@Override /* BasicHttpEntity */
public void writeTo(OutputStream os) throws IOException {
os = new NoCloseOutputStream(os);
- if (output instanceof InputStream) {
- IOPipe.create(output, os).run();
- } else if (output instanceof Reader) {
- try (OutputStreamWriter osw = new
OutputStreamWriter(os, UTF8)) {
- IOPipe.create(output, osw).run();
- }
+ Object content = getRawContent();
+ if (content instanceof InputStream || content instanceof Reader
|| content instanceof File) {
+ IOPipe.create(content, os).run();
} else {
try {
if (serializer == null) {
@@ -66,7 +101,7 @@ public class SerializedHttpEntity extends BasicHttpEntity {
SerializerSessionArgs sArgs =
SerializerSessionArgs.create().schema(schema);
SerializerSession session =
serializer.createSession(sArgs);
try (Closeable c =
session.isWriterSerializer() ? new OutputStreamWriter(os, UTF8) : os) {
- session.serialize(output, c);
+ session.serialize(content, c);
}
}
} catch (SerializeException e) {
@@ -77,19 +112,25 @@ public class SerializedHttpEntity extends BasicHttpEntity {
@Override /* BasicHttpEntity */
public boolean isRepeatable() {
- return true;
+ Object content = getRawContent();
+ return (! (content instanceof InputStream || content instanceof
Reader));
+ }
+
+ @Override
+ public long getContentLength() {
+ return -1;
}
@Override /* BasicHttpEntity */
public InputStream getContent() {
- if (outputBytes == null) {
+ if (cache == null) {
try (ByteArrayOutputStream baos = new
ByteArrayOutputStream()) {
writeTo(baos);
- outputBytes = baos.toByteArray();
+ cache = baos.toByteArray();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
- return new ByteArrayInputStream(outputBytes);
+ return new ByteArrayInputStream(cache);
}
}
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/SerializedNameValuePair.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/SerializedNameValuePair.java
index 4d366d2..bc3c9e7 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/SerializedNameValuePair.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/SerializedNameValuePair.java
@@ -141,6 +141,25 @@ public class SerializedNameValuePair extends
BasicNameValuePair implements Heade
return this;
}
+ /**
+ * Don't serialize this pair if the value is <jk>null</jk> or an empty
string.
+ *
+ * @return This object (for method chaining).
+ */
+ public SerializedNameValuePair skipIfEmpty() {
+ return skipIfEmpty(true);
+ }
+
+ /**
+ * Don't serialize this pair if the value is <jk>null</jk> or an empty
string.
+ *
+ * @param value The new value of this setting.
+ * @return This object (for method chaining).
+ */
+ public SerializedNameValuePair skipIfEmpty(boolean value) {
+ this.skipIfEmpty = value;
+ return this;
+ }
@Override /* Headerable */
public SerializedHeader asHeader() {
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/StreamResource.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/StreamResource.java
index 1dfad8f..4cff804 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/StreamResource.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/StreamResource.java
@@ -14,6 +14,7 @@ package org.apache.juneau.http;
import java.io.*;
import java.util.*;
+import java.util.function.*;
import org.apache.http.Header;
import org.apache.juneau.assertions.*;
@@ -41,7 +42,7 @@ public class StreamResource extends BasicHttpResource {
/**
* Creator.
*
- * @return A new empty {@link ReaderResource} object.
+ * @return A new empty {@link StreamResource} object.
*/
public static StreamResource create() {
return new StreamResource();
@@ -55,17 +56,41 @@ public class StreamResource extends BasicHttpResource {
* <br>Can be any of the following:
* <ul>
* <li><c>InputStream</c>
+ * <li><c>Reader</c> - Converted to UTF-8 bytes.
* <li><c>File</c>
+ * <li><c>CharSequence</c> - Converted to UTF-8 bytes.
* <li><c><jk>byte</jk>[]</c>.
+ * <li>A {@link Supplier} of anything on this list.
* </ul>
* </ul>
- * @return A new empty {@link ReaderResource} object.
+ * @return A new empty {@link StreamResource} object.
*/
public static StreamResource of(Object content) {
return new StreamResource().content(content);
}
/**
+ * Creator.
+ *
+ * @param content
+ * The content.
+ * <br>Can be any of the following:
+ * <ul>
+ * <li><c>InputStream</c>
+ * <li><c>Reader</c> - Converted to UTF-8 bytes.
+ * <li><c>File</c>
+ * <li><c>CharSequence</c> - Converted to UTF-8 bytes.
+ * <li><c><jk>byte</jk>[]</c>.
+ * <li>A {@link Supplier} of anything on this list.
+ * </ul>
+ * </ul>
+ * @return A new empty {@link StreamResource} object.
+ */
+ public static StreamResource of(Supplier<?> content) {
+ return new StreamResource().content(content);
+ }
+
+ /**
* Constructor.
*/
public StreamResource() {
@@ -90,6 +115,7 @@ public class StreamResource extends BasicHttpResource {
* <li><c>File</c>
* <li><c>CharSequence</c> - Converted to UTF-8 bytes.
* <li><c><jk>byte</jk>[]</c>.
+ * <li>A {@link Supplier} of anything on this list.
* </ul>
* </ul>
*/
@@ -119,43 +145,67 @@ public class StreamResource extends BasicHttpResource {
// <FluentSetters>
- @Override /* GENERATED - BasicHttpResource */
+ @Override /* GENERATED - BasicHttpEntity */
public StreamResource cache() {
super.cache();
return this;
}
- @Override /* GENERATED - BasicHttpResource */
+ @Override /* GENERATED - BasicHttpEntity */
+ public StreamResource cache(boolean value) {
+ super.cache(value);
+ return this;
+ }
+
+ @Override /* GENERATED - BasicHttpEntity */
public StreamResource chunked() {
super.chunked();
return this;
}
- @Override /* GENERATED - BasicHttpResource */
+ @Override /* GENERATED - BasicHttpEntity */
+ public StreamResource chunked(boolean value) {
+ super.chunked(value);
+ return this;
+ }
+
+ @Override /* GENERATED - BasicHttpEntity */
public StreamResource content(Object value) {
super.content(value);
return this;
}
- @Override /* GENERATED - BasicHttpResource */
+ @Override /* GENERATED - BasicHttpEntity */
+ public StreamResource content(Supplier<?> value) {
+ super.content(value);
+ return this;
+ }
+
+ @Override /* GENERATED - BasicHttpEntity */
public StreamResource contentEncoding(String value) {
super.contentEncoding(value);
return this;
}
- @Override /* GENERATED - BasicHttpResource */
+ @Override /* GENERATED - BasicHttpEntity */
public StreamResource contentEncoding(Header value) {
super.contentEncoding(value);
return this;
}
- @Override /* GENERATED - BasicHttpResource */
+ @Override /* GENERATED - BasicHttpEntity */
+ public StreamResource contentLength(long value) {
+ super.contentLength(value);
+ return this;
+ }
+
+ @Override /* GENERATED - BasicHttpEntity */
public StreamResource contentType(String value) {
super.contentType(value);
return this;
}
- @Override /* GENERATED - BasicHttpResource */
+ @Override /* GENERATED - BasicHttpEntity */
public StreamResource contentType(Header value) {
super.contentType(value);
return this;
diff --git
a/juneau-releng/juneau-all/src/java/main/ConfigurablePropertyCodeGenerator.java
b/juneau-releng/juneau-all/src/java/main/ConfigurablePropertyCodeGenerator.java
index 7502f62..4e33cf0 100644
---
a/juneau-releng/juneau-all/src/java/main/ConfigurablePropertyCodeGenerator.java
+++
b/juneau-releng/juneau-all/src/java/main/ConfigurablePropertyCodeGenerator.java
@@ -186,6 +186,7 @@ public class ConfigurablePropertyCodeGenerator {
CollectionAssertion.class,
ListAssertion.class,
+ BasicHttpEntity.class,
BasicHttpResource.class,
StreamResource.class,
ReaderResource.class,
diff --git
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/http/BasicHttpResource_Test.java
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/http/BasicHttpResource_Test.java
index 9d0bf5a..d02d777 100644
---
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/http/BasicHttpResource_Test.java
+++
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/http/BasicHttpResource_Test.java
@@ -87,6 +87,12 @@ public class BasicHttpResource_Test {
assertTrue(x.isRepeatable());
x.writeTo(new ByteArrayOutputStream());
+ x = of(f).cache();
+ assertStream(x.getContent()).string().isEmpty();
+ assertStream(x.getContent()).string().isEmpty();
+ assertTrue(x.isRepeatable());
+ x.writeTo(new ByteArrayOutputStream());
+
assertLong(of("foo").getContentLength()).is(3l);
assertLong(of("foo".getBytes()).getContentLength()).is(3l);
assertLong(of(f).getContentLength()).is(0l);
@@ -99,5 +105,15 @@ public class BasicHttpResource_Test {
assertObject(x.getFirstHeader("Bar")).doesNotExist();
assertObject(x.getLastHeader("Bar")).doesNotExist();
assertObject(x.getHeaders()).json().is("['Foo: bar','Foo:
baz']");
+
+ BasicHttpResource x2 = new BasicHttpResource() {
+ @Override
+ protected byte[] readBytes(Object o) throws IOException
{
+ throw new IOException("bad");
+ }
+ };
+ x2.cache().content(new StringReader("foo"));
+ assertLong(x2.getContentLength()).is(-1l);
+ assertThrown(()->x2.writeTo(new
ByteArrayOutputStream())).contains("bad");
}
}
diff --git
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RestClient_FormData_Test.java
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RestClient_FormData_Test.java
index 31aae74..bf67232 100644
---
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RestClient_FormData_Test.java
+++
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RestClient_FormData_Test.java
@@ -27,10 +27,10 @@ import org.apache.juneau.httppart.*;
import org.apache.juneau.marshall.*;
import org.apache.juneau.rest.*;
import org.apache.juneau.rest.annotation.*;
-import org.apache.juneau.rest.client2.RestClient_Test.*;
import org.apache.juneau.rest.mock2.*;
import org.apache.juneau.serializer.*;
import org.apache.juneau.testutils.*;
+import org.apache.juneau.testutils.pojos.ABean;
import org.apache.juneau.uon.*;
import org.junit.*;
@@ -89,7 +89,7 @@ public class RestClient_FormData_Test {
client().build().post("/formData").formDatas(AList.of(pair("foo","bar"),pair("foo","baz"))).run().assertBody().is("foo=bar&foo=baz");
client().build().post("/formData").formDatas((Object)new
NameValuePair[]{pair("foo","bar")}).run().assertBody().is("foo=bar");
-
client().build().post("/formData").formDatas(ABean.get()).run().assertBody().is("f=1");
+
client().build().post("/formData").formDatas(ABean.get()).run().assertBody().is("a=1&b=foo");
client().formDatas(pair("foo","bar"),null).build().post("/formData").run().assertBody().is("foo=bar");
client().build().post("/formData").formDatas(pair("foo","bar"),null).run().assertBody().is("foo=bar");
@@ -102,6 +102,9 @@ public class RestClient_FormData_Test {
client().build().post("/formData").formDatas(pair(null,null)).run().assertBody().is("");
client().formDatas(SerializedHeader.of("foo","bar")).build().post("/formData").run().assertBody().is("foo=bar");
+
client().formDatas(SerializedNameValuePair.of("foo","bar").schema(null)).build().post("/formData").run().assertBody().is("foo=bar");
+
client().formDatas(SerializedNameValuePair.of("foo",null).schema(null)).build().post("/formData").run().assertBody().is("");
+
client().formDatas(SerializedNameValuePair.of("foo",null).skipIfEmpty().schema(HttpPartSchema.create()._default("bar").build())).build().post("/formData").run().assertBody().is("foo=bar");
assertThrown(()->client().build().post("/formData").formDatas("bad")).is("Invalid
type passed to formDatas(): java.lang.String");
assertThrown(()->client().formDatas(pair("foo","bar"),"baz")).is("Invalid type
passed to formData(): java.lang.String");
@@ -197,6 +200,23 @@ public class RestClient_FormData_Test {
x2.post("/formData").formData("foo",s,T_ARRAY_PIPES).run().assertBody().urlDecode().is("foo=bar|baz");
}
+ public static class A12 implements HttpPartSerializer {
+ @Override
+ public HttpPartSerializerSession
createPartSession(SerializerSessionArgs args) {
+ return new HttpPartSerializerSession() {
+ @Override
+ public String serialize(HttpPartType type,
HttpPartSchema schema, Object value) throws SerializeException,
SchemaValidationException {
+ throw new SerializeException("bad");
+ }
+ };
+ }
+ }
+
+ @Test
+ public void a12_formData_BadSerialization() throws Exception {
+
assertThrown(()->client().formData(SerializedNameValuePair.of("Foo","bar").serializer(new
A12())).build().get()).contains("bad");
+ }
+
//------------------------------------------------------------------------------------------------------------------
// Helper methods.
//------------------------------------------------------------------------------------------------------------------
diff --git
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RestClient_Headers_Test.java
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RestClient_Headers_Test.java
index c3d4131..20d5921 100644
---
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RestClient_Headers_Test.java
+++
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RestClient_Headers_Test.java
@@ -120,6 +120,8 @@ public class RestClient_Headers_Test {
checkClient("f").build().get("/headers").headers((Object)null).debug().run().assertBody().is("null");
assertThrown(()->client().headers("Foo")).contains("Invalid
type");
assertThrown(()->client().build().get("").headers("Foo")).contains("Invalid
type");
+
+
checkFooClient().headers(SerializedHeader.of("Foo",null).skipIfEmpty().schema(HttpPartSchema.create()._default("bar").build())).build().get("/headers").run().assertBody().is("['bar']");
}
@Test
@@ -185,6 +187,23 @@ public class RestClient_Headers_Test {
checkFooClient().header("Foo",s,T_ARRAY_PIPES,UonSerializer.DEFAULT).build().get("/headers").run().assertBody().is("['@(foo,bar)']");
}
+ public static class A12 implements HttpPartSerializer {
+ @Override
+ public HttpPartSerializerSession
createPartSession(SerializerSessionArgs args) {
+ return new HttpPartSerializerSession() {
+ @Override
+ public String serialize(HttpPartType type,
HttpPartSchema schema, Object value) throws SerializeException,
SchemaValidationException {
+ throw new SerializeException("bad");
+ }
+ };
+ }
+ }
+
+ @Test
+ public void a12_headers_BadSerialization() throws Exception {
+
assertThrown(()->checkFooClient().header(SerializedHeader.of("Foo","bar").serializer(new
A12())).build().get()).contains("bad");
+ }
+
//------------------------------------------------------------------------------------------------------------------
// Other tests
//------------------------------------------------------------------------------------------------------------------