1 /* 2 * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 import java.io.IOException; 25 import java.io.InputStream; 26 import java.io.PrintStream; 27 import java.net.Authenticator; 28 import java.net.InetSocketAddress; 29 import java.net.ProxySelector; 30 import java.net.URI; 31 import java.net.http.HttpClient; 32 import java.net.http.HttpClient.Redirect; 33 import java.net.http.HttpClient.Version; 34 import java.net.http.HttpRequest; 35 import java.net.http.HttpRequest.BodyPublishers; 36 import java.net.http.HttpResponse; 37 import java.net.http.HttpResponse.BodyHandler; 38 import java.net.http.HttpResponse.BodyHandlers; 39 import java.net.http.HttpResponse.BodySubscribers; 40 import java.nio.file.Path; 41 import java.nio.file.Paths; 42 import java.time.Duration; 43 import java.util.Collections; 44 import java.util.List; 45 import java.util.concurrent.CopyOnWriteArrayList; 46 import java.util.concurrent.Flow; 47 import java.util.regex.Pattern; 48 import static java.nio.charset.StandardCharsets.UTF_8; 49 50 /* 51 * THE CONTENTS OF THIS FILE HAVE TO BE IN SYNC WITH THE EXAMPLES USED IN THE 52 * JAVADOC. 53 * 54 * @test 55 * @compile JavadocExamples.java 56 */ 57 public class JavadocExamples { 58 HttpRequest request = null; 59 HttpClient client = null; 60 Pattern p = null; 61 62 void fromHttpClientClasslevelDescription() throws Exception { 63 //Synchronous Example 64 HttpClient client = HttpClient.newBuilder() 65 .version(Version.HTTP_1_1) 66 .followRedirects(Redirect.NORMAL) 67 .proxy(ProxySelector.of(new InetSocketAddress("proxy.example.com", 80))) 68 .authenticator(Authenticator.getDefault()) 69 .build(); 70 HttpResponse<String> response = client.send(request, BodyHandlers.ofString()); 71 System.out.println(response.statusCode()); 72 System.out.println(response.body()); 73 74 //Asynchronous Example 75 HttpRequest request = HttpRequest.newBuilder() 76 .uri(URI.create("https://foo.com/")) 77 .timeout(Duration.ofMinutes(1)) 78 .header("Content-Type", "application/json") 79 .POST(BodyPublishers.ofFile(Paths.get("file.json"))) 80 .build(); 81 client.sendAsync(request, BodyHandlers.ofString()) 82 .thenApply(HttpResponse::body) 83 .thenAccept(System.out::println); 84 } 85 86 void fromHttpRequest() throws Exception { 87 // HttpRequest class-level description 88 HttpClient client = HttpClient.newHttpClient(); 89 HttpRequest request = HttpRequest.newBuilder() 90 .uri(URI.create("http://foo.com/")) 91 .build(); 92 client.sendAsync(request, BodyHandlers.ofString()) 93 .thenApply(HttpResponse::body) 94 .thenAccept(System.out::println) 95 .join(); 96 97 // HttpRequest.BodyPublishers class-level description 98 // Request body from a String 99 HttpRequest request1 = HttpRequest.newBuilder() 100 .uri(URI.create("https://foo.com/")) 101 .header("Content-Type", "text/plain; charset=UTF-8") 102 .POST(BodyPublishers.ofString("some body text")) 103 .build(); 104 105 // Request body from a File 106 HttpRequest request2 = HttpRequest.newBuilder() 107 .uri(URI.create("https://foo.com/")) 108 .header("Content-Type", "application/json") 109 .POST(BodyPublishers.ofFile(Paths.get("file.json"))) 110 .build(); 111 112 // Request body from a byte array 113 HttpRequest request3 = HttpRequest.newBuilder() 114 .uri(URI.create("https://foo.com/")) 115 .POST(BodyPublishers.ofByteArray(new byte[] { /*...*/ })) 116 .build(); 117 } 118 119 void fromHttpResponse() throws Exception { 120 // HttpResponse class-level description 121 HttpResponse<String> response = client 122 .send(request, BodyHandlers.ofString()); 123 124 // HttpResponse.BodyHandler class-level description 125 HttpRequest request = HttpRequest.newBuilder() 126 .uri(URI.create("http://www.foo.com/")) 127 .build(); 128 client.sendAsync(request, BodyHandlers.ofFile(Paths.get("/tmp/f"))) 129 .thenApply(HttpResponse::body) 130 .thenAccept(System.out::println); 131 132 HttpRequest request1 = HttpRequest.newBuilder() 133 .uri(URI.create("http://www.foo.com/")) 134 .build(); 135 BodyHandler<Path> bodyHandler = (info) -> info.statusCode() == 200 136 ? BodySubscribers.ofFile(Paths.get("/tmp/f")) 137 : BodySubscribers.replacing(Paths.get("/NULL")); 138 client.sendAsync(request, bodyHandler) 139 .thenApply(HttpResponse::body) 140 .thenAccept(System.out::println); 141 142 143 // HttpResponse.BodyHandlers class-level description 144 // Receives the response body as a String 145 HttpResponse<String> response1 = client 146 .send(request, BodyHandlers.ofString()); 147 148 // Receives the response body as a file 149 HttpResponse<Path> response2 = client 150 .send(request, BodyHandlers.ofFile(Paths.get("example.html"))); 151 152 // Receives the response body as an InputStream 153 HttpResponse<InputStream> respons3 = client 154 .send(request, BodyHandlers.ofInputStream()); 155 156 // Discards the response body 157 HttpResponse<Void> respons4 = client 158 .send(request, BodyHandlers.discarding()); 159 160 161 // HttpResponse.BodySubscribers class-level description 162 // Streams the response body to a File 163 HttpResponse<byte[]> response5 = client 164 .send(request, responseInfo -> BodySubscribers.ofByteArray()); 165 166 // Accumulates the response body and returns it as a byte[] 167 HttpResponse<byte[]> response6 = client 168 .send(request, responseInfo -> BodySubscribers.ofByteArray()); 169 170 // Discards the response body 171 HttpResponse<Void> response7 = client 172 .send(request, responseInfo -> BodySubscribers.discarding()); 173 174 // Accumulates the response body as a String then maps it to its bytes 175 HttpResponse<byte[]> response8 = client 176 .send(request, responseInfo -> 177 BodySubscribers.mapping(BodySubscribers.ofString(UTF_8), String::getBytes)); 178 179 } 180 181 /** 182 * @apiNote This method can be used as an adapter between a {@code 183 * BodySubscriber} and a text based {@code Flow.Subscriber} that parses 184 * text line by line. 185 * 186 * <p> For example: 187 * <pre> {@code // A PrintSubscriber that implements Flow.Subscriber<String> 188 * // and print lines received by onNext() on System.out 189 * PrintSubscriber subscriber = new PrintSubscriber(System.out); 190 * client.sendAsync(request, BodyHandlers.fromLineSubscriber(subscriber)) 191 * .thenApply(HttpResponse::statusCode) 192 * .thenAccept((status) -> { 193 * if (status != 200) { 194 * System.err.printf("ERROR: %d status received%n", status); 195 * } 196 * }); }</pre> 197 */ 198 void fromLineSubscriber1() { 199 // A PrintSubscriber that implements Flow.Subscriber<String> 200 // and print lines received by onNext() on System.out 201 PrintSubscriber subscriber = new PrintSubscriber(System.out); 202 client.sendAsync(request, BodyHandlers.fromLineSubscriber(subscriber)) 203 .thenApply(HttpResponse::statusCode) 204 .thenAccept((status) -> { 205 if (status != 200) { 206 System.err.printf("ERROR: %d status received%n", status); 207 } 208 }); 209 } 210 211 /** 212 * @apiNote This method can be used as an adapter between a {@code 213 * BodySubscriber} and a text based {@code Flow.Subscriber} that parses 214 * text line by line. 215 * 216 * <p> For example: 217 * <pre> {@code // A LineParserSubscriber that implements Flow.Subscriber<String> 218 * // and accumulates lines that match a particular pattern 219 * Pattern pattern = ...; 220 * LineParserSubscriber subscriber = new LineParserSubscriber(pattern); 221 * HttpResponse<List<String>> response = client.send(request, 222 * BodyHandlers.fromLineSubscriber(subscriber, s -> s.getMatchingLines(), "\n")); 223 * if (response.statusCode() != 200) { 224 * System.err.printf("ERROR: %d status received%n", response.statusCode()); 225 * } }</pre> 226 * 227 */ 228 void fromLineSubscriber2() throws IOException, InterruptedException { 229 // A LineParserSubscriber that implements Flow.Subscriber<String> 230 // and accumulates lines that match a particular pattern 231 Pattern pattern = p; 232 LineParserSubscriber subscriber = new LineParserSubscriber(pattern); 233 HttpResponse<List<String>> response = client.send(request, 234 BodyHandlers.fromLineSubscriber(subscriber, s -> s.getMatchingLines(), "\n")); 235 if (response.statusCode() != 200) { 236 System.err.printf("ERROR: %d status received%n", response.statusCode()); 237 } 238 } 239 240 static final class PrintSubscriber implements Flow.Subscriber<String> { 241 final PrintStream out; 242 PrintSubscriber(PrintStream out) { 243 this.out = out; 244 } 245 @Override 246 public void onSubscribe(Flow.Subscription subscription) { 247 subscription.request(Long.MAX_VALUE); 248 } 249 @Override 250 public void onNext(String item) { 251 out.println(item); 252 } 253 254 @Override 255 public void onError(Throwable throwable) { 256 throwable.printStackTrace(); 257 } 258 @Override 259 public void onComplete() { 260 } 261 } 262 263 static final class LineParserSubscriber implements Flow.Subscriber<String> { 264 final Pattern pattern; 265 final CopyOnWriteArrayList<String> matches = new CopyOnWriteArrayList<>(); 266 LineParserSubscriber(Pattern pattern) { 267 this.pattern = pattern; 268 } 269 @Override 270 public void onSubscribe(Flow.Subscription subscription) { 271 subscription.request(Long.MAX_VALUE); 272 } 273 @Override 274 public void onNext(String item) { 275 if (pattern.matcher(item).matches()) { 276 matches.add(item); 277 } 278 } 279 @Override 280 public void onError(Throwable throwable) { 281 throwable.printStackTrace(); 282 } 283 @Override 284 public void onComplete() { 285 } 286 287 public List<String> getMatchingLines() { 288 return Collections.unmodifiableList(matches); 289 } 290 } 291 292 }