8300792: Refactor examples in java.net.http to use @snippet

Reviewed-by: dfuchs, jpai
This commit is contained in:
Darragh Clarke 2023-02-27 09:18:56 +00:00 committed by Jaikiran Pai
parent a2c5a4ac9e
commit 306134dcf9
4 changed files with 113 additions and 76 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -85,7 +85,8 @@ import jdk.internal.net.http.HttpClientBuilderImpl;
* </ul>
*
* <p><b>Synchronous Example</b>
* <pre>{@code HttpClient client = HttpClient.newBuilder()
* {@snippet :
* HttpClient client = HttpClient.newBuilder()
* .version(Version.HTTP_1_1)
* .followRedirects(Redirect.NORMAL)
* .connectTimeout(Duration.ofSeconds(20))
@ -94,10 +95,11 @@ import jdk.internal.net.http.HttpClientBuilderImpl;
* .build();
* HttpResponse<String> response = client.send(request, BodyHandlers.ofString());
* System.out.println(response.statusCode());
* System.out.println(response.body()); }</pre>
* System.out.println(response.body()); }
*
* <p><b>Asynchronous Example</b>
* <pre>{@code HttpRequest request = HttpRequest.newBuilder()
* {@snippet :
* HttpRequest request = HttpRequest.newBuilder()
* .uri(URI.create("https://foo.com/"))
* .timeout(Duration.ofMinutes(2))
* .header("Content-Type", "application/json")
@ -105,7 +107,7 @@ import jdk.internal.net.http.HttpClientBuilderImpl;
* .build();
* client.sendAsync(request, BodyHandlers.ofString())
* .thenApply(HttpResponse::body)
* .thenAccept(System.out::println); }</pre>
* .thenAccept(System.out::println); }
*
* <p> <a id="securitychecks"><b>Security checks</b></a>
*
@ -688,20 +690,23 @@ public abstract class HttpClient {
* Creates a new {@code WebSocket} builder (optional operation).
*
* <p> <b>Example</b>
* <pre>{@code HttpClient client = HttpClient.newHttpClient();
* {@snippet :
* HttpClient client = HttpClient.newHttpClient();
* CompletableFuture<WebSocket> ws = client.newWebSocketBuilder()
* .buildAsync(URI.create("ws://websocket.example.com"), listener); }</pre>
* .buildAsync(URI.create("ws://websocket.example.com"), listener); }
*
* <p> Finer control over the WebSocket Opening Handshake can be achieved
* by using a custom {@code HttpClient}.
*
* <p> <b>Example</b>
* <pre>{@code InetSocketAddress addr = new InetSocketAddress("proxy.example.com", 80);
* {@snippet :
* InetSocketAddress addr = new InetSocketAddress("proxy.example.com", 80);
* HttpClient client = HttpClient.newBuilder()
* .proxy(ProxySelector.of(addr))
* .build();
*
* CompletableFuture<WebSocket> ws = client.newWebSocketBuilder()
* .buildAsync(URI.create("ws://websocket.example.com"), listener); }</pre>
* .buildAsync(URI.create("ws://websocket.example.com"), listener); }
*
* @implSpec The default implementation of this method throws
* {@code UnsupportedOperationException}. Clients obtained through

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -66,14 +66,17 @@ import static java.nio.charset.StandardCharsets.UTF_8;
* <p> The following is an example of a GET request that prints the response
* body as a String:
*
* <pre>{@code HttpClient client = HttpClient.newHttpClient();
* {@snippet :
* HttpClient client = HttpClient.newHttpClient();
*
* HttpRequest request = HttpRequest.newBuilder()
* .uri(URI.create("http://foo.com/"))
* .build();
*
* client.sendAsync(request, BodyHandlers.ofString())
* .thenApply(HttpResponse::body)
* .thenAccept(System.out::println)
* .join(); }</pre>
* .join(); }
*
* <p>The class {@link BodyPublishers BodyPublishers} provides implementations
* of many common publishers. Alternatively, a custom {@code BodyPublisher}
@ -341,13 +344,16 @@ public abstract class HttpRequest {
* <br><br>
* <ul>
* <li> Retain all headers:
* <pre>{@code HttpRequest.newBuilder(request, (n, v) -> true)}</pre>
* {@snippet :
* HttpRequest.newBuilder(request, (n, v) -> true) }
*
* <li> Remove all headers:
* <pre>{@code HttpRequest.newBuilder(request, (n, v) -> false)}</pre>
* {@snippet :
* HttpRequest.newBuilder(request, (n, v) -> false) }
*
* <li> Remove a particular header (e.g. Foo-Bar):
* <pre>{@code HttpRequest.newBuilder(request, (name, value) -> !name.equalsIgnoreCase("Foo-Bar"))}</pre>
* {@snippet :
* HttpRequest.newBuilder(request, (name, value) -> !name.equalsIgnoreCase("Foo-Bar")) }
* </ul>
*
* @param request the original request
@ -561,25 +567,28 @@ public abstract class HttpRequest {
* convert common high-level Java objects into a flow of data suitable for
* sending as a request body:
*
* <pre>{@code // Request body from a String
* {@snippet :
* // Request body from a String
* HttpRequest request = HttpRequest.newBuilder()
* .uri(URI.create("https://foo.com/"))
* .header("Content-Type", "text/plain; charset=UTF-8")
* .POST(BodyPublishers.ofString("some body text"))
* .build();
* .build(); }
*
* {@snippet :
* // Request body from a File
* HttpRequest request = HttpRequest.newBuilder()
* .uri(URI.create("https://foo.com/"))
* .header("Content-Type", "application/json")
* .POST(BodyPublishers.ofFile(Paths.get("file.json")))
* .build();
* .build(); }
*
* {@snippet :
* // Request body from a byte array
* HttpRequest request = HttpRequest.newBuilder()
* .uri(URI.create("https://foo.com/"))
* .POST(BodyPublishers.ofByteArray(new byte[] { ... }))
* .build(); }</pre>
* .build(); }
*
* @since 11
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -77,8 +77,9 @@ import static jdk.internal.net.http.common.Utils.charsetFrom;
*
* <p> The following is an example of retrieving a response as a String:
*
* <pre>{@code HttpResponse<String> response = client
* .send(request, BodyHandlers.ofString()); }</pre>
* {@snippet :
* HttpResponse<String> response = client
* .send(request, BodyHandlers.ofString()); }
*
* <p> The class {@link BodyHandlers BodyHandlers} provides implementations
* of many common response handlers. Alternatively, a custom {@code BodyHandler}
@ -211,12 +212,14 @@ public interface HttpResponse<T> {
* predefined body handlers} that always process the response body in the
* same way ( streams the response body to a file ).
*
* <pre>{@code HttpRequest request = HttpRequest.newBuilder()
* {@snippet :
* HttpRequest request = HttpRequest.newBuilder()
* .uri(URI.create("http://www.foo.com/"))
* .build();
*
* client.sendAsync(request, BodyHandlers.ofFile(Paths.get("/tmp/f")))
* .thenApply(HttpResponse::body)
* .thenAccept(System.out::println); }</pre>
* .thenAccept(System.out::println); }
*
* Note, that even though the pre-defined handlers do not examine the
* response code, the response code and headers are always retrievable from
@ -224,7 +227,8 @@ public interface HttpResponse<T> {
*
* <p> In the second example, the function returns a different subscriber
* depending on the status code.
* <pre>{@code HttpRequest request = HttpRequest.newBuilder()
* {@snippet :
* HttpRequest request = HttpRequest.newBuilder()
* .uri(URI.create("http://www.foo.com/"))
* .build();
* BodyHandler<Path> bodyHandler = (rspInfo) -> rspInfo.statusCode() == 200
@ -232,7 +236,7 @@ public interface HttpResponse<T> {
* : BodySubscribers.replacing(Paths.get("/NULL"));
* client.sendAsync(request, bodyHandler)
* .thenApply(HttpResponse::body)
* .thenAccept(System.out::println); }</pre>
* .thenAccept(System.out::println); }
*
* @param <T> the response body type
* @see BodyHandlers
@ -272,21 +276,25 @@ public interface HttpResponse<T> {
* <p>The following are examples of using the predefined body handlers to
* convert a flow of response body data into common high-level Java objects:
*
* <pre>{@code // Receives the response body as a String
* {@snippet :
* // Receives the response body as a String
* HttpResponse<String> response = client
* .send(request, BodyHandlers.ofString());
* .send(request, BodyHandlers.ofString()); }
*
* {@snippet :
* // Receives the response body as a file
* HttpResponse<Path> response = client
* .send(request, BodyHandlers.ofFile(Paths.get("example.html")));
* .send(request, BodyHandlers.ofFile(Paths.get("example.html"))); }
*
* {@snippet :
* // Receives the response body as an InputStream
* HttpResponse<InputStream> response = client
* .send(request, BodyHandlers.ofInputStream());
* .send(request, BodyHandlers.ofInputStream()); }
*
* {@snippet :
* // Discards the response body
* HttpResponse<Void> response = client
* .send(request, BodyHandlers.discarding()); }</pre>
* .send(request, BodyHandlers.discarding()); }
*
* @since 11
*/
@ -310,10 +318,11 @@ public interface HttpResponse<T> {
* BodySubscriber} and {@code Flow.Subscriber}.
*
* <p> For example:
* <pre> {@code TextSubscriber subscriber = new TextSubscriber();
* {@snippet :
* TextSubscriber subscriber = new TextSubscriber();
* HttpResponse<Void> response = client.sendAsync(request,
* BodyHandlers.fromSubscriber(subscriber)).join();
* System.out.println(response.statusCode()); }</pre>
* System.out.println(response.statusCode()); }
*
* @param subscriber the subscriber
* @return a response body handler
@ -340,10 +349,11 @@ public interface HttpResponse<T> {
* BodySubscriber} and {@code Flow.Subscriber}.
*
* <p> For example:
* <pre> {@code TextSubscriber subscriber = ...; // accumulates bytes and transforms them into a String
* {@snippet :
* TextSubscriber subscriber = ...; // accumulates bytes and transforms them into a String
* HttpResponse<String> response = client.sendAsync(request,
* BodyHandlers.fromSubscriber(subscriber, TextSubscriber::getTextResult)).join();
* String text = response.body(); }</pre>
* String text = response.body(); }
*
* @param <S> the type of the Subscriber
* @param <T> the type of the response body
@ -380,7 +390,8 @@ public interface HttpResponse<T> {
* text line by line.
*
* <p> For example:
* <pre> {@code // A PrintSubscriber that implements Flow.Subscriber<String>
* {@snippet :
* // A PrintSubscriber that implements Flow.Subscriber<String>
* // and print lines received by onNext() on System.out
* PrintSubscriber subscriber = new PrintSubscriber(System.out);
* client.sendAsync(request, BodyHandlers.fromLineSubscriber(subscriber))
@ -389,7 +400,7 @@ public interface HttpResponse<T> {
* if (status != 200) {
* System.err.printf("ERROR: %d status received%n", status);
* }
* }); }</pre>
* }); }
*
* @param subscriber the subscriber
* @return a response body handler
@ -423,7 +434,8 @@ public interface HttpResponse<T> {
* text line by line.
*
* <p> For example:
* <pre> {@code // A LineParserSubscriber that implements Flow.Subscriber<String>
* {@snippet :
* // A LineParserSubscriber that implements Flow.Subscriber<String>
* // and accumulates lines that match a particular pattern
* Pattern pattern = ...;
* LineParserSubscriber subscriber = new LineParserSubscriber(pattern);
@ -431,7 +443,7 @@ public interface HttpResponse<T> {
* BodyHandlers.fromLineSubscriber(subscriber, s -> s.getMatchingLines(), "\n"));
* if (response.statusCode() != 200) {
* System.err.printf("ERROR: %d status received%n", response.statusCode());
* } }</pre>
* } }
*
*
* @param <S> the type of the Subscriber
@ -904,23 +916,26 @@ public interface HttpResponse<T> {
* to convert a flow of response body data into common high-level Java
* objects:
*
* <pre>{@code // Streams the response body to a File
* {@snippet :
* // Streams the response body to a File
* HttpResponse<Path> response = client
* .send(request, responseInfo -> BodySubscribers.ofFile(Paths.get("example.html"));
* .send(request, responseInfo -> BodySubscribers.ofFile(Paths.get("example.html")); }
*
* {@snippet :
* // Accumulates the response body and returns it as a byte[]
* HttpResponse<byte[]> response = client
* .send(request, responseInfo -> BodySubscribers.ofByteArray());
* .send(request, responseInfo -> BodySubscribers.ofByteArray()); }
*
* {@snippet :
* // Discards the response body
* HttpResponse<Void> response = client
* .send(request, responseInfo -> BodySubscribers.discarding());
* .send(request, responseInfo -> BodySubscribers.discarding()); }
*
* {@snippet :
* // Accumulates the response body as a String then maps it to its bytes
* HttpResponse<byte[]> response = client
* .send(request, responseInfo ->
* BodySubscribers.mapping(BodySubscribers.ofString(UTF_8), String::getBytes));
* }</pre>
* BodySubscribers.mapping(BodySubscribers.ofString(UTF_8), String::getBytes)); }
*
* @since 11
*/
@ -988,9 +1003,8 @@ public interface HttpResponse<T> {
* @apiNote This method can be used as an adapter between {@code
* BodySubscriber} and {@code Flow.Subscriber}.
*
* @implNote This is equivalent to calling <pre>{@code
* fromLineSubscriber(subscriber, s -> null, StandardCharsets.UTF_8, null)
* }</pre>
* @implNote This is equivalent to calling {@snippet :
* fromLineSubscriber(subscriber, s -> null, StandardCharsets.UTF_8, null) }
*
* @param subscriber the subscriber
* @return a body subscriber
@ -1330,7 +1344,8 @@ public interface HttpResponse<T> {
* convert an {@code InputStream} into any annotated Java type.
*
* <p>For example:
* <pre> {@code public static <W> BodySubscriber<Supplier<W>> asJSON(Class<W> targetType) {
* {@snippet :
* public static <W> BodySubscriber<Supplier<W>> asJSON(Class<W> targetType) {
* BodySubscriber<InputStream> upstream = BodySubscribers.ofInputStream();
*
* BodySubscriber<Supplier<W>> downstream = BodySubscribers.mapping(
@ -1344,7 +1359,7 @@ public interface HttpResponse<T> {
* }
* });
* return downstream;
* } }</pre>
* } }
*
* @param <T> the upstream body type
* @param <U> the type of the body subscriber returned

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -258,7 +258,8 @@ public interface WebSocket {
* Here is an example of a listener that requests invocations, one at a
* time, until a complete message has been accumulated, then processes
* the result, and completes the {@code CompletionStage}:
* <pre>{@code WebSocket.Listener listener = new WebSocket.Listener() {
* {@snippet :
* WebSocket.Listener listener = new WebSocket.Listener() {
*
* List<CharSequence> parts = new ArrayList<>();
* CompletableFuture<?> accumulatedMessage = new CompletableFuture<>();
@ -278,8 +279,7 @@ public interface WebSocket {
* }
* return accumulatedMessage;
* }
* ...
* } } </pre>
* }; }
*
* @since 11
*/
@ -292,7 +292,8 @@ public interface WebSocket {
* typically used to make a request for more invocations.
*
* @implSpec The default implementation is equivalent to:
* <pre>{@code webSocket.request(1); }</pre>
* {@snippet :
* webSocket.request(1); }
*
* @param webSocket
* the WebSocket that has been connected
@ -308,8 +309,9 @@ public interface WebSocket {
* this {@code CompletionStage} has completed.
*
* @implSpec The default implementation is equivalent to:
* <pre>{@code webSocket.request(1);
* return null; }</pre>
* {@snippet :
* webSocket.request(1);
* return null; }
*
* @implNote The {@code data} is always a legal UTF-16 sequence.
*
@ -343,8 +345,9 @@ public interface WebSocket {
* this {@code CompletionStage} has completed.
*
* @implSpec The default implementation is equivalent to:
* <pre>{@code webSocket.request(1);
* return null; }</pre>
* {@snippet :
* webSocket.request(1);
* return null; }
*
* @param webSocket
* the WebSocket on which the data has been received
@ -381,8 +384,9 @@ public interface WebSocket {
* this {@code CompletionStage} has completed.
*
* @implSpec The default implementation is equivalent to:
* <pre>{@code webSocket.request(1);
* return null; }</pre>
* {@snippet :
* webSocket.request(1);
* return null; }
*
* @param webSocket
* the WebSocket on which the message has been received
@ -412,8 +416,9 @@ public interface WebSocket {
* this {@code CompletionStage} has completed.
*
* @implSpec The default implementation is equivalent to:
* <pre>{@code webSocket.request(1);
* return null; }</pre>
* {@snippet :
* webSocket.request(1);
* return null; }
*
* @param webSocket
* the WebSocket on which the message has been received
@ -456,12 +461,13 @@ public interface WebSocket {
* <p> To specify a custom closure code or reason code the
* {@code sendClose} method may be invoked from inside the
* {@code onClose} invocation:
* <pre>{@code public CompletionStage<?> onClose(WebSocket webSocket,
* int statusCode,
* String reason) {
* {@snippet :
* public CompletionStage<?> onClose(WebSocket webSocket,
* int statusCode,
* String reason) {
* webSocket.sendClose(CUSTOM_STATUS_CODE, CUSTOM_REASON);
* return new CompletableFuture<Void>();
* } } </pre>
* } }
*
* @implSpec The default implementation of this method returns
* {@code null}, indicating that the output should be closed
@ -654,11 +660,13 @@ public interface WebSocket {
*
* @apiNote Use the provided integer constant {@link #NORMAL_CLOSURE} as a
* status code and an empty string as a reason in a typical case:
* <pre>{@code CompletableFuture<WebSocket> webSocket = ...
* webSocket.thenCompose(ws -> ws.sendText("Hello, ", false))
* {@snippet :
* CompletableFuture<WebSocket> webSocket = ...
* webSocket.thenCompose(ws -> ws.sendText("Hello, ", false))
* .thenCompose(ws -> ws.sendText("world!", true))
* .thenCompose(ws -> ws.sendClose(WebSocket.NORMAL_CLOSURE, ""))
* .join(); }</pre>
* .join();
* }
*
* The {@code sendClose} method does not close this WebSocket's input. It
* merely closes this WebSocket's output by sending a Close message. To
@ -666,7 +674,8 @@ public interface WebSocket {
* example of an application that sends a Close message, and then starts a
* timer. Once no data has been received within the specified timeout, the
* timer goes off and the alarm aborts {@code WebSocket}:
* <pre>{@code MyAlarm alarm = new MyAlarm(webSocket::abort);
* {@snippet :
* MyAlarm alarm = new MyAlarm(webSocket::abort);
* WebSocket.Listener listener = new WebSocket.Listener() {
*
* public CompletionStage<?> onText(WebSocket webSocket,
@ -682,8 +691,7 @@ public interface WebSocket {
* MyTimer idleTimer = new MyTimer();
* idleTimer.add(alarm, 30, TimeUnit.SECONDS);
* };
* webSocket.sendClose(WebSocket.NORMAL_CLOSURE, "ok").thenRun(startTimer);
* } </pre>
* webSocket.sendClose(WebSocket.NORMAL_CLOSURE, "ok").thenRun(startTimer); }
*
* @param statusCode
* the status code
@ -717,7 +725,8 @@ public interface WebSocket {
* <p> Here is an example of a listener that requests invocations, one at a
* time, until a complete message has been accumulated, and then processes
* the result:
* <pre>{@code WebSocket.Listener listener = new WebSocket.Listener() {
* {@snippet :
* WebSocket.Listener listener = new WebSocket.Listener() {
*
* StringBuilder text = new StringBuilder();
*
@ -732,8 +741,7 @@ public interface WebSocket {
* webSocket.request(1);
* return null;
* }
* ...
* } } </pre>
* }; }
*
* @param n
* the number of invocations