Bläddra i källkod

教程点2:GET 请求 - 列表、按id查询、查询参数示例与测试

yangyi 1 vecka sedan
förälder
incheckning
3e8de5dea6

+ 59 - 1
doc.md

@@ -57,4 +57,62 @@ System.out.println("响应体: " + response.body());
 
 
 见 `QuickStartTest.java`。测试会真实调用本地 API,运行后控制台打印响应结果。
 见 `QuickStartTest.java`。测试会真实调用本地 API,运行后控制台打印响应结果。
 (测试目标:GET `http://localhost:8080/api/users`,正常情况下返回
 (测试目标:GET `http://localhost:8080/api/users`,正常情况下返回
-`{"code":200,"message":"OK","data":[...]}`)
+`{"code":200,"message":"OK","data":[...]}`)
+
+---
+
+## 二、GET 请求
+
+### 2.1 文字说明
+
+GET 是最常用的 HTTP 方法,用于从服务器获取数据,且**不携带请求体**。
+用 JDK HTTP Client 发送 GET 请求时,有三种常见写法:
+
+1. **不带参数的 GET**:`.uri(url)` + `.GET()`,例如查询用户列表;
+2. **带路径参数的 GET**:把 id 等参数拼进 URL 路径,例如查询单个用户
+   `/api/users/1`;
+3. **带查询字符串的 GET**:`?key=value` 跟在 URI 后面,服务端按查询条件过滤。
+
+要点总结:
+
+| 要点 | 说明 |
+|------|------|
+| `.GET()` | 显式声明请求方法;省略时默认也是 GET,但显式写出更清晰 |
+| 路径参数 | 直接拼在 URL 中,如 `/api/users/{id}` |
+| 查询参数 | 拼在 `?` 之后,多个用 `&` 连接 |
+| 无请求体 | GET 请求使用 `BodyPublishers.noBody()`(默认),无需设置请求体 |
+| 响应码 | 200 找到资源;404 资源不存在 |
+
+### 2.2 示例代码
+
+见 `GetExample.java`。核心代码如下:
+
+```java
+// 不带参数的 GET:查询所有用户
+HttpRequest request = HttpRequest.newBuilder()
+        .uri(URI.create(BASE_URL + "/api/users"))
+        .GET()
+        .build();
+HttpResponse<String> response =
+        httpClient.send(request, HttpResponse.BodyHandlers.ofString());
+
+// 带路径参数的 GET:根据 id 查询单个用户
+HttpRequest request2 = HttpRequest.newBuilder()
+        .uri(URI.create(BASE_URL + "/api/users/" + id))
+        .GET()
+        .build();
+HttpResponse<String> response2 =
+        httpClient.send(request2, HttpResponse.BodyHandlers.ofString());
+
+// 带查询字符串的 GET(标准写法演示)
+URI uri = URI.create(BASE_URL + "/api/users?account=alice01");
+```
+
+### 2.3 测试代码
+
+见 `GetExampleTest.java`,测试点包括:
+
+- `getUsers`:GET `/api/users` 返回 200,且响应体含 `code` 包装字段;
+- `getUserById_notExists`:GET `/api/users/999999999` 返回 404;
+- `buildRequestWithQuery`:验证带 `?account=alice01` 查询参数的请求
+  URI 拼接正确,且 GET 请求体为空。

+ 61 - 8
src/main/java/space/anyi/httpClient/GetExample.java

@@ -4,18 +4,71 @@ import java.io.IOException;
 import java.net.URI;
 import java.net.URI;
 import java.net.http.HttpClient;
 import java.net.http.HttpClient;
 import java.net.http.HttpRequest;
 import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
 
 
+/**
+ * GET 请求示例:演示发送 GET 请求的两种常见场景
+ *
+ * <ul>
+ *     <li>GET 请求列表:查询所有用户 GET /api/users</li>
+ *     <li>GET 请求单个资源:根据 id 查询用户 GET /api/users/{id}</li>
+ * </ul>
+ */
 public class GetExample {
 public class GetExample {
-    public void process() throws IOException, InterruptedException {
+
+    /** 服务基地址常量 */
+    private static final String BASE_URL = "http://localhost:8080";
+
+    /**
+     * 发送一个不带参数的 GET 请求,查询所有用户。
+     *
+     * @return 响应对象,可通过 statusCode()/body() 获取状态码和响应体
+     */
+    public HttpResponse<String> getUsers() throws IOException, InterruptedException {
+        // 创建 HttpClient,newHttpClient() 使用默认配置
         HttpClient httpClient = HttpClient.newHttpClient();
         HttpClient httpClient = HttpClient.newHttpClient();
-        HttpRequest httpRequest = HttpRequest.newBuilder()
-                //设置请求的URL
-                .uri(URI.create("http://www.baidu.com"))
-                //设置请求方法为GET
+
+        // 构造 GET 请求:.GET() 显式声明请求方法(省略时默认为 GET)
+        HttpRequest request = HttpRequest.newBuilder()
+                .uri(URI.create(BASE_URL + "/api/users"))
                 .GET()
                 .GET()
-                //设置请求头
-                .header("Content-Type", "application/json")
                 .build();
                 .build();
 
 
+        // 发送请求并返回响应
+        return httpClient.send(request, HttpResponse.BodyHandlers.ofString());
+    }
+
+    /**
+     * 发送一个带路径参数的 GET 请求,根据用户 id 查询单个用户。
+     *
+     * @param id 用户 id,会拼接在 URL 路径中
+     * @return 响应对象;若用户存在则状态码为 200,否则为 404
+     */
+    public HttpResponse<String> getUserById(long id) throws IOException, InterruptedException {
+        HttpClient httpClient = HttpClient.newHttpClient();
+
+        // 通过字符串拼接把 id 拼进 URL 路径,形成 /api/users/1 这样的地址
+        HttpRequest request = HttpRequest.newBuilder()
+                .uri(URI.create(BASE_URL + "/api/users/" + id))
+                .GET()
+                .build();
+
+        return httpClient.send(request, HttpResponse.BodyHandlers.ofString());
+    }
+
+    /**
+     * 演示如何按条件查询。本服务不支持查询参数,这里展示标准写法:
+     * 通过 {@link URI#create(String)} 拼上 ?key=value 的查询字符串。
+     *
+     * <p>此方法不实际调用(服务无此接口),仅用于讲解构造带查询字符串的 GET 请求。</p>
+     */
+    public HttpRequest buildRequestWithQuery(String account) {
+        // 查询字符串格式:?参数名=参数值,多个参数用 & 连接
+        URI uri = URI.create(BASE_URL + "/api/users?account=" + account);
+
+        return HttpRequest.newBuilder()
+                .uri(uri)
+                .GET()
+                .build();
     }
     }
-}
+}

+ 46 - 0
src/test/java/space/anyi/httpClient/GetExampleTest.java

@@ -0,0 +1,46 @@
+package space.anyi.httpClient;
+
+import org.junit.jupiter.api.Test;
+
+import java.io.IOException;
+import java.net.http.HttpResponse;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * GET 请求示例的测试类
+ *
+ * <p>测试依赖本地运行的 User Management API 服务(http://localhost:8080)。</p>
+ */
+class GetExampleTest {
+
+    private final GetExample getExample = new GetExample();
+
+    @Test
+    void getUsers() throws IOException, InterruptedException {
+        // 查询所有用户:状态码应为 200
+        HttpResponse<String> response = getExample.getUsers();
+
+        assertEquals(200, response.statusCode());
+        // 响应体是标准包装结构,应包含 code 字段
+        assertTrue(response.body().contains("\"code\""));
+    }
+
+    @Test
+    void getUserById_notExists() throws IOException, InterruptedException {
+        // 使用一个不存在的 id(例如 999999999),服务应返回 404
+        HttpResponse<String> response = getExample.getUserById(999999999L);
+
+        assertEquals(404, response.statusCode());
+    }
+
+    @Test
+    void buildRequestWithQuery() {
+        // 验证带查询参数的请求对象可以正常构建,URI 拼接正确
+        var request = getExample.buildRequestWithQuery("alice01");
+        assertEquals("http://localhost:8080/api/users?account=alice01",
+                request.uri().toString());
+        // GET 方法的 HttpRequest 不应包含请求体
+        assertEquals(null, request.bodyPublisher().orElse(null));
+    }
+}