Retrofit2 Get请求包含特殊字符

本文介绍如何在Retrofit2的GET请求中处理特殊字符,避免URL编码,通过使用encoded参数实现直接传递特殊字符,同时提供接口定义和调用示例。

如果 Retrofit2 Get请求包含特殊字符(例如:%*?等),不希望请求的过程中被转码,可以使用参数(encoded = true):

1、接口定义:

    /**
     * 数据查询
     *
     * @return
     */
    @GET("ezview/vehicle/gather")
    Call<HttpBaseResult<QueryResponse>> getVehicleList(@QueryMap(encoded = true) Map<String, Object> map);

2、接口调用:

 public void getQueryResult(String startTime, String stopTime, boolean loadMore) {
        Map<String, Object> map = new HashMap<>();

        if (startTime != null && startTime.length() > 0) {
            map.put("startTime", startTime + " 00:00:00");
        }

        if (stopTime != null && stopTime.length() > 0) {
            map.put("stopTime", stopTime + " 23:59:59");
        }
        if (loadMore) {
            pageNo++;
        } else {
            pageNo = 0;
        }

        map.put("pageNo", pageNo);
        map.put("pageSize", BundleConstants.pageSize);
        map.put("queryAll", false);//仅显示当前用户的信息

        serviceApi.getVehicleList(map).enqueue(new HttpRequestCallback<QueryResponse>() {
            @Override
            public void onSuccess(QueryResponse result) {
                super.onSuccess(result);
            }

            @Override
            public void onFailure(int status, String message) {
                super.onFailure(status, message);
            }
        });
    }
<think>嗯,用户之前已经问过如何在Kotlin中发送GET请求,现在他们特别想了解如何使用Retrofit来发送GET请求。首先,我需要回忆一下Retrofit的基本用法和它在项目中的常见应用场景。Retrofit是一个类型安全的HTTP客户端,通常用于Android和Java应用,能够将HTTP API转换成Kotlin或Java接口,这样开发者可以更方便地进行网络请求。 用户之前的问题中已经提到了Retrofit作为方法4,但可能他们想深入了解具体的步骤和细节。所以,我需要详细分解Retrofit的使用流程,包括添加依赖、创建数据模型、定义接口、构建Retrofit实例以及实际调用的方法。同时,用户可能需要知道如何处理不同的参数类型,比如路径参数、查询参数和请求头,这些都是GET请求中常见的需求。 考虑到用户可能是Android开发者,我需要强调在Android中使用时的注意事项,比如主线程限制和权限问题。此外,异步处理也是关键点,Retrofit通常结合协程或RxJava来处理异步请求,但根据用户之前的回答,他们已经介绍了Ktor的协程支持,所以可能需要重点说明Retrofit与协程的结合使用。 另外,错误处理和配置选项也是用户可能关心的内容。例如,如何设置超时时间、添加拦截器或者使用不同的转换器(如Gson、Moshi)。这些高级配置可以帮助用户优化网络请求的处理。 需要确保示例代码正确,并且符合Kotlin的语法习惯。比如,使用挂起函数来简化协程调用,以及使用数据类来解析JSON响应。同时,提醒用户在实际项目中需要替换示例中的URL和数据结构,并处理可能的异常情况,比如网络错误或解析失败。 最后,总结Retrofit的优势,比如类型安全、简洁的API设计和与其他库的良好兼容性,帮助用户理解为什么选择Retrofit而不是其他库。同时,对比之前提到的OkHttp和Ktor,指出Retrofit适合复杂API交互的场景,而简单项目可能不需要这么重的库。</think>以下是使用 Retrofit 发送 GET 请求的完整指南,包含基础配置、参数传递和最佳实践: --- ### 一、基础配置 1. **添加依赖** (build.gradle.kts) ```kotlin implementation("com.squareup.retrofit2:retrofit:2.9.0") implementation("com.squareup.retrofit2:converter-gson:2.9.0") // JSON 解析 implementation("com.squareup.okhttp3:logging-interceptor:4.12.0") // 日志拦截器 ``` 2. **创建数据模型** ```kotlin data class User( val id: Int, val name: String, val email: String ) ``` 3. **定义 API 接口** ```kotlin interface ApiService { // 基础 GET 请求 @GET("users") suspend fun getUsers(): List<User> // 带路径参数的请求 @GET("users/{userId}") suspend fun getUserById(@Path("userId") id: Int): User // 带查询参数的请求 @GET("search") suspend fun searchUsers( @Query("name") name: String, @Query("page") page: Int = 1 ): List<User> } ``` --- ### 二、构建 Retrofit 实例 ```kotlin val retrofit = Retrofit.Builder() .baseUrl("https://api.example.com/") .client( OkHttpClient.Builder() .addInterceptor(HttpLoggingInterceptor().apply { level = HttpLoggingInterceptor.Level.BODY }) .readTimeout(30, TimeUnit.SECONDS) .build() ) .addConverterFactory(GsonConverterFactory.create()) .build() val apiService = retrofit.create(ApiService::class.java) ``` --- ### 三、发起 GET 请求 #### 同步请求(需在协程/后台线程执行) ```kotlin viewModelScope.launch(Dispatchers.IO) { try { val users = apiService.getUsers() println("Fetched ${users.size} users") } catch (e: Exception) { println("Request failed: ${e.message}") } } ``` #### 异步请求(协程实现) ```kotlin // 在 ViewModel 中使用 suspend fun loadUserDetails(userId: Int) { try { val user = apiService.getUserById(userId) _userLiveData.postValue(user) } catch (e: IOException) { _errorLiveData.postValue("Network error") } catch (e: HttpException) { _errorLiveData.postValue("HTTP error: ${e.code()}") } } ``` --- ### 四、高级用法 1. **动态请求头** ```kotlin @GET("profile") suspend fun getProfile( @Header("Authorization") token: String ): UserProfile ``` 2. **URL 参数编码** ```kotlin @GET("search") suspend fun search( @Query("keyword") @Encoded keyword: String // 保留特殊字符 ) ``` 3. **多查询参数合并** ```kotlin @GET("filter") suspend fun filterUsers( @Query("tags") tags: List<String> // 自动转换为 ?tags=foo&tags=bar ) ``` --- ### 五、最佳实践 1. **错误处理模板** ```kotlin inline fun <T> safeApiCall(block: () -> T): Result<T> { return try { Result.success(block()) } catch (e: IOException) { Result.failure(e) } catch (e: HttpException) { Result.failure(Exception("HTTP error ${e.code()}")) } } // 使用示例 val result = safeApiCall { apiService.getUsers() } ``` 2. **配置建议** - 使用 `baseUrl` 必须以 `/` 结尾 - 推荐使用 `suspend` 函数简化协程调用 - 生产环境关闭日志拦截器 - 使用 `GsonBuilder` 自定义日期格式等序列化策略 --- ### 六、完整调用流程示例 ```kotlin // 1. 创建 Retrofit 实例 private val apiService: ApiService by lazy { Retrofit.Builder() .baseUrl("https://jsonplaceholder.typicode.com/") .addConverterFactory(GsonConverterFactory.create()) .build() .create(ApiService::class.java) } // 2. 在 ViewModel 中调用 fun loadData() { viewModelScope.launch { when (val result = safeApiCall { apiService.getUsers() }) { is Result.Success -> _uiState.value = UiState.Success(result.data) is Result.Failure -> _uiState.value = UiState.Error(result.exception) } } } ``` --- ### 七、常见问题解决 1. **返回 404 错误** 检查: - 完整 URL 拼接是否正确(baseUrl + @GET 路径) - 是否缺少路径参数 - 服务器路由是否存在 2. **JSON 解析失败** 检查: - 数据类字段是否与 JSON key 完全匹配 - 是否使用了 `@SerializedName` 注解处理命名差异 - 是否包含未预期的 null 值 3. **网络权限问题** Android 需添加: ```xml <uses-permission android:name="android.permission.INTERNET" /> ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

唐诺

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值