Android Okhttp3 的坑

本文介绍了如何在OkHttp中实现Cookie的管理功能,通过自定义CookieJar接口的具体实现,可以将Cookie保存到内存中,并在请求时加载这些Cookie。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//记录下正确姿势
OkHttpClient mHttpClient = new OkHttpClient.Builder().cookieJar(new CookieJar() {
    private final HashMap<String, List<Cookie>> cookieStore = new HashMap<>();
    //Tip:這裡key必須是String
    @Override
    public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
        cookieStore.put(url.host(), cookies);
    }
    @Override
    public List<Cookie> loadForRequest(HttpUrl url) {
        List<Cookie> cookies = cookieStore.get(url.host());
        return cookies != null ? cookies : new ArrayList<Cookie>();
    }
}).build();

转载于:https://my.oschina.net/u/3136970/blog/907365

<think>嗯,用户现在想了解如何使用OkHttp3发送带参数的GET请求。用户提供了站内引用,展示了基本GET请求的实现,但没有直接提供带参数的示例。用户可能是个Android开发者,正在调试网络请求功能。从查询的精确性来看,用户应该有一定OkHttp基础,但需要具体的参数传递示例。这种需求在实际开发中很常见,比如需要调用带查询字符串的API。在准备回答时,需要考虑三个技术要点:第一是参数构造的正确方法。虽然可以直接拼接URL字符串,但官方推荐使用HttpUrl.Builder更安全,能自动处理特殊字符编码问题。第二要区分同步和异步调用的差异。之前的引用[1]和[3]已经展示了这两种模式的基本用法,只需在此基础上增加参数部分即可。第三要特别注意线程安全问题。在回调中处理响应时,需要提醒用户注意Android的线程限制,比如不能直接更新UI。考虑到用户可能遇到的点,应该在示例中特别说明两个易错点:一是中文参数必须编码,否则会乱码;二是如果参数值包含特殊字符(如&符号),手动拼接容易出错。这正是推荐使用Builder的核心原因。用户之前查过资料但没找到具体方案,所以采用最直观的分步示例会更友好。准备分别演示同步请求和异步请求两种场景,并强调关键步骤的注意事项。另外注意到引用[4]提到响应计数的方法,虽然与当前问题无关,但可能暗示用户之后会需要处理重定向等高级特性。不过这已经超出本次问题范围了。</think> 要在OkHttp3中实现带参数的GET请求,核心是正确构造包含查询参数的URL。以下是具体实现方法及示例: ### 1. 使用 `HttpUrl.Builder` 构建带参URL(推荐) ```java OkHttpClient client = new OkHttpClient(); // 1. 构造带参数的URL HttpUrl url = new HttpUrl.Builder() .scheme("https") // 协议 .host("api.example.com") // 主机地址 .addPathSegment("data") // 路径 .addQueryParameter("key1", "value1") // 参数1 .addQueryParameter("key2", "中文") // 中文参数自动编码 .addQueryParameter("page", "1") // 参数2 .build(); // 2. 创建请求 Request request = new Request.Builder() .url(url) .get() // 显式声明GET(可省略) .build(); // 3. 同步执行请求 try (Response response = client.newCall(request).execute()) { if (response.isSuccessful()) { System.out.println(response.body().string()); } } catch (IOException e) { e.printStackTrace(); } ``` > **自动编码说明**: > `addQueryParameter()` 会自动对特殊字符和中文进行URL编码,避免手动处理 `URLEncoder.encode()`[^2] ### 2. 手动拼接URL(简易场景) ```java String baseUrl = "https://api.example.com/data?"; String fullUrl = baseUrl + "key1=" + URLEncoder.encode("value1", StandardCharsets.UTF_8.name()) + "&key2=" + URLEncoder.encode("中文", StandardCharsets.UTF_8.name()); Request request = new Request.Builder() .url(fullUrl) .build(); // 后续执行步骤同上 ``` > **注意**:手动拼接时必须使用 `URLEncoder.encode()` 处理特殊字符,否则参数值含空格/中文时会报错[^2] ### 异步请求示例 ```java client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { e.printStackTrace(); } @Override public void onResponse(Call call, Response response) throws IOException { try (ResponseBody body = response.body()) { if (response.isSuccessful()) { System.out.println(body.string()); } else { System.out.println("请求失败: " + response.code()); } } } }); ``` ### 关键点总结 1. **参数安全** - 优先使用 `HttpUrl.Builder` 避免编码错误 - 手动拼接时 **必须** 用 `URLEncoder.encode()` - 空格需转为 `+` 或 `%20`(自动处理) 2. **符号处理** 保留字符如 `&`, `=` 在参数值中出现时会被自动编码为 `%26`, `%3D` 等[^3] 3. **特殊场景** ```java .addQueryParameter("ids", "101,102,103") // 数组参数:逗号分隔 .addQueryParameter("sort", "-date") // 排序参数 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值