29 import java.io.InputStream;
30 import java.net.URI;
31 import jdk.incubator.http.ResponseSubscribers.MultiSubscriberImpl;
32 import static jdk.incubator.http.internal.common.Utils.unchecked;
33 import static jdk.incubator.http.internal.common.Utils.charsetFrom;
34 import java.nio.ByteBuffer;
35 import java.nio.charset.Charset;
36 import java.nio.channels.FileChannel;
37 import java.nio.file.OpenOption;
38 import java.nio.file.Path;
39 import java.nio.file.Paths;
40 import java.nio.file.StandardOpenOption;
41 import java.security.AccessControlContext;
42 import java.util.Arrays;
43 import java.util.List;
44 import java.util.Objects;
45 import java.util.Optional;
46 import java.util.concurrent.CompletableFuture;
47 import java.util.concurrent.CompletionStage;
48 import java.util.concurrent.Flow;
49 import java.util.function.Consumer;
50 import java.util.function.Function;
51 import javax.net.ssl.SSLParameters;
52
53 /**
54 * Represents a response to a {@link HttpRequest}.
55 * {@Incubating}
56 *
57 * <p> A {@code HttpResponse} is available when the response status code and
58 * headers have been received, and typically after the response body has also
59 * been received. This depends on the response body handler provided when
60 * sending the request. In all cases, the response body handler is invoked
61 * before the body is read. This gives applications an opportunity to decide
62 * how to handle the body.
63 *
64 * <p> Methods are provided in this class for accessing the response headers,
65 * and response body.
66 *
67 * <p><b>Response handlers and subscribers</b>
68 *
312 * @param <T> the response body type
313 */
314 @FunctionalInterface
315 public interface BodyHandler<T> {
316
317 /**
318 * Returns a {@link BodySubscriber BodySubscriber} considering the given
319 * response status code and headers. This method is always called before
320 * the body is read and its implementation can decide to keep the body
321 * and store it somewhere, or else discard it by returning the {@code
322 * BodySubscriber} returned from {@link BodySubscriber#discard(Object)
323 * discard}.
324 *
325 * @param statusCode the HTTP status code received
326 * @param responseHeaders the response headers received
327 * @return a body subscriber
328 */
329 public BodySubscriber<T> apply(int statusCode, HttpHeaders responseHeaders);
330
331 /**
332 * Returns a response body handler which discards the response body and
333 * uses the given value as a replacement for it.
334 *
335 * @param <U> the response body type
336 * @param value the value of U to return as the body, may be {@code null}
337 * @return a response body handler
338 */
339 public static <U> BodyHandler<U> discard(U value) {
340 return (status, headers) -> BodySubscriber.discard(value);
341 }
342
343 /**
344 * Returns a {@code BodyHandler<String>} that returns a
345 * {@link BodySubscriber BodySubscriber}{@code <String>} obtained from
346 * {@link BodySubscriber#asString(Charset) BodySubscriber.asString(Charset)}.
347 * If a charset is provided, the body is decoded using it. If charset is
348 * {@code null} then the handler tries to determine the character set
349 * from the {@code Content-encoding} header. If that charset is not
350 * supported then {@link java.nio.charset.StandardCharsets#UTF_8 UTF_8}
351 * is used.
584 * #onComplete() onComplete} or {@link #onError(Throwable) onError}
585 * are signalled, or {@linkplain Flow.Subscription#request cancel} its
586 * {@linkplain #onSubscribe(Flow.Subscription) subscription}
587 * if unable or unwilling to do so.
588 * Calling {@code cancel} before exhausting the data may cause
589 * the underlying HTTP connection to be closed and prevent it
590 * from being reused for subsequent operations.
591 *
592 * @param <T> the response body type
593 */
594 public interface BodySubscriber<T>
595 extends Flow.Subscriber<List<ByteBuffer>> {
596
597 /**
598 * Returns a {@code CompletionStage} which when completed will return
599 * the response body object.
600 *
601 * @return a CompletionStage for the response body
602 */
603 public CompletionStage<T> getBody();
604
605 /**
606 * Returns a body subscriber which stores the response body as a {@code
607 * String} converted using the given {@code Charset}.
608 *
609 * <p> The {@link HttpResponse} using this subscriber is available after
610 * the entire response has been read.
611 *
612 * @param charset the character set to convert the String with
613 * @return a body subscriber
614 */
615 public static BodySubscriber<String> asString(Charset charset) {
616 return new ResponseSubscribers.ByteArraySubscriber<>(
617 bytes -> new String(bytes, charset)
618 );
619 }
620
621 /**
622 * Returns a {@code BodySubscriber} which stores the response body as a
623 * byte array.
|
29 import java.io.InputStream;
30 import java.net.URI;
31 import jdk.incubator.http.ResponseSubscribers.MultiSubscriberImpl;
32 import static jdk.incubator.http.internal.common.Utils.unchecked;
33 import static jdk.incubator.http.internal.common.Utils.charsetFrom;
34 import java.nio.ByteBuffer;
35 import java.nio.charset.Charset;
36 import java.nio.channels.FileChannel;
37 import java.nio.file.OpenOption;
38 import java.nio.file.Path;
39 import java.nio.file.Paths;
40 import java.nio.file.StandardOpenOption;
41 import java.security.AccessControlContext;
42 import java.util.Arrays;
43 import java.util.List;
44 import java.util.Objects;
45 import java.util.Optional;
46 import java.util.concurrent.CompletableFuture;
47 import java.util.concurrent.CompletionStage;
48 import java.util.concurrent.Flow;
49 import java.util.concurrent.Flow.Subscriber;
50 import java.util.function.Consumer;
51 import java.util.function.Function;
52 import javax.net.ssl.SSLParameters;
53
54 /**
55 * Represents a response to a {@link HttpRequest}.
56 * {@Incubating}
57 *
58 * <p> A {@code HttpResponse} is available when the response status code and
59 * headers have been received, and typically after the response body has also
60 * been received. This depends on the response body handler provided when
61 * sending the request. In all cases, the response body handler is invoked
62 * before the body is read. This gives applications an opportunity to decide
63 * how to handle the body.
64 *
65 * <p> Methods are provided in this class for accessing the response headers,
66 * and response body.
67 *
68 * <p><b>Response handlers and subscribers</b>
69 *
313 * @param <T> the response body type
314 */
315 @FunctionalInterface
316 public interface BodyHandler<T> {
317
318 /**
319 * Returns a {@link BodySubscriber BodySubscriber} considering the given
320 * response status code and headers. This method is always called before
321 * the body is read and its implementation can decide to keep the body
322 * and store it somewhere, or else discard it by returning the {@code
323 * BodySubscriber} returned from {@link BodySubscriber#discard(Object)
324 * discard}.
325 *
326 * @param statusCode the HTTP status code received
327 * @param responseHeaders the response headers received
328 * @return a body subscriber
329 */
330 public BodySubscriber<T> apply(int statusCode, HttpHeaders responseHeaders);
331
332 /**
333 * Returns a response body handler that returns a {@link BodySubscriber
334 * BodySubscriber}{@code <Void>} obtained from {@linkplain
335 * BodySubscriber#fromSubscriber(Subscriber)}, with the given
336 * {@code subscriber}.
337 *
338 * <p> The response body is not available through this, or the {@code
339 * HttpResponse} API, but instead all response body is forwarded to the
340 * given {@code subscriber}, which should make it available, if
341 * appropriate, through some other mechanism, e.g. an entry in a
342 * database, etc.
343 *
344 * @apiNote This method can be used as an adapter between {@code
345 * BodySubscriber} and {@code Flow.Subscriber}.
346 *
347 * <p> For example:
348 * <pre> {@code
349 * TextSubscriber subscriber = new TextSubscriber();
350 * HttpResponse<Void> response = client.sendAsync(request,
351 * BodyHandler.fromSubscriber(subscriber)).join();
352 * System.out.println(response.statusCode());
353 * }</pre>
354 *
355 * @param subscriber the subscriber
356 * @return a response body handler
357 */
358 public static BodyHandler<Void>
359 fromSubscriber(Subscriber<? super List<ByteBuffer>> subscriber) {
360 Objects.requireNonNull(subscriber);
361 return (status, headers) -> BodySubscriber.fromSubscriber(subscriber,
362 s -> null);
363 }
364
365 /**
366 * Returns a response body handler that returns a {@link BodySubscriber
367 * BodySubscriber}{@code <T>} obtained from {@link
368 * BodySubscriber#fromSubscriber(Subscriber, Function)}, with the
369 * given {@code subscriber} and {@code finisher} function.
370 *
371 * <p> The given {@code finisher} function is applied after the given
372 * subscriber's {@code onComplete} has been invoked. The {@code finisher}
373 * function is invoked with the given subscriber, and returns a value
374 * that is set as the response's body.
375 *
376 * @apiNote This method can be used as an adapter between {@code
377 * BodySubscriber} and {@code Flow.Subscriber}.
378 *
379 * <p> For example:
380 * <pre> {@code
381 * TextSubscriber subscriber = ...; // accumulates bytes and transforms them into a String
382 * HttpResponse<String> response = client.sendAsync(request,
383 * BodyHandler.fromSubscriber(subscriber, TextSubscriber::getTextResult)).join();
384 * String text = response.body();
385 * }</pre>
386 *
387 * @param <S> the type of the Subscriber
388 * @param <T> the type of the response body
389 * @param subscriber the subscriber
390 * @param finisher a function to be applied after the subscriber has completed
391 * @return a response body handler
392 */
393 public static <S extends Subscriber<? super List<ByteBuffer>>,T> BodyHandler<T>
394 fromSubscriber(S subscriber, Function<S,T> finisher) {
395 Objects.requireNonNull(subscriber);
396 Objects.requireNonNull(finisher);
397 return (status, headers) -> BodySubscriber.fromSubscriber(subscriber,
398 finisher);
399 }
400
401 /**
402 * Returns a response body handler which discards the response body and
403 * uses the given value as a replacement for it.
404 *
405 * @param <U> the response body type
406 * @param value the value of U to return as the body, may be {@code null}
407 * @return a response body handler
408 */
409 public static <U> BodyHandler<U> discard(U value) {
410 return (status, headers) -> BodySubscriber.discard(value);
411 }
412
413 /**
414 * Returns a {@code BodyHandler<String>} that returns a
415 * {@link BodySubscriber BodySubscriber}{@code <String>} obtained from
416 * {@link BodySubscriber#asString(Charset) BodySubscriber.asString(Charset)}.
417 * If a charset is provided, the body is decoded using it. If charset is
418 * {@code null} then the handler tries to determine the character set
419 * from the {@code Content-encoding} header. If that charset is not
420 * supported then {@link java.nio.charset.StandardCharsets#UTF_8 UTF_8}
421 * is used.
654 * #onComplete() onComplete} or {@link #onError(Throwable) onError}
655 * are signalled, or {@linkplain Flow.Subscription#request cancel} its
656 * {@linkplain #onSubscribe(Flow.Subscription) subscription}
657 * if unable or unwilling to do so.
658 * Calling {@code cancel} before exhausting the data may cause
659 * the underlying HTTP connection to be closed and prevent it
660 * from being reused for subsequent operations.
661 *
662 * @param <T> the response body type
663 */
664 public interface BodySubscriber<T>
665 extends Flow.Subscriber<List<ByteBuffer>> {
666
667 /**
668 * Returns a {@code CompletionStage} which when completed will return
669 * the response body object.
670 *
671 * @return a CompletionStage for the response body
672 */
673 public CompletionStage<T> getBody();
674
675 /**
676 * Returns a body subscriber that forwards all response body to the
677 * given {@code Flow.Subscriber}. The {@linkplain #getBody()} completion
678 * stage} of the returned body subscriber completes after one of the
679 * given subscribers {@code onComplete} or {@code onError} has been
680 * invoked.
681 *
682 * @apiNote This method can be used as an adapter between {@code
683 * BodySubscriber} and {@code Flow.Subscriber}.
684 *
685 * @param <S> the type of the Subscriber
686 * @param subscriber the subscriber
687 * @return a body subscriber
688 */
689 public static <S extends Subscriber<? super List<ByteBuffer>>> BodySubscriber<Void>
690 fromSubscriber(S subscriber) {
691 return new ResponseSubscribers.SubscriberAdapter<S,Void>(subscriber, s -> null);
692 }
693
694 /**
695 * Returns a body subscriber that forwards all response body to the
696 * given {@code Flow.Subscriber}. The {@linkplain #getBody()} completion
697 * stage} of the returned body subscriber completes after one of the
698 * given subscribers {@code onComplete} or {@code onError} has been
699 * invoked.
700 *
701 * <p> The given {@code finisher} function is applied after the given
702 * subscriber's {@code onComplete} has been invoked. The {@code finisher}
703 * function is invoked with the given subscriber, and returns a value
704 * that is set as the response's body.
705 *
706 * @apiNote This method can be used as an adapter between {@code
707 * BodySubscriber} and {@code Flow.Subscriber}.
708 *
709 * @param <S> the type of the Subscriber
710 * @param <T> the type of the response body
711 * @param subscriber the subscriber
712 * @param finisher a function to be applied after the subscriber has
713 * completed
714 * @return a body subscriber
715 */
716 public static <S extends Subscriber<? super List<ByteBuffer>>,T> BodySubscriber<T>
717 fromSubscriber(S subscriber,
718 Function<S,T> finisher) {
719 return new ResponseSubscribers.SubscriberAdapter<S,T>(subscriber, finisher);
720 }
721
722 /**
723 * Returns a body subscriber which stores the response body as a {@code
724 * String} converted using the given {@code Charset}.
725 *
726 * <p> The {@link HttpResponse} using this subscriber is available after
727 * the entire response has been read.
728 *
729 * @param charset the character set to convert the String with
730 * @return a body subscriber
731 */
732 public static BodySubscriber<String> asString(Charset charset) {
733 return new ResponseSubscribers.ByteArraySubscriber<>(
734 bytes -> new String(bytes, charset)
735 );
736 }
737
738 /**
739 * Returns a {@code BodySubscriber} which stores the response body as a
740 * byte array.
|