src/java.net.http/share/classes/java/net/http/HttpResponse.java
branchhttp-client-branch
changeset 56410 1b37529eaf3a
parent 56405 3642d0ef7755
child 56438 f2f496ec03c6
equal deleted inserted replaced
56409:b0c62cfc1d12 56410:1b37529eaf3a
   166      */
   166      */
   167     public HttpClient.Version version();
   167     public HttpClient.Version version();
   168 
   168 
   169 
   169 
   170     /**
   170     /**
       
   171      * Initial response information supplied to a {@link BodyHandler} when a
       
   172      * response is initially received and before the body is processed.
       
   173      */
       
   174     public interface ResponseInfo {
       
   175         /**
       
   176          * Provides the response status code
       
   177          * @return the response status code
       
   178          */
       
   179         public int statusCode();
       
   180 
       
   181         /**
       
   182          * Provides the response headers
       
   183          * @return the response headers
       
   184          */
       
   185         public HttpHeaders headers();
       
   186 
       
   187         /**
       
   188          * Provides the response protocol version
       
   189          * @return the response protocol version
       
   190          */
       
   191         public HttpClient.Version version();
       
   192     }
       
   193 
       
   194     /**
   171      * A handler for response bodies.  The class {@link BodyHandlers BodyHandlers}
   195      * A handler for response bodies.  The class {@link BodyHandlers BodyHandlers}
   172      * provides implementations of many common body handlers.
   196      * provides implementations of many common body handlers.
   173      *
   197      *
   174      * <p> The {@code BodyHandler} interface allows inspection of the response
   198      * <p> The {@code BodyHandler} interface allows inspection of the response
   175      * code and headers, before the actual response body is received, and is
   199      * code and headers, before the actual response body is received, and is
   176      * responsible for creating the response {@link BodySubscriber
   200      * responsible for creating the response {@link BodySubscriber
   177      * BodySubscriber}. The {@code BodySubscriber} consumes the actual response
   201      * BodySubscriber}. The {@code BodySubscriber} consumes the actual response
   178      * body bytes and, typically, converts them into a higher-level Java type.
   202      * body bytes and, typically, converts them into a higher-level Java type.
   179      *
   203      *
   180      * <p> A {@code BodyHandler} is a function that takes two parameters: the
   204      * <p> A {@code BodyHandler} is a function that takes a {@link ResponseInfo}
   181      * response status code and the response headers; and which returns a
   205      * object; and which returns a
   182      * {@code BodySubscriber}. The {@code BodyHandler} is invoked when the
   206      * {@code BodySubscriber}. The {@code BodyHandler} is invoked when the
   183      * response status code and headers are available, but before the response
   207      * response status code and headers are available, but before the response
   184      * body bytes are received.
   208      * body bytes are received.
   185      *
   209      *
   186      * <p> The following example uses one of the {@linkplain BodyHandlers
   210      * <p> The following example uses one of the {@linkplain BodyHandlers
   201      * <p> In the second example, the function returns a different subscriber
   225      * <p> In the second example, the function returns a different subscriber
   202      * depending on the status code.
   226      * depending on the status code.
   203      * <pre>{@code   HttpRequest request = HttpRequest.newBuilder()
   227      * <pre>{@code   HttpRequest request = HttpRequest.newBuilder()
   204      *        .uri(URI.create("http://www.foo.com/"))
   228      *        .uri(URI.create("http://www.foo.com/"))
   205      *        .build();
   229      *        .build();
   206      *  BodyHandler<Path> bodyHandler = (status, headers) -> status == 200
   230      *  BodyHandler<Path> bodyHandler = (rspInfo) -> rspInfo.statusCode() == 200
   207      *                      ? BodySubscribers.ofFile(Paths.get("/tmp/f"))
   231      *                      ? BodySubscribers.ofFile(Paths.get("/tmp/f"))
   208      *                      : BodySubscribers.replacing(Paths.get("/NULL"));
   232      *                      : BodySubscribers.replacing(Paths.get("/NULL"));
   209      *  client.sendAsync(request, bodyHandler)
   233      *  client.sendAsync(request, bodyHandler)
   210      *        .thenApply(HttpResponse::body)
   234      *        .thenApply(HttpResponse::body)
   211      *        .thenAccept(System.out::println); }</pre>
   235      *        .thenAccept(System.out::println); }</pre>
   226          *
   250          *
   227          * <p> The response body can be discarded using one of {@link
   251          * <p> The response body can be discarded using one of {@link
   228          * BodyHandlers#discarding() discarding} or {@link
   252          * BodyHandlers#discarding() discarding} or {@link
   229          * BodyHandlers#replacing(Object) replacing}.
   253          * BodyHandlers#replacing(Object) replacing}.
   230          *
   254          *
   231          * @param statusCode the HTTP status code received
   255          * @param responseInfo the response info.
   232          * @param responseHeaders the response headers received
       
   233          * @return a body subscriber
   256          * @return a body subscriber
   234          */
   257          */
   235         public BodySubscriber<T> apply(int statusCode, HttpHeaders responseHeaders);
   258         public BodySubscriber<T> apply(ResponseInfo responseInfo);
   236     }
   259     }
   237 
   260 
   238     /**
   261     /**
   239      * Implementations of {@link BodyHandler BodyHandler} that implement various
   262      * Implementations of {@link BodyHandler BodyHandler} that implement various
   240      * useful handlers, such as handling the response body as a String, or
   263      * useful handlers, such as handling the response body as a String, or
   296          * @return a response body handler
   319          * @return a response body handler
   297          */
   320          */
   298         public static BodyHandler<Void>
   321         public static BodyHandler<Void>
   299         fromSubscriber(Subscriber<? super List<ByteBuffer>> subscriber) {
   322         fromSubscriber(Subscriber<? super List<ByteBuffer>> subscriber) {
   300             Objects.requireNonNull(subscriber);
   323             Objects.requireNonNull(subscriber);
   301             return (status, headers) -> BodySubscribers.fromSubscriber(subscriber,
   324             return (responseInfo) -> BodySubscribers.fromSubscriber(subscriber,
   302                                                                        s -> null);
   325                                                                        s -> null);
   303         }
   326         }
   304 
   327 
   305         /**
   328         /**
   306          * Returns a response body handler that returns a {@link BodySubscriber
   329          * Returns a response body handler that returns a {@link BodySubscriber
   330          */
   353          */
   331         public static <S extends Subscriber<? super List<ByteBuffer>>,T> BodyHandler<T>
   354         public static <S extends Subscriber<? super List<ByteBuffer>>,T> BodyHandler<T>
   332         fromSubscriber(S subscriber, Function<? super S,? extends T> finisher) {
   355         fromSubscriber(S subscriber, Function<? super S,? extends T> finisher) {
   333             Objects.requireNonNull(subscriber);
   356             Objects.requireNonNull(subscriber);
   334             Objects.requireNonNull(finisher);
   357             Objects.requireNonNull(finisher);
   335             return (status, headers) -> BodySubscribers.fromSubscriber(subscriber,
   358             return (responseInfo) -> BodySubscribers.fromSubscriber(subscriber,
   336                                                                       finisher);
   359                                                                       finisher);
   337         }
   360         }
   338 
   361 
   339         /**
   362         /**
   340          * Returns a response body handler that returns a {@link BodySubscriber
   363          * Returns a response body handler that returns a {@link BodySubscriber
   372          * @return a response body handler
   395          * @return a response body handler
   373          */
   396          */
   374         public static BodyHandler<Void>
   397         public static BodyHandler<Void>
   375         fromLineSubscriber(Subscriber<? super String> subscriber) {
   398         fromLineSubscriber(Subscriber<? super String> subscriber) {
   376             Objects.requireNonNull(subscriber);
   399             Objects.requireNonNull(subscriber);
   377             return (status, headers) ->
   400             return (responseInfo) ->
   378                         BodySubscribers.fromLineSubscriber(subscriber,
   401                         BodySubscribers.fromLineSubscriber(subscriber,
   379                                                            s -> null,
   402                                                            s -> null,
   380                                                            charsetFrom(headers),
   403                                                            charsetFrom(responseInfo.headers()),
   381                                                            null);
   404                                                            null);
   382         }
   405         }
   383 
   406 
   384         /**
   407         /**
   385          * Returns a response body handler that returns a {@link BodySubscriber
   408          * Returns a response body handler that returns a {@link BodySubscriber
   429             Objects.requireNonNull(subscriber);
   452             Objects.requireNonNull(subscriber);
   430             Objects.requireNonNull(finisher);
   453             Objects.requireNonNull(finisher);
   431             // implicit null check
   454             // implicit null check
   432             if (lineSeparator != null && lineSeparator.isEmpty())
   455             if (lineSeparator != null && lineSeparator.isEmpty())
   433                 throw new IllegalArgumentException("empty line separator");
   456                 throw new IllegalArgumentException("empty line separator");
   434             return (status, headers) ->
   457             return (responseInfo) ->
   435                         BodySubscribers.fromLineSubscriber(subscriber,
   458                         BodySubscribers.fromLineSubscriber(subscriber,
   436                                                            finisher,
   459                                                            finisher,
   437                                                            charsetFrom(headers),
   460                                                            charsetFrom(responseInfo.headers()),
   438                                                            lineSeparator);
   461                                                            lineSeparator);
   439         }
   462         }
   440 
   463 
   441         /**
   464         /**
   442          * Returns a response body handler that discards the response body.
   465          * Returns a response body handler that discards the response body.
   443          *
   466          *
   444          * @return a response body handler
   467          * @return a response body handler
   445          */
   468          */
   446         public static BodyHandler<Void> discarding() {
   469         public static BodyHandler<Void> discarding() {
   447             return (status, headers) -> BodySubscribers.discarding();
   470             return (responseInfo) -> BodySubscribers.discarding();
   448         }
   471         }
   449 
   472 
   450         /**
   473         /**
   451          * Returns a response body handler that returns the given replacement
   474          * Returns a response body handler that returns the given replacement
   452          * value, after discarding the response body.
   475          * value, after discarding the response body.
   454          * @param <U> the response body type
   477          * @param <U> the response body type
   455          * @param value the value of U to return as the body, may be {@code null}
   478          * @param value the value of U to return as the body, may be {@code null}
   456          * @return a response body handler
   479          * @return a response body handler
   457          */
   480          */
   458         public static <U> BodyHandler<U> replacing(U value) {
   481         public static <U> BodyHandler<U> replacing(U value) {
   459             return (status, headers) -> BodySubscribers.replacing(value);
   482             return (responseInfo) -> BodySubscribers.replacing(value);
   460         }
   483         }
   461 
   484 
   462         /**
   485         /**
   463          * Returns a {@code BodyHandler<String>} that returns a
   486          * Returns a {@code BodyHandler<String>} that returns a
   464          * {@link BodySubscriber BodySubscriber}{@code <String>} obtained from
   487          * {@link BodySubscriber BodySubscriber}{@code <String>} obtained from
   468          * @param charset the character set to convert the body with
   491          * @param charset the character set to convert the body with
   469          * @return a response body handler
   492          * @return a response body handler
   470          */
   493          */
   471         public static BodyHandler<String> ofString(Charset charset) {
   494         public static BodyHandler<String> ofString(Charset charset) {
   472             Objects.requireNonNull(charset);
   495             Objects.requireNonNull(charset);
   473             return (status, headers) -> BodySubscribers.ofString(charset);
   496             return (responseInfo) -> BodySubscribers.ofString(charset);
   474         }
   497         }
   475 
   498 
   476         /**
   499         /**
   477          * Returns a {@code BodyHandler<Path>} that returns a
   500          * Returns a {@code BodyHandler<Path>} that returns a
   478          * {@link BodySubscriber BodySubscriber}{@code <Path>} obtained from
   501          * {@link BodySubscriber BodySubscriber}{@code <Path>} obtained from
   586          * information.
   609          * information.
   587          *
   610          *
   588          * @return a response body handler
   611          * @return a response body handler
   589          */
   612          */
   590         public static BodyHandler<InputStream> ofInputStream() {
   613         public static BodyHandler<InputStream> ofInputStream() {
   591             return (status, headers) -> BodySubscribers.ofInputStream();
   614             return (responseInfo) -> BodySubscribers.ofInputStream();
   592         }
   615         }
   593 
   616 
   594         /**
   617         /**
   595          * Returns a {@code BodyHandler<Stream<String>>} that returns a
   618          * Returns a {@code BodyHandler<Stream<String>>} that returns a
   596          * {@link BodySubscriber BodySubscriber}{@code <Stream<String>>} obtained
   619          * {@link BodySubscriber BodySubscriber}{@code <Stream<String>>} obtained
   603          * not have been completely received.
   626          * not have been completely received.
   604          *
   627          *
   605          * @return a response body handler
   628          * @return a response body handler
   606          */
   629          */
   607         public static BodyHandler<Stream<String>> ofLines() {
   630         public static BodyHandler<Stream<String>> ofLines() {
   608             return (status, headers) ->
   631             return (responseInfo) ->
   609                     BodySubscribers.ofLines(charsetFrom(headers));
   632                     BodySubscribers.ofLines(charsetFrom(responseInfo.headers()));
   610         }
   633         }
   611 
   634 
   612         /**
   635         /**
   613          * Returns a {@code BodyHandler<Void>} that returns a
   636          * Returns a {@code BodyHandler<Void>} that returns a
   614          * {@link BodySubscriber BodySubscriber}{@code <Void>} obtained from
   637          * {@link BodySubscriber BodySubscriber}{@code <Void>} obtained from
   627          * @return a response body handler
   650          * @return a response body handler
   628          */
   651          */
   629         public static BodyHandler<Void>
   652         public static BodyHandler<Void>
   630         ofByteArrayConsumer(Consumer<Optional<byte[]>> consumer) {
   653         ofByteArrayConsumer(Consumer<Optional<byte[]>> consumer) {
   631             Objects.requireNonNull(consumer);
   654             Objects.requireNonNull(consumer);
   632             return (status, headers) -> BodySubscribers.ofByteArrayConsumer(consumer);
   655             return (responseInfo) -> BodySubscribers.ofByteArrayConsumer(consumer);
   633         }
   656         }
   634 
   657 
   635         /**
   658         /**
   636          * Returns a {@code BodyHandler<byte[]>} that returns a
   659          * Returns a {@code BodyHandler<byte[]>} that returns a
   637          * {@link BodySubscriber BodySubscriber}&lt;{@code byte[]}&gt; obtained
   660          * {@link BodySubscriber BodySubscriber}&lt;{@code byte[]}&gt; obtained
   641          * been completely written to the byte array.
   664          * been completely written to the byte array.
   642          *
   665          *
   643          * @return a response body handler
   666          * @return a response body handler
   644          */
   667          */
   645         public static BodyHandler<byte[]> ofByteArray() {
   668         public static BodyHandler<byte[]> ofByteArray() {
   646             return (status, headers) -> BodySubscribers.ofByteArray();
   669             return (responseInfo) -> BodySubscribers.ofByteArray();
   647         }
   670         }
   648 
   671 
   649         /**
   672         /**
   650          * Returns a {@code BodyHandler<String>} that returns a
   673          * Returns a {@code BodyHandler<String>} that returns a
   651          * {@link BodySubscriber BodySubscriber}{@code <String>} obtained from
   674          * {@link BodySubscriber BodySubscriber}{@code <String>} obtained from
   659          * been completely written to the string.
   682          * been completely written to the string.
   660          *
   683          *
   661          * @return a response body handler
   684          * @return a response body handler
   662          */
   685          */
   663         public static BodyHandler<String> ofString() {
   686         public static BodyHandler<String> ofString() {
   664             return (status, headers) -> BodySubscribers.ofString(charsetFrom(headers));
   687             return (responseInfo) -> BodySubscribers.ofString(charsetFrom(responseInfo.headers()));
   665         }
   688         }
   666 
   689 
   667         /**
   690         /**
   668          * Returns a {@code BodyHandler<Publisher<List<ByteBuffer>>>} that creates a
   691          * Returns a {@code BodyHandler<Publisher<List<ByteBuffer>>>} that creates a
   669          * {@link BodySubscriber BodySubscriber}{@code <Publisher<List<ByteBuffer>>>}
   692          * {@link BodySubscriber BodySubscriber}{@code <Publisher<List<ByteBuffer>>>}
   681          * information.
   704          * information.
   682          *
   705          *
   683          * @return a response body handler
   706          * @return a response body handler
   684          */
   707          */
   685         public static BodyHandler<Publisher<List<ByteBuffer>>> ofPublisher() {
   708         public static BodyHandler<Publisher<List<ByteBuffer>>> ofPublisher() {
   686             return (status, headers) -> BodySubscribers.ofPublisher();
   709             return (responseInfo) -> BodySubscribers.ofPublisher();
   687         }
   710         }
   688 
   711 
   689         /**
   712         /**
   690          * Returns a {@code BodyHandler} which, when invoked, returns a {@linkplain
   713          * Returns a {@code BodyHandler} which, when invoked, returns a {@linkplain
   691          * BodySubscribers#buffering(BodySubscriber,int) buffering BodySubscriber}
   714          * BodySubscribers#buffering(BodySubscriber,int) buffering BodySubscriber}
   705          public static <T> BodyHandler<T> buffering(BodyHandler<T> downstreamHandler,
   728          public static <T> BodyHandler<T> buffering(BodyHandler<T> downstreamHandler,
   706                                                     int bufferSize) {
   729                                                     int bufferSize) {
   707              Objects.requireNonNull(downstreamHandler);
   730              Objects.requireNonNull(downstreamHandler);
   708              if (bufferSize <= 0)
   731              if (bufferSize <= 0)
   709                  throw new IllegalArgumentException("must be greater than 0");
   732                  throw new IllegalArgumentException("must be greater than 0");
   710              return (status, headers) -> BodySubscribers
   733              return (responseInfo) -> BodySubscribers
   711                      .buffering(downstreamHandler.apply(status, headers),
   734                      .buffering(downstreamHandler.apply(responseInfo),
   712                                 bufferSize);
   735                                 bufferSize);
   713          }
   736          }
   714     }
   737     }
   715 
   738 
   716     /**
   739     /**