---

# (DD03) Business Logic — Example.http2() [19 LOC]

| Field | Value |
|-------|-------|
| Fully Qualified Name | `io.github.biezhi.java11.http.Example` |
| Layer | Utility / Demo |
| Module | `http` (Package: `io.github.biezhi.java11.http`) |

## 1. Role

### Example.http2()

This method demonstrates how to use the Java 11 `HttpClient` API to perform an **asynchronous HTTP/2 request** to an external endpoint (Akamai's HTTP/2 demo page). It builds an HTTP client configured to follow normal redirects and use the HTTP/2 protocol version, constructs an HTTP GET request targeting `https://http2.akamai.com/demo`, and dispatches it asynchronously using `sendAsync`. A `whenComplete` callback is registered to handle both success and failure scenarios — printing the response body and status code on success, or printing the stack trace on error. The method blocks on `join()` to wait for the asynchronous operation to complete before returning. This is a **self-contained demo utility** with no callers within the codebase, serving as a learning example for Java 11's reactive HTTP client API. The Chinese comment "访问 HTTP2 地址" translates to "access HTTP2 address".

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START(["http2"])
    CLIENT_BUILDER["HttpClient.newBuilder"]
    FOLLOW_REDIRECT["followRedirects NORMAL"]
    SET_VERSION["version HTTP_2"]
    CLIENT_BUILD["build produces HttpClient"]
    REQUEST_NEW["HttpRequest.newBuilder"]
    URI_CREATE["new URI target"]
    SET_URI["uri set target URI"]
    SET_METHOD["GET set method"]
    REQUEST_BUILD["build produces HttpRequest"]
    SEND_ASYNC["sendAsync request async"]
    WHEN_COMPLETE["whenComplete callback"]
    CHECK_ERROR["t is null"]
    ERROR_HANDLE["t.printStackTrace"]
    SUCCESS_HANDLE["print resp body and status"]
    JOIN_CALL["join wait completion"]
    END_NODE(["Return"])

    START --> CLIENT_BUILDER
    CLIENT_BUILDER --> FOLLOW_REDIRECT
    FOLLOW_REDIRECT --> SET_VERSION
    SET_VERSION --> CLIENT_BUILD
    CLIENT_BUILD --> REQUEST_NEW
    REQUEST_NEW --> URI_CREATE
    URI_CREATE --> SET_URI
    SET_URI --> SET_METHOD
    SET_METHOD --> REQUEST_BUILD
    REQUEST_BUILD --> SEND_ASYNC
    SEND_ASYNC --> WHEN_COMPLETE
    WHEN_COMPLETE --> CHECK_ERROR
    CHECK_ERROR -->|true| ERROR_HANDLE
    CHECK_ERROR -->|false| SUCCESS_HANDLE
    ERROR_HANDLE --> END_NODE
    SUCCESS_HANDLE --> JOIN_CALL
    JOIN_CALL --> END_NODE
```

**Processing Summary:**

1. **Client Construction Phase**: `HttpClient.newBuilder()` initiates a fluent builder chain. `followRedirects(NORMAL)` configures the client to follow normal (same-origin) redirects but not cross-protocol redirects. `version(HTTP_2)` requests the HTTP/2 protocol version. `build()` materializes the `HttpClient` instance.

2. **Request Construction Phase**: `HttpRequest.newBuilder()` starts a new HTTP request builder. `uri(new URI("https://http2.akamai.com/demo"))` sets the target URI to Akamai's HTTP/2 demo page. `GET()` sets the HTTP method to GET. `build()` materializes the `HttpRequest` instance.

3. **Async Dispatch Phase**: `sendAsync(request, HttpResponse.BodyHandlers.ofString())` dispatches the request asynchronously, returning a `CompletableFuture<HttpResponse<String>>`. The response body is handled as a String via `BodyHandlers.ofString()`.

4. **Completion Handler Phase**: `whenComplete((resp, t) -> { ... })` registers a BiConsumer callback that runs when the async operation completes — whether successfully or with an error. If `t` (the throwable) is non-null, the error is printed via `printStackTrace()`. Otherwise, the response body and status code are printed to `System.out`.

5. **Wait Phase**: `join()` blocks the calling thread until the async operation completes, ensuring the method does not return before the response is processed.

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|---------------------|
| - | (none) | - | This method takes no parameters. It uses a hardcoded target URI. |

**External State Read:**
None — this method is entirely stateless and self-contained. It does not reference any instance fields or rely on external configuration.

## 4. CRUD Operations / Called Services

This method does **not perform any CRUD operations**. It is a pure HTTP client demo that communicates with an external web service (Akamai). All method calls are part of the Java 11 `java.net.http` standard library API.

| # | Type | Description |
|---|------|-------------|
| 1 | HTTP GET | Asynchronous HTTP GET request to `https://http2.akamai.com/demo` |

## 5. Dependency Trace

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | N/A (Demo entry point) | Standalone demo method — no callers found in codebase | HTTP GET `https://http2.akamai.com/demo` |

**Note:** This method is a self-contained demo/utility with no callers within the codebase. The Chinese comment "访问 HTTP2 地址" ("access HTTP2 address") indicates its purpose as a demonstration of Java 11's HTTP/2 capabilities.

## 6. Per-Branch Detail Blocks

### Block 1 — [STATIC METHOD ENTRY] (L154)

> Entry point of the static method. Declares `throws Exception` to propagate any IOException, URISyntaxException, or other I/O errors that may occur during client construction or request execution.

| # | Type | Code |
|---|------|------|
| 1 | ENTRY | `public static void http2() throws Exception` |
| 2 | SET | `HttpClient.Builder builder = HttpClient.newBuilder()` — initiate client builder [-> Java 11 HttpClient.Builder] |
| 3 | EXEC | `followRedirects(HttpClient.Redirect.NORMAL)` — set redirect policy to normal [-> follows same-origin redirects only] |
| 4 | EXEC | `version(HttpClient.Version.HTTP_2)` — request HTTP/2 protocol version [-> forces HTTP/2 when server supports it] |
| 5 | CALL | `build()` — materializes `HttpClient` instance [-> Java 11 default executor, no proxy, insecure HTTPS disabled] |

### Block 2 — [REQUEST BUILDER CHAIN] (L157-161)

> Constructs an HTTP GET request targeting the Akamai HTTP/2 demo page. Uses fluent builder pattern on `HttpRequest.Builder`.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `HttpRequest.newBuilder()` — initiate request builder |
| 2 | SET | `uri(new URI("https://http2.akamai.com/demo"))` — set target URI [-> hardcoded demo endpoint] |
| 3 | EXEC | `GET()` — set HTTP method to GET |
| 4 | CALL | `build()` — materializes `HttpRequest` instance [-> immutable request object] |

### Block 3 — [ASYNC DISPATCH] (L162)

> Dispatches the HTTP request asynchronously and registers a completion callback.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `.sendAsync(request, HttpResponse.BodyHandlers.ofString())` — dispatches async request [-> returns CompletableFuture<HttpResponse<String>>] |

### Block 4 — [COMPLETION CALLBACK — WHENCLOSE] (L163)

> `whenComplete` callback executed upon async operation completion (success or error). This is a non-branching handler that covers both outcomes.

| # | Type | Code |
|---|------|------|
| 1 | SET | Lambda `(resp, t) -> { if (t != null) { ... } else { ... } }` — BiConsumer for response and throwable |

#### Block 4.1 — [ERROR BRANCH] `t != null` (L164)

> When the async operation failed with an exception (e.g., network error, DNS failure, timeout), print the stack trace.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `t.printStackTrace()` — print error stack trace to stderr |

#### Block 4.2 — [SUCCESS BRANCH] `t == null` (L165-167)

> When the async operation succeeded, print the response body and HTTP status code to stdout.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `System.out.println(resp.body())` — print response body (String) |
| 2 | EXEC | `System.out.println(resp.statusCode())` — print HTTP status code (int) |

### Block 5 — [WAIT PHASE] (L168)

> Blocks the calling thread until the async operation completes.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `.join()` — blocks until `CompletableFuture` completes [-> throws unchecked exception if operation failed] |

### Block 6 — [METHOD EXIT] (L169)

> Method returns void. No return value to propagate.

| # | Type | Code |
|---|------|------|
| 1 | RETURN | `}` — end of method (void return) |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `HttpClient` | Class | Java 11 HTTP Client — the primary API for making HTTP/1.1 and HTTP/2 requests, introduced in `java.net.http` package |
| `HttpRequest` | Class | Java 11 HTTP Request — represents an immutable HTTP request with method, URI, headers, and body |
| `HttpResponse` | Class | Java 11 HTTP Response — represents the response from an HTTP request, including status code, headers, and body |
| `HTTP_2` | Protocol | HTTP/2 — the second major version of the HTTP protocol, providing multiplexing, header compression, and server push |
| `Redirect.NORMAL` | Enum | HTTP redirect policy — follow redirects only for the same protocol and host (not cross-protocol or cross-host) |
| `sendAsync` | Method | Asynchronous send — dispatches an HTTP request without blocking the calling thread; returns a `CompletableFuture` |
| `whenComplete` | Method | Callback registration — registers a handler that runs when the async operation completes, whether successfully or with an error |
| `join` | Method | Blocks until async result is available — similar to `get()` but throws unchecked exceptions instead of checked ones |
| `BodyHandlers.ofString` | Handler | Response body handler that collects the entire response body into a String |
| `new URI(...)` | API | Java URI constructor — parses and validates a Uniform Resource Identifier string |
| Akamai | External service | CDN and cloud service provider — `http2.akamai.com/demo` is Akamai's public HTTP/2 demo page used to verify HTTP/2 support |

---
