Retrofit请求返回String报错问题解决方案

本文探讨了在处理服务端返回字符串时遇到的问题,介绍了两种解决方案:一是接口返回值改为JsonObject,二是自定义GsonConverterFactory进行字符串转对象。重点在于避免直接字符串解析错误,并提供了详细的实现步骤。

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

项目场景

会有这种情况,需要获取到服务端返回的字符串,再根据返回的结果进一步处理,而不是直接获取到定义好的对象。

问题描述

如果将接口定义为如下情况,当接口返回结果为大括号开头,可能会遇到报错:Expected a string but was BEGIN_OBJECT at line 1 column 2 path $

interface Service {
    @POST("/test")
    suspend fun test(@Body body: RequestBody): String
}

解决方案

这里提供两种解决方案供参考:

方案1:

将返回结果改为 JsonObject

interface Service {
    @POST("/test")
    suspend fun test(@Body body: RequestBody): JsonObject
}

方案2:

替换GsonConverterFactory(这个方案也很简单,分以下三步)

Okhttp获取请求后,通过 GsonConverterFactory 的 responseBodyConverter 获取到GsonResponseBodyConverter对象,GsonResponseBodyConverter的convert方法负责将获取到的结果转换为想要的对象。

第一步:我们这里只需要 GsonConverterFactory  和 GsonResponseBodyConverter 复制一份出来,修改一个喜欢的名字,比如我这里定义为 MyGsonConverterFactory 和 MyGsonResponseBodyConverter。

第二部:修改MyGsonResponseBodyConverter的convert方法如下:

final class MyGsonRequestBodyConverter<T> implements Converter<T, RequestBody> {

  private final Gson gson;
  private final TypeAdapter<T> adapter;

  GsonRequestBodyConverter(Gson gson, TypeAdapter<T> adapter) {
    this.gson = gson;
    this.adapter = adapter;
  }

  @Override
  public RequestBody convert(T value) throws IOException {
    String response = value.string();
        try {
            T result = gson.fromJson(response, type);
            return result;
        } catch (JsonSyntaxException e) {
            // 解析出错,如果是String类型直接返回
            if (type instanceof Class) {
                Class<?> clazz = (Class<?>) type;
                if (clazz == String.class) {
                    return (T) response;
                }
            }
            throw e;
        }
  }
}

第三部:

实例化Service的时候记得替换成我们定义的ConverterFactory

Retrofit
    .Builder()
    .baseUrl(hostUrl)
    .client(okHttpClient)
    .addConverterFactory(MyGsonConverterFactory.create()) // 自定义的ConvertFactory

### Midscene 插件 HTTP 400 错误解决方案 当遇到 `HTTP 400 Bad Request` 的错误时,通常表示服务器无法处理客户端发送的请求。以下是针对此问题的原因分析以及解决方法: #### 1. 出错原因 根据描述,Midscene 插件出现了 `HTTP 400 Bad Request` 错误。此类错误可能是由于以下原因之一引起的: - 请求体为空或格式不正确[^2]。 - 参数缺失或参数值不符合预期[^3]。 - 接口未正确定义或缺少必要的注解配置[^5]。 具体表现为服务器端接收到的数据存在问题,例如 JSON 数据结构不匹配、字段名拼写错误或者数据类型不符等。 --- #### 2. Spring Boot 实现代码示例 为了验证是否存在上述问题,可以检查服务端接收 POST 请求的相关实现逻辑。以下是一个典型的 Spring Boot 控制器代码示例: ```java @RestController @RequestMapping("/scenario") public class ScenarioController { @PostMapping(value = "/card/queryAllRecycleBinScenarioCard", consumes = "application/json", produces = "application/json") public ResponseEntity<?> queryAllRecycleBinScenarioCard(@RequestBody(required = true) Map<String, Object> requestBody) { try { // 验证请求体是否为空 if (requestBody.isEmpty()) { return new ResponseEntity<>("Request Body is empty!", HttpStatus.BAD_REQUEST); } // 处理业务逻辑... System.out.println("Received data: " + requestBody); return new ResponseEntity<>(Collections.singletonMap("success", true), HttpStatus.OK); } catch (Exception e) { return new ResponseEntity<>("Error processing request: " + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); } } } ``` 在此代码中,通过设置 `@RequestBody(required = true)` 明确指定了请求体不能为空,并提供了基本的校验机制来捕获潜在的输入错误[^1]。 --- #### 3. Retrofit 客户端调试技巧 如果前端使用了 Retrofit 进行 API 调用,则可以通过以下方式进一步排查问题: ##### (1)启用日志记录功能 在初始化 Retrofit 对象时增加 OkHttp 日志拦截器以便观察实际发出的请求内容: ```java OkHttpClient client = new OkHttpClient.Builder() .addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)) .build(); Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://your-api-base-url.com/") .client(client) .addConverterFactory(GsonConverterFactory.create()) .build(); ``` ##### (2)捕获并解析错误响应 对于失败回调中的 Throwable 对象,尝试将其转换为 HttpException 并提取详细的错误信息: ```java try { throw throwable; } catch (HttpException e) { Response response = e.response(); String errorMessage = null; if (response != null && response.errorBody() != null) { try { errorMessage = response.errorBody().string(); // 获取完整的错误消息 } catch (IOException ex) { ex.printStackTrace(); } } Log.e("API Error", "Code: " + e.code() + ", Message: " + errorMessage); } ``` 这种方法可以帮助开发者快速定位问题所在。 --- #### 4. 总结与建议 综合以上分析可知,要彻底解决问题需从以下几个方面入手: - **确认请求头**:确保 Content-Type 设置为 application/json。 - **验证请求体**:仔细核对接口文档,保证传递给后端的数据完全一致。 - **优化服务端设计**:增强异常捕捉能力,提供更友好的反馈提示。 - **加强测试覆盖范围**:利用工具模拟各种边界条件下的行为表现。 最终目的是让整个交互流程更加健壮可靠。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值