513 * @param openOptions any options to use when opening/creating the file |
513 * @param openOptions any options to use when opening/creating the file |
514 * @return a response body handler |
514 * @return a response body handler |
515 * @throws IllegalArgumentException if an invalid set of open options |
515 * @throws IllegalArgumentException if an invalid set of open options |
516 * are specified |
516 * are specified |
517 * @throws SecurityException If a security manager has been installed |
517 * @throws SecurityException If a security manager has been installed |
518 * and it denies {@link SecurityManager#checkWrite(String) |
518 * and it denies {@linkplain SecurityManager#checkWrite(String) |
519 * write access} to the file. |
519 * write access} to the file. |
520 */ |
520 */ |
521 public static BodyHandler<Path> ofFile(Path file, OpenOption... openOptions) { |
521 public static BodyHandler<Path> ofFile(Path file, OpenOption... openOptions) { |
522 Objects.requireNonNull(file); |
522 Objects.requireNonNull(file); |
523 List<OpenOption> opts = List.of(openOptions); |
523 List<OpenOption> opts = List.of(openOptions); |
539 * that the {@code BodyHandler} is not shared with untrusted code. |
539 * that the {@code BodyHandler} is not shared with untrusted code. |
540 * |
540 * |
541 * @param file the file to store the body in |
541 * @param file the file to store the body in |
542 * @return a response body handler |
542 * @return a response body handler |
543 * @throws SecurityException If a security manager has been installed |
543 * @throws SecurityException If a security manager has been installed |
544 * and it denies {@link SecurityManager#checkWrite(String) |
544 * and it denies {@linkplain SecurityManager#checkWrite(String) |
545 * write access} to the file. |
545 * write access} to the file. |
546 */ |
546 */ |
547 public static BodyHandler<Path> ofFile(Path file) { |
547 public static BodyHandler<Path> ofFile(Path file) { |
548 return BodyHandlers.ofFile(file, CREATE, WRITE); |
548 return BodyHandlers.ofFile(file, CREATE, WRITE); |
549 } |
549 } |
654 return (responseInfo) -> BodySubscribers.ofByteArrayConsumer(consumer); |
654 return (responseInfo) -> BodySubscribers.ofByteArrayConsumer(consumer); |
655 } |
655 } |
656 |
656 |
657 /** |
657 /** |
658 * Returns a {@code BodyHandler<byte[]>} that returns a |
658 * Returns a {@code BodyHandler<byte[]>} that returns a |
659 * {@link BodySubscriber BodySubscriber}<{@code byte[]}> obtained |
659 * {@link BodySubscriber BodySubscriber}{@code <byte[]>} obtained |
660 * from {@link BodySubscribers#ofByteArray() BodySubscribers.ofByteArray()}. |
660 * from {@link BodySubscribers#ofByteArray() BodySubscribers.ofByteArray()}. |
661 * |
661 * |
662 * <p> When the {@code HttpResponse} object is returned, the body has |
662 * <p> When the {@code HttpResponse} object is returned, the body has |
663 * been completely written to the byte array. |
663 * been completely written to the byte array. |
664 * |
664 * |
693 * BodySubscribers.ofPublisher()}. |
693 * BodySubscribers.ofPublisher()}. |
694 * |
694 * |
695 * <p> When the {@code HttpResponse} object is returned, the response |
695 * <p> When the {@code HttpResponse} object is returned, the response |
696 * headers will have been completely read, but the body may not have |
696 * headers will have been completely read, but the body may not have |
697 * been fully received yet. The {@link #body()} method returns a |
697 * been fully received yet. The {@link #body()} method returns a |
698 * {@link Publisher Publisher<List<ByteBuffer>>} from which the body |
698 * {@link Publisher Publisher}{@code <List<ByteBuffer>>} from which the body |
699 * response bytes can be obtained as they are received. The publisher |
699 * response bytes can be obtained as they are received. The publisher |
700 * can and must be subscribed to only once. |
700 * can and must be subscribed to only once. |
701 * |
701 * |
702 * @apiNote See {@link BodySubscribers#ofPublisher()} for more |
702 * @apiNote See {@link BodySubscribers#ofPublisher()} for more |
703 * information. |
703 * information. |
792 * <p> Entries are added to the given map for each push promise accepted. |
792 * <p> Entries are added to the given map for each push promise accepted. |
793 * The entry's key is the push request, and the entry's value is a |
793 * The entry's key is the push request, and the entry's value is a |
794 * {@code CompletableFuture} that completes with the response |
794 * {@code CompletableFuture} that completes with the response |
795 * corresponding to the key's push request. A push request is rejected / |
795 * corresponding to the key's push request. A push request is rejected / |
796 * cancelled if there is already an entry in the map whose key is |
796 * cancelled if there is already an entry in the map whose key is |
797 * {@link HttpRequest#equals equal} to it. A push request is |
797 * {@linkplain HttpRequest#equals equal} to it. A push request is |
798 * rejected / cancelled if it does not have the same origin as its |
798 * rejected / cancelled if it does not have the same origin as its |
799 * initiating request. |
799 * initiating request. |
800 * |
800 * |
801 * <p> Entries are added to the given map as soon as practically |
801 * <p> Entries are added to the given map as soon as practically |
802 * possible when a push promise is received and accepted. That way code, |
802 * possible when a push promise is received and accepted. That way code, |
837 * once passed to the subscriber, are no longer used by the HTTP Client. The |
837 * once passed to the subscriber, are no longer used by the HTTP Client. The |
838 * subscriber converts the incoming buffers of data to some higher-level |
838 * subscriber converts the incoming buffers of data to some higher-level |
839 * Java type {@code T}. |
839 * Java type {@code T}. |
840 * |
840 * |
841 * <p> The {@link #getBody()} method returns a |
841 * <p> The {@link #getBody()} method returns a |
842 * {@link CompletionStage}<{@code T}> that provides the response body |
842 * {@link CompletionStage}{@code <T>} that provides the response body |
843 * object. The {@code CompletionStage} must be obtainable at any time. When |
843 * object. The {@code CompletionStage} must be obtainable at any time. When |
844 * it completes depends on the nature of type {@code T}. In many cases, |
844 * it completes depends on the nature of type {@code T}. In many cases, |
845 * when {@code T} represents the entire body after being consumed then |
845 * when {@code T} represents the entire body after being consumed then |
846 * the {@code CompletionStage} completes after the body has been consumed. |
846 * the {@code CompletionStage} completes after the body has been consumed. |
847 * If {@code T} is a streaming type, such as {@link java.io.InputStream |
847 * If {@code T} is a streaming type, such as {@link java.io.InputStream |
848 * InputStream}, then it completes before the body has been read, because |
848 * InputStream}, then it completes before the body has been read, because |
849 * the calling code uses the {@code InputStream} to consume the data. |
849 * the calling code uses the {@code InputStream} to consume the data. |
850 * |
850 * |
851 * @apiNote To ensure that all resources associated with the corresponding |
851 * @apiNote To ensure that all resources associated with the corresponding |
852 * HTTP exchange are properly released, an implementation of {@code |
852 * HTTP exchange are properly released, an implementation of {@code |
853 * BodySubscriber} should ensure to {@link Flow.Subscription#request |
853 * BodySubscriber} should ensure to {@linkplain Flow.Subscription#request |
854 * request} more data until one of {@link #onComplete() onComplete} or |
854 * request} more data until one of {@link #onComplete() onComplete} or |
855 * {@link #onError(Throwable) onError} are signalled, or {@link |
855 * {@link #onError(Throwable) onError} are signalled, or {@link |
856 * Flow.Subscription#request cancel} its {@linkplain |
856 * Flow.Subscription#request cancel} its {@linkplain |
857 * #onSubscribe(Flow.Subscription) subscription} if unable or unwilling to |
857 * #onSubscribe(Flow.Subscription) subscription} if unable or unwilling to |
858 * do so. Calling {@code cancel} before exhausting the response body data |
858 * do so. Calling {@code cancel} before exhausting the response body data |
1075 * @param openOptions the list of options to open the file with |
1075 * @param openOptions the list of options to open the file with |
1076 * @return a body subscriber |
1076 * @return a body subscriber |
1077 * @throws IllegalArgumentException if an invalid set of open options |
1077 * @throws IllegalArgumentException if an invalid set of open options |
1078 * are specified |
1078 * are specified |
1079 * @throws SecurityException if a security manager has been installed |
1079 * @throws SecurityException if a security manager has been installed |
1080 * and it denies {@link SecurityManager#checkWrite(String) |
1080 * and it denies {@linkplain SecurityManager#checkWrite(String) |
1081 * write access} to the file |
1081 * write access} to the file |
1082 */ |
1082 */ |
1083 public static BodySubscriber<Path> ofFile(Path file, OpenOption... openOptions) { |
1083 public static BodySubscriber<Path> ofFile(Path file, OpenOption... openOptions) { |
1084 Objects.requireNonNull(file); |
1084 Objects.requireNonNull(file); |
1085 List<OpenOption> opts = List.of(openOptions); |
1085 List<OpenOption> opts = List.of(openOptions); |
1101 * that the {@code BodyHandler} is not shared with untrusted code. |
1101 * that the {@code BodyHandler} is not shared with untrusted code. |
1102 * |
1102 * |
1103 * @param file the file to store the body in |
1103 * @param file the file to store the body in |
1104 * @return a body subscriber |
1104 * @return a body subscriber |
1105 * @throws SecurityException if a security manager has been installed |
1105 * @throws SecurityException if a security manager has been installed |
1106 * and it denies {@link SecurityManager#checkWrite(String) |
1106 * and it denies {@linkplain SecurityManager#checkWrite(String) |
1107 * write access} to the file |
1107 * write access} to the file |
1108 */ |
1108 */ |
1109 public static BodySubscriber<Path> ofFile(Path file) { |
1109 public static BodySubscriber<Path> ofFile(Path file) { |
1110 return ofFile(file, CREATE, WRITE); |
1110 return ofFile(file, CREATE, WRITE); |
1111 } |
1111 } |
1158 return new ResponseSubscribers.HttpResponseInputStream(); |
1158 return new ResponseSubscribers.HttpResponseInputStream(); |
1159 } |
1159 } |
1160 |
1160 |
1161 /** |
1161 /** |
1162 * Returns a {@code BodySubscriber} which streams the response body as |
1162 * Returns a {@code BodySubscriber} which streams the response body as |
1163 * a {@link Stream Stream<String>}, where each string in the stream |
1163 * a {@link Stream Stream}{@code <String>}, where each string in the stream |
1164 * corresponds to a line as defined by {@link BufferedReader#lines()}. |
1164 * corresponds to a line as defined by {@link BufferedReader#lines()}. |
1165 * |
1165 * |
1166 * <p> The {@link HttpResponse} using this subscriber is available |
1166 * <p> The {@link HttpResponse} using this subscriber is available |
1167 * immediately after the response headers have been read, without |
1167 * immediately after the response headers have been read, without |
1168 * requiring to wait for the entire body to be processed. The response |
1168 * requiring to wait for the entire body to be processed. The response |
1176 * the underlying HTTP connection to be closed and prevent it |
1176 * the underlying HTTP connection to be closed and prevent it |
1177 * from being reused for subsequent operations. |
1177 * from being reused for subsequent operations. |
1178 * |
1178 * |
1179 * @param charset the character set to use when converting bytes to characters |
1179 * @param charset the character set to use when converting bytes to characters |
1180 * @return a body subscriber that streams the response body as a |
1180 * @return a body subscriber that streams the response body as a |
1181 * {@link Stream Stream<String>}. |
1181 * {@link Stream Stream}{@code <String>}. |
1182 * |
1182 * |
1183 * @see BufferedReader#lines() |
1183 * @see BufferedReader#lines() |
1184 */ |
1184 */ |
1185 public static BodySubscriber<Stream<String>> ofLines(Charset charset) { |
1185 public static BodySubscriber<Stream<String>> ofLines(Charset charset) { |
1186 return ResponseSubscribers.createLineStream(charset); |
1186 return ResponseSubscribers.createLineStream(charset); |