Path: blob/master/test/jdk/java/net/httpclient/BodyProcessorInputStreamTest.java
41149 views
/*1* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import java.io.InputStream;24import java.io.InputStreamReader;25import java.io.Reader;26import java.net.URI;27import java.net.http.HttpClient;28import java.net.http.HttpHeaders;29import java.net.http.HttpRequest;30import java.net.http.HttpResponse;31import java.net.http.HttpResponse.BodyHandlers;32import java.nio.charset.Charset;33import java.util.Locale;34import java.util.Optional;35import java.util.concurrent.CompletableFuture;36import java.util.stream.Stream;37import static java.lang.System.err;3839/*40* @test41* @bug 818750342* @summary An example on how to read a response body with InputStream.43* @run main/othervm/manual -Dtest.debug=true BodyProcessorInputStreamTest44* @author daniel fuchs45*/46public class BodyProcessorInputStreamTest {4748public static boolean DEBUG = Boolean.getBoolean("test.debug");4950/**51* Examine the response headers to figure out the charset used to52* encode the body content.53* If the content type is not textual, returns an empty Optional.54* Otherwise, returns the body content's charset, defaulting to55* ISO-8859-1 if none is explicitly specified.56* @param headers The response headers.57* @return The charset to use for decoding the response body, if58* the response body content is text/...59*/60public static Optional<Charset> getCharset(HttpHeaders headers) {61Optional<String> contentType = headers.firstValue("Content-Type");62Optional<Charset> charset = Optional.empty();63if (contentType.isPresent()) {64final String[] values = contentType.get().split(";");65if (values[0].startsWith("text/")) {66charset = Optional.of(Stream.of(values)67.map(x -> x.toLowerCase(Locale.ROOT))68.map(String::trim)69.filter(x -> x.startsWith("charset="))70.map(x -> x.substring("charset=".length()))71.findFirst()72.orElse("ISO-8859-1"))73.map(Charset::forName);74}75}76return charset;77}7879public static void main(String[] args) throws Exception {80HttpClient client = HttpClient.newHttpClient();81HttpRequest request = HttpRequest82.newBuilder(new URI("http://hg.openjdk.java.net/jdk9/sandbox/jdk/shortlog/http-client-branch/"))83.GET()84.build();8586// This example shows how to return an InputStream that can be used to87// start reading the response body before the response is fully received.88// In comparison, the snipet below (which uses89// HttpResponse.BodyHandlers.ofString()) obviously will not return before the90// response body is fully read:91//92// System.out.println(93// client.sendAsync(request, HttpResponse.BodyHandlers.ofString()).get().body());9495CompletableFuture<HttpResponse<InputStream>> handle =96client.sendAsync(request, BodyHandlers.ofInputStream());97if (DEBUG) err.println("Request sent");9899HttpResponse<InputStream> pending = handle.get();100101// At this point, the response headers have been received, but the102// response body may not have arrived yet. This comes from103// the implementation of HttpResponseInputStream::getBody above,104// which returns an already completed completion stage, without105// waiting for any data.106// We can therefore access the headers - and the body, which107// is our live InputStream, without waiting...108HttpHeaders responseHeaders = pending.headers();109110// Get the charset declared in the response headers.111// The optional will be empty if the content type is not112// of type text/...113Optional<Charset> charset = getCharset(responseHeaders);114115try (InputStream is = pending.body();116// We assume a textual content type. Construct an InputStream117// Reader with the appropriate Charset.118// charset.get() will throw NPE if the content is not textual.119Reader r = new InputStreamReader(is, charset.get())) {120121char[] buff = new char[32];122int off=0, n=0;123if (DEBUG) err.println("Start receiving response body");124if (DEBUG) err.println("Charset: " + charset.get());125126// Start consuming the InputStream as the data arrives.127// Will block until there is something to read...128while ((n = r.read(buff, off, buff.length - off)) > 0) {129assert (buff.length - off) > 0;130assert n <= (buff.length - off);131if (n == (buff.length - off)) {132System.out.print(buff);133off = 0;134} else {135off += n;136}137assert off < buff.length;138}139140// last call to read may not have filled 'buff' completely.141// flush out the remaining characters.142assert off >= 0 && off < buff.length;143for (int i=0; i < off; i++) {144System.out.print(buff[i]);145}146147// We're done!148System.out.println("Done!");149}150}151152}153154155