This is an automated email from the ASF dual-hosted git repository.
jamesbognar pushed a commit to branch jbFixRestNpe
in repository https://gitbox.apache.org/repos/asf/juneau.git
The following commit(s) were added to refs/heads/jbFixRestNpe by this push:
new 5eae23d07 RestClient improvements
5eae23d07 is described below
commit 5eae23d077fa42f7742d0d07c86398041c53e972
Author: JamesBognar <[email protected]>
AuthorDate: Sun Aug 14 11:51:11 2022 -0400
RestClient improvements
---
.../src/main/java/org/apache/juneau/Context.java | 11 +++
.../org/apache/juneau/rest/client/RestClient.java | 81 ++++++++++++++++------
.../org/apache/juneau/rest/client/RestRequest.java | 50 ++++++++++++-
.../apache/juneau/rest/client/RestResponse.java | 2 +-
4 files changed, 121 insertions(+), 23 deletions(-)
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java
index 37df258f8..d47cbdace 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java
@@ -841,6 +841,7 @@ public abstract class Context implements AnnotationProvider
{
* @param builder The builder for this class.
*/
protected Context(Builder builder) {
+ init(builder);
debug = builder.debug;
annotations =
optional(builder.annotations).orElseGet(()->emptyList());
@@ -879,6 +880,16 @@ public abstract class Context implements
AnnotationProvider {
constructorAnnotationCache = new
TwoKeyConcurrentCache<>(disabled, (k1,k2) -> annotationMap.appendAll(k1, k2,
k1.getAnnotationsByType(k2)));
}
+ /**
+ * Perform optional initialization on builder before it is used.
+ *
+ * <p>
+ * Default behavior is a no-op.
+ *
+ * @param builder The builder to initialize.
+ */
+ protected void init(Builder builder) {}
+
/**
* Creates a builder from this context object.
*
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 b4c1a3493..1740c8374 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
@@ -997,14 +997,37 @@ import org.apache.juneau.xml.*;
* <jk>public class</jk> MyRestClient <jk>extends</jk> RestClient {
*
* <jc>// Must provide this constructor!</jc>
- * <jk>public</jk> MyRestClient(ContextProperties
<jv>properties</jv>) {
- * <jk>super</jk>(<jv>properties</jv>);
+ * <jk>public</jk> MyRestClient(RestClient.Builder
<jv>builder</jv>) {
+ * <jk>super</jk>(<jv>builder</jv>);
* }
*
+ * <jd>/** Optionally override to customize builder settings
before initialization. </jd>
* <ja>@Override</ja>
- * <jk>public</jk> HttpResponse run(HttpHost <jv>target</jv>,
HttpRequest <jv>request</jv>, HttpContext <jv>context</jv>) <jk>throws</jk>
IOException {
- * <jc>// Perform special handling of requests.</jc>
- * }
+ * <jk>protected void</jk> init(RestClient.Builder) {...}
+ *
+ * <jd>/** Optionally override to provide post-initialization
(e.g. setting up SAML handshakes, etc...). </jd>
+ * <ja>@Override</ja>
+ * <jk>protected void</jk> init() {...}
+ *
+ * <jd>/** Optionally override to customize requests when they're
created (e.g. add headers to each request). </jd>
+ * <ja>@Override</ja>
+ * <jk>protected void</jk> request(RestOperation) {...}
+ *
+ * <jd>/** Optionally override to implement your own call
handling. </jd>
+ * <ja>@Override</ja>
+ * <jk>protected</jk> HttpResponse run(HttpHost, HttpRequest,
HttpContext) {...}
+ *
+ * <jd>/** Optionally override to customize requests before
they're executed. </jd>
+ * <ja>@Override</ja>
+ * <jk>protected void</jk> onCallInit(RestRequest) {...}
+ *
+ * <jd>/** Optionally override to customize responses as soon as a
connection is made. </jd>
+ * <ja>@Override</ja>
+ * <jk>protected void</jk> onCallConnect(RestRequest,
RestResponse) {...}
+ *
+ * <jd>/** Optionally override to perform any call cleanup. </jd>
+ * <ja>@Override</ja>
+ * <jk>protected void</jk> onCallClose(RestRequest, RestResponse)
{...}
* }
*
* <jc>// Instantiate your client.</jc>
@@ -1024,7 +1047,7 @@ import org.apache.juneau.xml.*;
* <li class='extlink'>{@source}
* </ul>
*/
-public class RestClient extends BeanContextable implements HttpClient,
Closeable, RestCallHandler, RestCallInterceptor {
+public class RestClient extends BeanContextable implements HttpClient,
Closeable {
//-------------------------------------------------------------------------------------------------------------------
// Static
@@ -3627,8 +3650,8 @@ public class RestClient extends BeanContextable
implements HttpClient, Closeable
* </p>
*
* <ul class='notes'>
- * <li class='note'>The {@link
RestClient#onInit(RestRequest)}, {@link
RestClient#onConnect(RestRequest,RestResponse)}, and
- * {@link RestClient#onClose(RestRequest,RestResponse)} methods
can also be overridden to produce the same results.
+ * <li class='note'>The {@link
RestClient#onCallInit(RestRequest)}, {@link
RestClient#onCallConnect(RestRequest,RestResponse)}, and
+ * {@link RestClient#onCallClose(RestRequest,RestResponse)}
methods can also be overridden to produce the same results.
* </ul>
*
* @param values
@@ -3691,8 +3714,8 @@ public class RestClient extends BeanContextable
implements HttpClient, Closeable
* </p>
*
* <ul class='notes'>
- * <li class='note'>The {@link
RestClient#onInit(RestRequest)}, {@link
RestClient#onConnect(RestRequest,RestResponse)}, and
- * {@link RestClient#onClose(RestRequest,RestResponse)} methods
can also be overridden to produce the same results.
+ * <li class='note'>The {@link
RestClient#onCallInit(RestRequest)}, {@link
RestClient#onCallConnect(RestRequest,RestResponse)}, and
+ * {@link RestClient#onCallClose(RestRequest,RestResponse)}
methods can also be overridden to produce the same results.
* </ul>
*
* @param value
@@ -6373,6 +6396,8 @@ public class RestClient extends BeanContextable
implements HttpClient, Closeable
partParser = builder.partParser().create();
urlEncodingSerializer = builder.urlEncodingSerializer().build();
creationStack = isDebug() ?
Thread.currentThread().getStackTrace() : null;
+
+ init();
}
@Override /* Context */
@@ -6380,6 +6405,22 @@ public class RestClient extends BeanContextable
implements HttpClient, Closeable
throw new NoSuchMethodError("Not implemented.");
}
+ /**
+ * Perform optional initialization on builder before it is used.
+ *
+ * <p>
+ * Default behavior is a no-op.
+ *
+ * @param builder The builder to initialize.
+ */
+ protected void init(RestClient.Builder builder) {}
+
+ /**
+ * Gets called add the end of the constructor call to perform any
post-initialization.
+ */
+ protected void init() {
+ }
+
/**
* Calls {@link CloseableHttpClient#close()} on the underlying {@link
CloseableHttpClient}.
*
@@ -6440,8 +6481,7 @@ public class RestClient extends BeanContextable
implements HttpClient, Closeable
* @throws IOException In case of a problem or the connection was
aborted.
* @throws ClientProtocolException In case of an http protocol error.
*/
- @Override /* RestCallHandler */
- public HttpResponse run(HttpHost target, HttpRequest request,
HttpContext context) throws ClientProtocolException, IOException {
+ protected HttpResponse run(HttpHost target, HttpRequest request,
HttpContext context) throws ClientProtocolException, IOException {
return callHandler.run(target, request, context);
}
@@ -7123,13 +7163,17 @@ public class RestClient extends BeanContextable
implements HttpClient, Closeable
/**
* Perform an arbitrary request against the specified URI.
*
+ * <p>
+ * All requests feed through this method so it can be used to intercept
request creations and make modifications
+ * (such as add headers).
+ *
* @param op The operation that identifies the HTTP method, URL, and
optional payload.
* @return
* A {@link RestRequest} object that can be further tailored
before executing the request and getting the response
* as a parsed object.
* @throws RestCallException If any authentication errors occurred.
*/
- public RestRequest request(RestOperation op) throws RestCallException {
+ protected RestRequest request(RestOperation op) throws
RestCallException {
if (isClosed) {
Exception e2 = null;
if (closedStack != null) {
@@ -7142,7 +7186,7 @@ public class RestClient extends BeanContextable
implements HttpClient, Closeable
RestRequest req = createRequest(toURI(op.getUri(), rootUri),
op.getMethod(), op.hasContent());
- onInit(req);
+ onCallInit(req);
req.content(op.getContent());
@@ -7780,8 +7824,7 @@ public class RestClient extends BeanContextable
implements HttpClient, Closeable
* @param req The HTTP request.
* @throws RestCallException If any of the interceptors threw an
exception.
*/
- @Override
- public void onInit(RestRequest req) throws RestCallException {
+ protected void onCallInit(RestRequest req) throws RestCallException {
try {
for (RestCallInterceptor rci : interceptors)
rci.onInit(req);
@@ -7806,8 +7849,7 @@ public class RestClient extends BeanContextable
implements HttpClient, Closeable
* @param res The HTTP response.
* @throws RestCallException If any of the interceptors threw an
exception.
*/
- @Override
- public void onConnect(RestRequest req, RestResponse res) throws
RestCallException {
+ protected void onCallConnect(RestRequest req, RestResponse res) throws
RestCallException {
try {
for (RestCallInterceptor rci : interceptors)
rci.onConnect(req, res);
@@ -7832,8 +7874,7 @@ public class RestClient extends BeanContextable
implements HttpClient, Closeable
* @param res The HTTP response.
* @throws RestCallException If any of the interceptors threw an
exception.
*/
- @Override
- public void onClose(RestRequest req, RestResponse res) throws
RestCallException {
+ protected void onCallClose(RestRequest req, RestResponse res) throws
RestCallException {
try {
for (RestCallInterceptor rci : interceptors)
rci.onClose(req, res);
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 7aa2328e5..3a8853baa 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
@@ -80,7 +80,7 @@ import org.apache.juneau.xml.*;
* </ul>
*/
@FluentSetters
-public class RestRequest extends BeanSession implements HttpUriRequest,
Configurable {
+public class RestRequest extends BeanSession implements HttpUriRequest,
Configurable, AutoCloseable {
private static final ContentType TEXT_PLAIN = ContentType.TEXT_PLAIN;
@@ -2020,7 +2020,7 @@ public class RestRequest extends BeanSession implements
HttpUriRequest, Configur
for (RestCallInterceptor rci : interceptors)
rci.onConnect(this, response);
- client.onConnect(this, response);
+ client.onCallConnect(this, response);
String method = getMethod();
int sc = response.getStatusCode();
@@ -2162,6 +2162,47 @@ public class RestRequest extends BeanSession implements
HttpUriRequest, Configur
);
}
+ /**
+ * A shortcut for calling <c>run().getContent().asString()</c>.
+ *
+ * @return The response content as a simple string.
+ * @throws RestCallException If an exception or non-200 response code
occurred during the connection attempt.
+ */
+ public String getResponseAsString() throws RestCallException {
+ return run().getContent().asString();
+ }
+
+ /**
+ * A shortcut for calling <c>run().getContent().as(<js>type</js>)</c>.
+ *
+ * @param type The object type to create.
+ * @param <T> The object type to create.
+ * @see ResponseContent#as(Class)
+ * @return The response content as a simple string.
+ * @throws RestCallException If an exception or non-200 response code
occurred during the connection attempt.
+ */
+ public <T> T getResponse(Class<T> type) throws RestCallException {
+ return run().getContent().as(type);
+ }
+
+ /**
+ * A shortcut for calling
<c>run().getContent().as(<js>type</js>,<js>args</js>)</c>.
+ *
+ * @param type
+ * The object type to create.
+ * <br>Can be any of the following: {@link ClassMeta}, {@link
Class}, {@link ParameterizedType}, {@link GenericArrayType}
+ * @param args
+ * The type arguments of the class if it's a collection or map.
+ * <br>Can be any of the following: {@link ClassMeta}, {@link
Class}, {@link ParameterizedType}, {@link GenericArrayType}
+ * <br>Ignored if the main type is not a map or collection.
+ * @see ResponseContent#as(Type,Type...)
+ * @return The response content as a simple string.
+ * @throws RestCallException If an exception or non-200 response code
occurred during the connection attempt.
+ */
+ public <T> T getResponse(Type type, Type...args) throws
RestCallException {
+ return run().getContent().as(type, args);
+ }
+
/**
* Returns <jk>true</jk> if this request has a body.
*
@@ -2712,6 +2753,11 @@ public class RestRequest extends BeanSession implements
HttpUriRequest, Configur
// Other methods
//-----------------------------------------------------------------------------------------------------------------
+ @Override
+ public void close() throws Exception {
+ complete();
+ }
+
@Override /* ContextSession */
protected JsonMap properties() {
return filteredMap()
diff --git
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestResponse.java
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestResponse.java
index 6ed543d01..ab81d57ad 100644
---
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestResponse.java
+++
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestResponse.java
@@ -884,7 +884,7 @@ public class RestResponse implements HttpResponse {
throw new RestCallException(this, e,
"Interceptor throw exception on close");
}
}
- client.onClose(request, this);
+ client.onCallClose(request, this);
}
//------------------------------------------------------------------------------------------------------------------