# Io / Github / Biezhi / Java11 / Http

## Overview

This package appears to be a compact set of Java 11 `HttpClient` examples. It demonstrates the main request patterns engineers need when working with the JDK HTTP client: synchronous and asynchronous GET/POST calls, file upload and download, proxy configuration, basic authentication, HTTP/2, and simple parallel request fan-out.

The module exists as a learning and reference aid rather than as a reusable service layer. The code is intentionally direct and imperative so each example shows one HTTP client capability in isolation.

## Key Classes and Interfaces

### [Example](java11-examples-master/src/main/java/io/github/biezhi/java11/http/Example.java:26)

`Example` is the main demonstration class for the package. Almost every method in the class showcases one `HttpClient` feature, so it acts as the entry point for understanding how the JDK 11 HTTP API is used in practice.

Key responsibilities:

- build `HttpClient` and `HttpRequest` instances
- execute requests synchronously and asynchronously
- print response status codes and bodies
- show how to send JSON, stream files, use proxies, and authenticate
- demonstrate HTTP/2 and parallel request execution

Important methods:

- `syncGet(String uri)` — builds a default client, sends a blocking GET request, and prints the response status and body. It takes a URI string and returns `void`, but it throws `Exception` if request creation or execution fails.
- `asyncGet(String uri)` — performs the same GET request asynchronously using `sendAsync`. It registers a `whenComplete` callback that prints either the exception stack trace or the response body and status, then blocks on `join()` so the example does not exit early.
- `asyncPost()` — creates a `Foo`, serializes it with Gson to JSON, and posts it to `https://httpbin.org/post`. This method demonstrates how the HTTP client sends a JSON payload via `BodyPublishers.ofString` and how a content type header is attached.
- `downloadFile()` — sends a GET request to `https://labs.consol.de/` and writes the body to a temporary file using `BodyHandlers.ofFile`. It prints the HTTP status and the resulting file path.
- `uploadFile()` — posts a local file from `/tmp/files-to-upload.txt` to `http://localhost:8080/upload/` using `BodyPublishers.ofFile`, then prints the response status. This is the package's upload example.
- `proxy()` — creates a client with a proxy selector pointing at `127.0.0.1:1080`, then sends a GET request through that proxy.
- `basicAuth()` — configures an `Authenticator` that always returns the hard-coded username and password `username` / `password`, then sends a GET request to `https://labs.consol.de`.
- `http2()` — builds a client configured for HTTP/2 and normal redirects, then asynchronously requests `https://http2.akamai.com/demo`. This method is a focused example of version negotiation and redirect behavior.
- `getURIs(List<URI> uris)` — creates requests from a list of URIs and launches them all asynchronously, then waits for every future to complete with `CompletableFuture.allOf(...).join()`. It does not inspect response bodies; the purpose is to show concurrent request fan-out.
- `main(String[] args)` — currently calls `asyncPost()` and leaves the other examples commented out. In other words, the runnable demo currently exercises the JSON POST path by default.

Design notes:

- The class keeps each example self-contained. Every method creates its own client rather than sharing one globally.
- Methods print directly to standard output instead of returning structured values. That makes the code easy to read but less reusable in production code.
- Several methods use hard-coded external endpoints. That is fine for documentation and demo purposes, but it means the examples depend on network access and the target servers being available.

### [Foo](java11-examples-master/src/main/java/io/github/biezhi/java11/http/Foo.java:7)

`Foo` is a minimal data holder used by `asyncPost()` as the JSON request body.

Fields:

- `name`
- `url`

Both fields are package-private and unannotated, which matches the example style: Gson serializes the object directly without any additional mapping layer. The class has no methods and no behavior of its own; it exists only to provide a simple object graph for JSON serialization.

## How It Works

### Synchronous GET flow

1. `syncGet(String uri)` creates a default `HttpClient`.
2. It builds an `HttpRequest` from the provided URI.
3. `client.send(...)` performs the request synchronously.
4. The method prints the response status code and body.

This is the simplest possible `HttpClient` usage pattern and is useful when a calling thread can afford to block.

### Asynchronous GET and POST flow

`asyncGet(String uri)` and `asyncPost()` follow the same overall shape:

1. Build an `HttpClient`.
2. Build an `HttpRequest`.
3. Call `sendAsync(...)` with `HttpResponse.BodyHandlers.ofString()`.
4. Register a `whenComplete` callback.
5. Use `join()` so the example waits for completion.

The callback prints either the exception or the response payload plus status. The use of `join()` means the example is still easy to run from `main`, but the asynchronous API is visible in the code.

### JSON POST flow

`asyncPost()` adds one extra step before the request is sent:

1. Instantiate `Foo`.
2. Set `foo.name` and `foo.url`.
3. Serialize the object with Gson.
4. Send the resulting JSON string as the request body.
5. Add `Content-Type: application/json`.

That makes the method a practical template for sending typed payloads to a JSON API.

### File transfer flow

The module contains both directions of file transfer:

- `downloadFile()` uses `BodyHandlers.ofFile(tempFile)` to stream the response body into a temporary file path created by `Files.createTempFile(...)`.
- `uploadFile()` uses `BodyPublishers.ofFile(Paths.get("/tmp/files-to-upload.txt"))` to stream a local file in the request body.

These examples are important because they show that the JDK client can work with files without manually buffering everything in memory.

### Proxy, authentication, and HTTP/2

The remaining methods show client configuration rather than request shape:

- `proxy()` configures a `ProxySelector` with a local SOCKS or HTTP proxy address.
- `basicAuth()` supplies an `Authenticator` so the client can respond to server authentication challenges.
- `http2()` selects `HttpClient.Version.HTTP_2` and normal redirect handling, then performs an async GET.

Each of these methods illustrates a different builder option on `HttpClient.newBuilder()`.

### Parallel request fan-out

`getURIs(List<URI> uris)` transforms a list of URIs into a list of `HttpRequest` objects, then starts an async request for each one. `CompletableFuture.allOf(...)` is used to wait for all of them to finish.

This method is the package's concurrency example. It shows how the client can be used for batch retrieval without manually managing threads.

## Data Model

There is only one model class in this package:

- `Foo` — a tiny request payload with `name` and `url` fields

It exists solely to demonstrate JSON serialization in `asyncPost()`. There are no DTO hierarchies, no persistence entities, and no validation rules in this package.

## Dependencies and Integration

### JDK APIs

The package uses standard Java 11 APIs from `java.net.http`:

- `HttpClient`
- `HttpRequest`
- `HttpResponse`
- `HttpClient.BodyHandlers`
- `HttpRequest.BodyPublishers`

It also uses supporting JDK types such as `URI`, `Path`, `Files`, `Paths`, `ProxySelector`, `InetSocketAddress`, `Authenticator`, `PasswordAuthentication`, and `CompletableFuture`.

### External library

`Example` imports `com.google.gson.Gson` to serialize `Foo` into JSON for the POST example.

### External endpoints

The examples are wired to concrete URLs:

- `https://biezhi.me`
- `https://httpbin.org/post`
- `https://labs.consol.de/`
- `http://localhost:8080/upload/`
- `https://www.google.com`
- `https://http2.akamai.com/demo`

Because of this, the examples are only fully runnable in an environment with network access and, for upload, a local server plus a file at `/tmp/files-to-upload.txt`.

## Notes for Developers

- Most methods throw `Exception` rather than handling checked failures locally. That keeps the examples short but is not a production error-handling strategy.
- The code prints directly to standard output. If you adapt it for an application, consider returning values or using a logger instead.
- `main(String[] args)` currently has only `asyncPost()` enabled. Uncomment the other calls to exercise the other scenarios one at a time.
- `getURIs(List<URI> uris)` builds requests from URIs but does not process the responses. If you need results, extend the method to inspect each returned `HttpResponse` rather than only waiting for completion.
- `basicAuth()` uses fixed credentials in code. Replace them with secure configuration if you reuse the pattern elsewhere.
- `proxy()` assumes a local proxy at port `1080`. Adjust the address to match the environment you run in.

## Relationships

```mermaid
flowchart LR
A["Example"] --> B["syncGet"]
A["Example"] --> C["asyncGet"]
A["Example"] --> D["asyncPost"]
A["Example"] --> E["downloadFile"]
A["Example"] --> F["uploadFile"]
A["Example"] --> G["proxy"]
A["Example"] --> H["basicAuth"]
A["Example"] --> I["http2"]
A["Example"] --> J["getURIs"]
D["asyncPost"] --> K["Foo"]
```

The diagram above highlights the package's central role: `Example` contains the HTTP demonstrations, and `Foo` is the only supporting data object used for JSON serialization.
