You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Android应用中调用返回ResponseEntity的SpringBoot API?

问题描述

我需要调用一个基于SpringBoot 3编写的服务器API,API定义如下:

public ResponseEntity<List<PostDTO>> getPosts();

在Android Studio的Java应用中使用Retrofit2(依赖:implementation 'com.squareup.retrofit2:retrofit:2.11.0')实现调用时,我在PostService.java里尝试了两种写法:
第一种:

@GET("v1/profiles/gigio/posts")
Response<List<Post>> getPosts();

第二种:

@GET("v1/profiles/gigio/posts")
Call<List<Post>> getPosts();

调用代码如下:

// retrieve posts for home page from server
postService = RetrofitClient.getClient().create(PostService.class);
Call<List<Post>> call = postService.getPosts();

结果触发了JNI错误,错误信息末尾内容:

2024-08-05 20:01:23.621 29123-29123 example.app         com.example.app                  A  runtime.cc:699] JNI DETECTED ERROR IN APPLICATION: the return type of CallObjectMethodA does not match retrofit2.Response com.example.app.service.PostService.getPosts()
                                                                                                    runtime.cc:699]     in call to CallObjectMethodA
                                                                                                    runtime.cc:699]     from void com.example.app.fragment.community.CommunityFragment.onViewCreated(android.view.View, android.os.Bundle)
2024-08-05 20:01:35.276 29123-29123 libc                    com.example.app                  A  Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 29123 (example.app), pid 29123 (example.app)

Post和PostDTO字段完全一致,我认为问题出在ResponseEntity上,想找到客户端侧的解决方案,无需修改服务器,请问有没有办法在客户端处理服务器返回的ResponseEntity?

解决方案

核心问题

JNI错误的直接原因是Retrofit接口定义的返回类型与调用时的接收类型不匹配——你用Call<List<Post>>接收返回值,但接口写的是Response<List<Post>>(或反过来),导致反射调用时类型兼容失败。另外,SpringBoot的ResponseEntity本质是封装了响应体、状态码、响应头的结构,Retrofit可以直接在客户端映射处理,无需修改服务器。

具体实现步骤

  1. 创建客户端版ResponseEntity实体类
    对应SpringBoot返回的ResponseEntity结构,在客户端定义实体类来映射JSON响应:

    public class ResponseEntity<T> {
        private T body;
        private int statusCode;
        private Map<String, List<String>> headers;
    
        // 生成getter、setter方法(可使用Lombok简化)
        public T getBody() { return body; }
        public void setBody(T body) { this.body = body; }
        public int getStatusCode() { return statusCode; }
        public void setStatusCode(int statusCode) { this.statusCode = statusCode; }
        public Map<String, List<String>> getHeaders() { return headers; }
        public void setHeaders(Map<String, List<String>> headers) { this.headers = headers; }
    }
    

    注意:如果服务器返回的statusCode是字符串枚举格式(如"statusCode": "OK"),需调整字段类型为String或自定义枚举类匹配。

  2. 统一Retrofit接口与调用的类型
    选择以下两种统一的实现方式之一:

    方式一:使用Call封装(同步/异步通用)

    接口定义:

    @GET("v1/profiles/gigio/posts")
    Call<ResponseEntity<List<Post>>> getPosts();
    

    调用代码(异步示例):

    postService = RetrofitClient.getClient().create(PostService.class);
    Call<ResponseEntity<List<Post>>> call = postService.getPosts();
    call.enqueue(new Callback<ResponseEntity<List<Post>>>() {
        @Override
        public void onResponse(Call<ResponseEntity<List<Post>>> call, retrofit2.Response<ResponseEntity<List<Post>>> response) {
            if (response.isSuccessful()) {
                ResponseEntity<List<Post>> serverResp = response.body();
                List<Post> posts = serverResp.getBody();
                // 业务数据处理
            }
        }
    
        @Override
        public void onFailure(Call<ResponseEntity<List<Post>>> call, Throwable t) {
            // 错误处理
        }
    });
    

    方式二:使用Response封装(适合同步调用)

    接口定义:

    @GET("v1/profiles/gigio/posts")
    Response<ResponseEntity<List<Post>>> getPosts();
    

    同步调用代码(需捕获IO异常):

    try {
        Response<ResponseEntity<List<Post>>> response = postService.getPosts().execute();
        if (response.isSuccessful()) {
            List<Post> posts = response.body().getBody();
            // 业务数据处理
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    
  3. 配置JSON转换器
    必须添加Retrofit的JSON转换器依赖,否则无法解析响应:

    // Gson转换器示例
    implementation 'com.squareup.retrofit2:converter-gson:2.11.0'
    

    并在Retrofit实例创建时添加转换器:

    Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("你的服务器基础URL")
        .addConverterFactory(GsonConverterFactory.create())
        .build();
    

关键注意事项

  • 接口定义的返回类型必须与调用时的接收类型完全一致,不能混用Call<X>和Response<X>,这是解决JNI错误的核心。
  • 客户端ResponseEntity的字段名必须与服务器返回的JSON结构严格匹配,否则会出现解析失败或字段为空的情况。

内容的提问来源于stack exchange,提问作者Francesco

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 19:55:15