src/java.net.http/share/classes/java/net/http/HttpResponse.java
branchhttp-client-branch
changeset 56097 15dc43936d39
parent 56092 fd85b2bf2b0d
child 56099 41ba54ac9403
--- a/src/java.net.http/share/classes/java/net/http/HttpResponse.java	Wed Feb 07 22:49:25 2018 +0000
+++ b/src/java.net.http/share/classes/java/net/http/HttpResponse.java	Thu Feb 08 20:58:35 2018 +0000
@@ -57,37 +57,22 @@
 import static jdk.internal.net.http.common.Utils.charsetFrom;
 
 /**
- * Represents a response to a {@link HttpRequest}.
- *
- * <p> A {@code HttpResponse} is available when the response status code and
- * headers have been received, and typically after the response body has also
- * been received. This depends on the response body handler provided when
- * sending the request. In all cases, the response body handler is invoked
- * before the body is read. This gives applications an opportunity to decide
- * how to handle the body.
- *
- * <p> Methods are provided in this class for accessing the response headers,
- * and response body.
- *
- * <p><b>Response handlers and subscribers</b>
+ * An HTTP response.
  *
- * <p> Response bodies are handled at two levels. Application code supplies a
- * response handler ({@link BodyHandler}) which may examine the response status
- * code and headers, and which then returns a {@link BodySubscriber} to actually
- * read (or discard) the body and convert it into some useful Java object type.
- * The handler can return one of the pre-defined subscriber types, or a custom
- * subscriber, or if the body is to be discarded it can call {@link
- * BodySubscriber#discard() discard} and return a subscriber which
- * discards the response body. Static implementations of both handlers and
- * subscribers are provided in {@linkplain BodyHandler BodyHandler} and
- * {@linkplain BodySubscriber BodySubscriber} respectively. In all cases, the
- * handler functions provided are convenience implementations which ignore the
- * supplied status code and headers and return the relevant pre-defined {@code
- * BodySubscriber}.
+ * <p> An {@code HttpResponse} is not created directly, but rather returned as
+ * a result of sending an {@linkplain HttpRequest}. An {@code HttpResponse} is
+ * made available when the response status code and headers have been received,
+ * and typically after the response body has also been completely received.
+ * Whether or not the {@code HttpResponse} is made available before the response
+ * body has been completely received depends on the {@linkplain BodyHandler
+ * BodyHandler} provided when sending the {@code HttpRequest}.
  *
- * <p> See {@link BodyHandler} for example usage.
+ * <p> This class provides methods for accessing the response status code,
+ * headers, the response body, and the {@code HttpRequest} corresponding
+ * to this response.
+ **
+ * @param <T> the response body type
  *
- * @param <T> the response body type
  * @since 11
  */
 public abstract class HttpResponse<T> {
@@ -178,76 +163,77 @@
     /**
      * A handler for response bodies.
      *
-     * <p> This is a function that takes two parameters: the response status code,
-     * and the response headers, and which returns a {@linkplain BodySubscriber}.
-     * The function is always called just before the response body is read. Its
-     * implementation may examine the status code or headers and must decide,
-     * whether to accept the response body or discard it, and if accepting it,
-     * exactly how to handle it.
+     * <p> The {@code BodyHandler} interface allows inspection of the response
+     * code and headers, before the actual response body is received, and is
+     * responsible for creating the response {@linkplain BodySubscriber
+     * BodySubscriber}. The {@code BodySubscriber} consumes the actual response
+     * body bytes and converts them into a higher-level Java type.
      *
-     * <p> Some pre-defined implementations which do not utilize the status code
-     * or headers (meaning the body is always accepted) are defined:
+     * <p> A {@code BodyHandler} is a function that takes two parameters: the
+     * response status code and the response headers; and which returns a
+     * {@code BodySubscriber}. The {@code BodyHandler} is invoked when the
+     * response status code and headers are available, but before the response
+     * body bytes are received.
+     *
+     * <p> A number of convenience static factory methods are provided that
+     * return pre-defined implementations that do not examine the status code
+     * (meaning the body is always accepted):
      * <ul><li>{@link #asByteArray() }</li>
      * <li>{@link #asByteArrayConsumer(java.util.function.Consumer)
      * asByteArrayConsumer(Consumer)}</li>
      * <li>{@link #asString(java.nio.charset.Charset) asString(Charset)}</li>
-     * <li>{@link #asFile(Path, OpenOption...)
-     * asFile(Path,OpenOption...)}</li>
+     * <li>{@link #asFile(Path, OpenOption...) asFile(Path,OpenOption...)}</li>
      * <li>{@link #asFileDownload(java.nio.file.Path,OpenOption...)
      * asFileDownload(Path,OpenOption...)}</li>
      * <li>{@link #asInputStream() asInputStream()}</li>
      * <li>{@link #discard() }</li>
      * <li>{@link #replace(Object) }</li>
-     * <li>{@link #buffering(BodyHandler, int)
-     * buffering(BodyHandler,int)}</li>
+     * <li>{@link #buffering(BodyHandler, int) buffering(BodyHandler,int)}</li>
      * </ul>
      *
-     * <p> These implementations return the equivalent {@link BodySubscriber}.
-     * Alternatively, the handler can be used to examine the status code
-     * or headers and return different body subscribers as appropriate.
+     * <p> These implementations return an equivalently named {@code
+     * BodySubscriber}. Alternatively, a custom handler can be used to examine
+     * the status code or headers, and return different body subscribers as
+     * appropriate.
      *
-     * <p><b>Examples of handler usage</b>
+     * <p><b>Examples:</b>
      *
-     * <p> The first example uses one of the predefined handler functions which
-     * ignores the response headers and status, and always process the response
-     * body in the same way.
-     * <pre>
-     * {@code
-     *      HttpResponse<Path> resp = HttpRequest
-     *              .create(URI.create("http://www.foo.com"))
-     *              .GET()
-     *              .response(BodyHandler.asFile(Paths.get("/tmp/f")));
-     * }
-     * </pre>
-     * Note, that even though these pre-defined handlers ignore the status code
-     * and headers, this information is still accessible from the
-     * {@code HttpResponse} when it is returned.
+     * <p> The first example uses one of the predefined handler functions that
+     * always process the response body in the same way.
+     * <pre>{@code   HttpRequest request = HttpRequest.newBuilder()
+     *        .uri(URI.create("http://www.foo.com/"))
+     *        .build();
+     *  client.sendAsync(request, BodyHandler.asFile(Paths.get("/tmp/f")))
+     *        .thenApply(HttpResponse::body)
+     *        .thenAccept(System.out::println) }</pre>
+     * Note, that even though these pre-defined handlers do not examine the
+     * response code, the response code and headers are always retrievable from
+     * the {@linkplain HttpResponse}, when it is returned.
      *
      * <p> In the second example, the function returns a different subscriber
      * depending on the status code.
-     * <pre>
-     * {@code
-     *      HttpResponse<Path> resp1 = HttpRequest
-     *              .create(URI.create("http://www.foo.com"))
-     *              .GET()
-     *              .response(
-     *                  (status, headers) -> status == 200
+     * <pre>{@code   HttpRequest request = HttpRequest.newBuilder()
+     *        .uri(URI.create("http://www.foo.com/"))
+     *        .build();
+     *  BodyHandler bodyHandler = (status, headers) -> status == 200
      *                      ? BodySubscriber.asFile(Paths.get("/tmp/f"))
      *                      : BodySubscriber.replace(Paths.get("/NULL")));
-     * }
-     * </pre>
+     *  client.sendAsync(request, bodyHandler))
+     *        .thenApply(HttpResponse::body)
+     *        .thenAccept(System.out::println) }</pre>
      *
      * @param <T> the response body type
      */
     @FunctionalInterface
     public interface BodyHandler<T> {
         /**
-         * Returns a {@link BodySubscriber BodySubscriber} considering the given
-         * response status code and headers. This method is always called before
-         * the body is read and its implementation can decide to keep the body
-         * and store it somewhere, or else discard it by returning the {@code
-         * BodySubscriber} returned from {@link BodySubscriber#discard()
-         * discard}.
+         * Returns a {@linkplain BodySubscriber BodySubscriber} considering the
+         * given response status code and headers. This method is invoked before
+         * the actual response body bytes are read and its implementation must
+         * return a {@code BodySubscriber} to consume the response body bytes.
+         *
+         * <p> The response body can be discarded using one of {@linkplain
+         * #discard() discard} or {@linkplain #replace(Object) replace}.
          *
          * @param statusCode the HTTP status code received
          * @param responseHeaders the response headers received
@@ -272,12 +258,10 @@
          * BodySubscriber} and {@code Flow.Subscriber}.
          *
          * <p> For example:
-         * <pre> {@code
-         *  TextSubscriber subscriber = new TextSubscriber();
+         * <pre> {@code  TextSubscriber subscriber = new TextSubscriber();
          *  HttpResponse<Void> response = client.sendAsync(request,
          *      BodyHandler.fromSubscriber(subscriber)).join();
-         *  System.out.println(response.statusCode());
-         * }</pre>
+         *  System.out.println(response.statusCode()); }</pre>
          *
          * @param subscriber the subscriber
          * @return a response body handler
@@ -304,12 +288,10 @@
          * BodySubscriber} and {@code Flow.Subscriber}.
          *
          * <p> For example:
-         * <pre> {@code
-         * TextSubscriber subscriber = ...;  // accumulates bytes and transforms them into a String
-         * HttpResponse<String> response = client.sendAsync(request,
-         *     BodyHandler.fromSubscriber(subscriber, TextSubscriber::getTextResult)).join();
-         * String text = response.body();
-         * }</pre>
+         * <pre> {@code  TextSubscriber subscriber = ...;  // accumulates bytes and transforms them into a String
+         *  HttpResponse<String> response = client.sendAsync(request,
+         *      BodyHandler.fromSubscriber(subscriber, TextSubscriber::getTextResult)).join();
+         *  String text = response.body(); }</pre>
          *
          * @param <S> the type of the Subscriber
          * @param <T> the type of the response body
@@ -345,12 +327,10 @@
          * BodySubscriber} and {@code Flow.Subscriber}.
          *
          * <p> For example:
-         * <pre> {@code
-         *  TextSubscriber subscriber = new TextSubscriber();
+         * <pre> {@code  TextSubscriber subscriber = new TextSubscriber();
          *  HttpResponse<Void> response = client.sendAsync(request,
          *      BodyHandler.fromLineSubscriber(subscriber, "\n")).join();
-         *  System.out.println(response.statusCode());
-         * }</pre>
+         *  System.out.println(response.statusCode()); }</pre>
          *
          * @param subscriber the subscriber
          * @return a response body handler
@@ -381,12 +361,10 @@
          * BodySubscriber} and {@code Flow.Subscriber}.
          *
          * <p> For example:
-         * <pre> {@code
-         * TextSubscriber subscriber = ...;  // accumulates bytes and transforms them into a String
-         * HttpResponse<String> response = client.sendAsync(request,
-         *     BodyHandler.fromSubscriber(subscriber, TextSubscriber::getTextResult, "\n")).join();
-         * String text = response.body();
-         * }</pre>
+         * <pre> {@code  TextSubscriber subscriber = ...;  // accumulates bytes and transforms them into a String
+         *  HttpResponse<String> response = client.sendAsync(request,
+         *      BodyHandler.fromSubscriber(subscriber, TextSubscriber::getTextResult, "\n")).join();
+         *  String text = response.body();  }</pre>
          *
          * @param <S> the type of the Subscriber
          * @param <T> the type of the response body
@@ -749,7 +727,8 @@
     }
 
     /**
-     * A subscriber for response bodies.
+     * A {@code BodySubscriber} consumes response body bytes and converts them
+     * into a higher-level Java type.
      *
      * <p> The object acts as a {@link Flow.Subscriber}&lt;{@link List}&lt;{@link
      * ByteBuffer}&gt;&gt; to the HTTP client implementation, which publishes
@@ -758,27 +737,27 @@
      * is a strictly ordered representation of the response body. Both the Lists
      * and the ByteBuffers, once passed to the subscriber, are no longer used by
      * the HTTP client. The subscriber converts the incoming buffers of data to
-     * some user-defined object type {@code T}.
-     *
-     * <p> The {@link #getBody()} method returns a {@link CompletionStage}{@code
-     * <T>} that provides the response body object. The {@code CompletionStage}
-     * must be obtainable at any time. When it completes depends on the nature
-     * of type {@code T}. In many cases, when {@code T} represents the entire
-     * body after being read then it completes after the body has been read. If
-     * {@code T} is a streaming type such as {@link java.io.InputStream} then it
-     * completes before the body has been read, because the calling code uses it
-     * to consume the data.
+     * some higher-level Java type {@code T}.
      *
-     * @apiNote To ensure that all resources associated with the
-     * corresponding exchange are properly released, an implementation
-     * of {@code BodySubscriber} must ensure to {@linkplain
-     * Flow.Subscription#request request} more data until {@link
-     * #onComplete() onComplete} or {@link #onError(Throwable) onError}
-     * are signalled, or {@linkplain Flow.Subscription#request cancel} its
-     * {@linkplain #onSubscribe(Flow.Subscription) subscription}
-     * if unable or unwilling to do so.
-     * Calling {@code cancel} before exhausting the data may cause
-     * the underlying HTTP connection to be closed and prevent it
+     * <p> The {@link #getBody()} method returns a
+     * {@link CompletionStage}&lt;{@code T}&gt; that provides the response body
+     * object. The {@code CompletionStage} must be obtainable at any time. When
+     * it completes depends on the nature of type {@code T}. In many cases,
+     * when {@code T} represents the entire body after being consumed then
+     * the {@code CompletionStage} completes after the body has been consumed.
+     * If  {@code T} is a streaming type, such as {@link java.io.InputStream
+     * InputStream}, then it completes before the body has been read, because
+     * the calling code uses the {@code InputStream} to consume the data.
+     *
+     * @apiNote To ensure that all resources associated with the corresponding
+     * HTTP exchange are properly released, an implementation of {@code
+     * BodySubscriber} should ensure to {@linkplain Flow.Subscription#request
+     * request} more data until one of {@linkplain #onComplete() onComplete} or
+     * {@link #onError(Throwable) onError} are signalled, or {@linkplain
+     * Flow.Subscription#request cancel} its {@linkplain
+     * #onSubscribe(Flow.Subscription) subscription} if unable or unwilling to
+     * do so. Calling {@code cancel} before exhausting the response body data
+     * may cause the underlying HTTP connection to be closed and prevent it
      * from being reused for subsequent operations.
      *
      * @param <T> the response body type
@@ -790,7 +769,7 @@
          * Returns a {@code CompletionStage} which when completed will return
          * the response body object. This method can be called at any time
          * relative to the other {@link Flow.Subscriber} methods and is invoked
-         * using the client's {@link Executor}.
+         * using the client's {@link HttpClient#executor() executor}.
          *
          * @return a CompletionStage for the response body
          */
@@ -1123,46 +1102,43 @@
          }
 
         /**
-         * Returns a {@code BodySubscriber} whose response body is mapped
-         * using the supplied mapping function from one type {@code <T>} to
-         * another type {@code <U>}. The mapping function is executed
-         * using the {@link Executor} of the sending client and can
-         * therefore be used to map any response body type, including
-         * blocking {@link java.io.InputStream}s as shown in the following
-         * example which uses a well-known JSON parser to convert an {@code InputStream}
-         * into any annotated Java object type.
-         * <p>
-         * <b>Example usage</b>
-         * <p> <pre> {@code
-         * public static <W> BodySubscriber<W> asJSON(Class<W> targetType) {
+         * Returns a {@code BodySubscriber} whose response body value is that of
+         * the result of applying the given function to the body object of the
+         * given {@code upstream} {@code BodySubscriber}.
+         *
+         * <p> The mapping function is executed using the client's {@linkplain
+         * HttpClient#executor()}, and can therefore be used to map any response
+         * body type, including blocking {@linkplain InputStream}, as shown in
+         * the following example which uses a well-known JSON parser to convert
+         * an {@code InputStream} into any annotated Java object type.
+         *
+         * <p>For example:
+         * <pre> {@code  public static <W> BodySubscriber<W> asJSON(Class<W> targetType) {
          *     BodySubscriber<InputStream> upstream = BodySubscriber.asInputStream();
          *
-         *     BodySubscriber<W> downstream = mappedFrom(
+         *     BodySubscriber<W> downstream = mapping(
          *           upstream,
          *           (InputStream is) -> {
          *               try (InputStream stream = is) {
          *                   ObjectMapper objectMapper = new ObjectMapper();
-         *                   W result = objectMapper.readValue(stream, targetType);
-         *                   return result;
+         *                   return objectMapper.readValue(stream, targetType);
          *               } catch (IOException e) {
          *                   throw new UncheckedIOException(e);
          *               }
          *           });
          *    return downstream;
-         * }
-         * }</pre>
+         * } }</pre>
          *
-         * @param <T> the type of the body subscriber to be mapped
+         * @param <T> the upstream both type
          * @param <U> the type of the body subscriber returned
          * @param upstream the body subscriber to be mapped
          * @param mapper the mapping function
          * @return a mapped body subscriber
          */
-        public static <T,U> BodySubscriber<U> mappedFrom(
-                BodySubscriber<T> upstream,
-                Function<T, U> mapper)
+        public static <T,U> BodySubscriber<U> mapping(BodySubscriber<T> upstream,
+                                                      Function<T, U> mapper)
         {
-            return new ResponseSubscribers.MappedSubscriber<T, U>(upstream, mapper);
+            return new ResponseSubscribers.MappingSubscriber<T, U>(upstream, mapper);
         }
     }
 }