# (DD01) Business Logic — Example.asyncPost() [25 LOC]

| Field | Value |
|-------|-------|
| Fully Qualified Name | `io.github.biezhi.java11.http.Example` |
| Layer | Utility (Example — Java 11 HttpClient demonstration code) |
| Module | `http` (Package: `io.github.biezhi.java11.http`) |

## 1. Role

### Example.asyncPost()

This method demonstrates an asynchronous POST HTTP request using Java 11's `HttpClient` API (non-blocking, reactive-style). It constructs an HTTP client, creates a `Foo` payload object containing a name (`王爵nice` / "Wang Jue nice") and a GitHub URL, serializes it to JSON via Gson, and sends the JSON body as a POST request to `https://httpbin.org/post` — a public test endpoint that echoes back received requests. The method implements the **asynchronous dispatch pattern** using `CompletableFuture`, where the HTTP call is initiated via `sendAsync()` and a `whenComplete` callback handles both success (printing the response body and status code) and failure (printing the stack trace). It plays the role of a **self-contained usage example** within an open-source Java 11 HTTP client demo project, serving as a reference implementation for developers learning the new `java.net.http` package. The method is callable directly from `main()` as the active demo call (other example methods are commented out).

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START(["asyncPost()"])

    START --> STEP1["Create HttpClient
(newHttpClient)"]
    STEP1 --> STEP2["Create Gson instance"]
    STEP2 --> STEP3["Create Foo object
name='王爵nice'
url='https://github.com/biezhi'"]
    STEP3 --> STEP4["Serialize Foo to JSON
(gson.toJson(foo))"]
    STEP4 --> STEP5["Build HttpRequest POST
URI: https://httpbin.org/post
Body: JSON string
Content-Type: application/json"]
    STEP5 --> STEP6["Send async HTTP request
(client.sendAsync)"]
    STEP6 --> WHENCOMPLETE["whenComplete callback registered"]
    WHENCOMPLETE --> CHECKERROR{"t != null?
(Error check)"}
    CHECKERROR -->|true| PRINTSTACK["Print stack trace
(t.printStackTrace())"]
    CHECKERROR -->|false| PRINTRESP["Print response body
and status code
(resp.body(),
 resp.statusCode())"]
    PRINTSTACK --> ASYNCJOIN["Join async future
(.join())"]
    PRINTRESP --> ASYNCJOIN
    ASYNCJOIN --> END_RETURN(["Return void"])
```

**Note:** This method has no conditional branches in its core flow. The only conditional element is the `whenComplete` callback's error check, which branches on whether the async request threw an exception (`t != null`) or succeeded (a response object is available).

**Processing Steps Summary:**

| Step | Action | API / Code | Business Meaning |
|------|--------|------------|-----------------|
| 1 | Create HTTP client | `HttpClient.newHttpClient()` | Initializes a non-blocking HTTP client for the request |
| 2 | Create Gson instance | `new Gson()` | Creates a JSON serializer for the payload |
| 3 | Construct Foo object | `new Foo(); foo.name = ...; foo.url = ...` | Builds a payload object with user name and URL |
| 4 | Serialize to JSON | `gson.toJson(foo)` | Converts the Java object to a JSON string body |
| 5 | Build HTTP request | `HttpRequest.newBuilder()...build()` | Constructs a POST request targeting httpbin.org/post |
| 6 | Send async request | `client.sendAsync(...)` | Dispatches the request without blocking the calling thread |
| 7 | Error handling | `whenComplete((resp, t) -> ...)` | Callback branch: prints stack trace on error, or response body and status code on success |
| 8 | Wait for completion | `.join()` | Blocks the main thread until the async request finishes |

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|---------------------|
| - | (none) | - | This method takes no parameters. All data is internally constructed. |
| - | (implicit) | `HttpClient` (local) | Non-blocking HTTP client used to send the async POST request |
| - | (implicit) | `Gson` (local) | JSON serialization engine for the payload object |
| - | (implicit) | `Foo` (local) | Payload object containing `name` (user display name) and `url` (profile URL) fields |

**No instance fields are read** — the method is entirely static and self-contained, using only local variables.

## 4. CRUD Operations / Called Services

This method is an **HTTP client demo** — it performs no database or CRUD operations. It makes a network call to an external HTTP endpoint (`https://httpbin.org/post`) which is a test utility service that echoes back the received request.

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| — | (none) | — | — | No CRUD or service component calls. This is a pure HTTP client example. |

## 5. Dependency Trace

### Pre-computed evidence from code analysis graph:

Direct callers found: 1 method.

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | Main (Example.java) | `main(String[])` -> `asyncPost()` | `sendAsync -> https://httpbin.org/post [HTTP POST]` |

**Notes:**
- This method is called directly from the `main()` entry point of the `Example` class (line 191).
- It is not referenced by any screen, batch, controller, or business component — it is a standalone demo method.
- The only "terminal" action is the asynchronous HTTP POST to the external `httpbin.org` test endpoint.

## 6. Per-Branch Detail Blocks

**Block 1** — [SET/LOCAL] `(L62)`

> Initialize the HTTP client and JSON serializer. Sets up the infrastructure for the async POST request.

| # | Type | Code |
|---|------|------|
| 1 | SET | `HttpClient client = HttpClient.newHttpClient();` // Create non-blocking HTTP client |
| 2 | SET | `Gson gson = new Gson();` // Create JSON serialization engine |

**Block 2** — [SET/LOCAL] `(L64–66)`

> Construct the payload object `Foo` with hardcoded name and URL values. The name uses a Chinese string "王爵nice" (Wang Jue nice) and the URL points to the author's GitHub profile.

| # | Type | Code |
|---|------|------|
| 1 | SET | `Foo foo = new Foo();` // Instantiate payload object |
| 2 | SET | `foo.name = "王爵nice";` // Set name field — "Wang Jue nice" |
| 3 | SET | `foo.url = "https://github.com/biezhi";` // Set URL field — author's GitHub |

**Block 3** — [SET/LOCAL] `(L68)`

> Serialize the `Foo` object into a JSON-formatted string to use as the HTTP request body.

| # | Type | Code |
|---|------|------|
| 1 | SET | `String jsonBody = gson.toJson(foo);` // Convert Foo to JSON string |

**Block 4** — [SET/LOCAL] `(L70–75)`

> Build the HTTP POST request using the builder pattern. Configures the target URI, sets the Content-Type header to application/json, publishes the JSON string as the body, and builds the immutable request.

| # | Type | Code |
|---|------|------|
| 1 | SET | `HttpRequest request = HttpRequest.newBuilder()...build();` // Build POST request |
| 2 | EXEC | `.uri(new URI("https://httpbin.org/post"))` // Set target endpoint |
| 3 | EXEC | `.header("Content-Type", "application/json")` // Set content type header |
| 4 | EXEC | `.POST(HttpRequest.BodyPublishers.ofString(jsonBody))` // Set body from JSON string |
| 5 | EXEC | `.build()` // Finalize immutable HttpRequest |

**Block 5** — [CALL + CALLBACK + IF] `(L76–84)`

> Send the HTTP request asynchronously. Register a `whenComplete` callback that branches on whether the async operation succeeded or failed. Then block on `.join()` until completion.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `client.sendAsync(request, HttpResponse.BodyHandlers.ofString())` // Dispatch async POST |
| 2 | EXEC | `.whenComplete((resp, t) -> { ... })` // Register completion callback |
| 3 | EXEC | `.join()` // Block until async call completes |

**Block 5.1** — [IF] `(t != null)` [Error branch] `(L78)`

> The async request threw an exception. Print the stack trace for debugging. This is the error-handling path of the callback.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `t.printStackTrace();` // Print exception stack trace |

**Block 5.2** — [ELSE] `(t == null)` [Success branch] `(L80–82)`

> The async request completed successfully. A valid `HttpResponse` object is available. Print the response body (echoed request data) and HTTP status code to stdout.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `System.out.println(resp.body());` // Print HTTP response body |
| 2 | EXEC | `System.out.println(resp.statusCode());` // Print HTTP status code |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `asyncPost` | Method | Asynchronous HTTP POST — demonstrates Java 11 non-blocking HTTP client usage |
| `HttpClient` | API | Java 11 `java.net.http.HttpClient` — built-in HTTP client supporting HTTP/1.1 and HTTP/2 |
| `HttpClient.newHttpClient()` | API | Factory method that creates a default non-blocking HttpClient instance |
| `sendAsync()` | API | Sends an HTTP request asynchronously, returning a `CompletableFuture<HttpResponse>` |
| `whenComplete()` | API | `CompletableFuture` callback method invoked when the async operation finishes (success or failure) |
| `.join()` | API | Blocks the calling thread until the `CompletableFuture` completes, returning the result or throwing the exception |
| `HttpRequest` | API | Java 11 HTTP request builder — immutable representation of an HTTP request |
| `HttpResponse` | API | Java 11 HTTP response — contains the response body and metadata (status code, headers) |
| `BodyPublishers.ofString()` | API | Creates a body publisher that writes a string as the HTTP request body |
| `BodyHandlers.ofString()` | API | Response handler that collects the response body into a String |
| `Gson` | Library | Google Gson — JSON serialization/deserialization library (`com.google.gson.Gson`) |
| `Foo` | Class | Simple payload DTO with `name` (String) and `url` (String) fields |
| `httpbin.org/post` | External Service | Public test endpoint that receives HTTP POST requests and echoes back the request details in JSON response |
| `王爵nice` | String | A Chinese username literal used as the `name` field value in the demo payload |

---
DD01 | `Example.asyncPost()` | Generated from `src/main/java/io/github/biezhi/java11/http/Example.java` lines 61–85
