【问题标题】:Retrofit 2 - Getting 200 response but not getting data returnedRetrofit 2 - 得到 200 响应但没有返回数据
【发布时间】:2020-11-16 03:43:38
【问题描述】:

TL;DR


新改造,所以这可能是一个菜鸟错误。端点在邮递员中工作正常,我在响应中得到Response{protocol=http/1.1, code=200, message=OK, url=http://192.168.1.249/api/v1/user/1},但没有与用户相关的数据。

问题


我已经使用 Laravel 构建了一个 REST API,我想从设备访问它。将有许多端点需要访问,但我无法让它们中的任何一个工作。我试图在添加其余部分之前让一个工作,但即使我得到 200 我也没有得到任何数据。

response.body 上存在所有属性,但它们都为空。

代码


MainActivity.java

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Toast;


import com.x.tools.actualrest.rest.User;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import java.util.ArrayList;
import java.util.List;

import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class MainActivity extends Activity {

    private CdenApi cdenAPI;

    private String token;

    String requested_with = "XMLHttpRequest";
    String content_type = "application/json";

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        createCdenAPI();

        cdenAPI.getUser(requested_with, content_type, "1").enqueue(userCallback);


    }

    @Override
    protected void onResume() {
        super.onResume();
    }

    private void createCdenAPI() {
        Gson gson = new GsonBuilder()
                .setDateFormat("yyyy-MM-dd HH:mm:ss")
                .create();

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(CdenApi.BASE_URL)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .build();

        cdenAPI = retrofit.create(CdenApi.class);
    }

    Callback<User> userCallback = new Callback<User>() {
        @Override
        public void onResponse(Call<User> call, Response<User> response) {
            if (response.isSuccessful()) {
                User data = new User();
                data = response.body();
            } else {

            }
        }

        @Override
        public void onFailure(Call<User> call, Throwable t) {
            t.printStackTrace();
        }
    };
} 

CdenApi.java

import com.x.tools.actualrest.rest.User;

import retrofit2.http.GET;
import retrofit2.http.Header;
import retrofit2.http.Path;
import retrofit2.Call;

public interface CdenApi {

    String BASE_URL = "http://192.168.1.249/api/v1/";

    @GET("user/{id}")
    Call<User> getUser(@Header("X-Requested-With") String req_with, @Header("Content-Type") String cont_type, @Path("id")String userId);

} 

用户.java

import com.google.gson.annotations.SerializedName;

public class User {

    @SerializedName("id")
    public Integer id;
    @SerializedName("name")
    public String name;
    @SerializedName("email")
    public String email;
    @SerializedName("access_level")
    public Integer accessLevel;
    @SerializedName("created_at")
    public String createdAt;
    @SerializedName("updated_at")
    public String updatedAt;
    @SerializedName("view_boxes")
    public ViewBoxes viewBoxes;

}

UserResult.java

import com.google.gson.annotations.SerializedName;

public class UserResult {

    @SerializedName("msg")
    public String msg;
    @SerializedName("user")
    public User user;

}

ViewBoxes.java

import com.google.gson.annotations.SerializedName;

public class ViewBoxes {

    @SerializedName("href")
    public String href;
    @SerializedName("method")
    public String method;

}

来自端点的 JSON:

{
    "msg": "User information",
    "user": {
        "id": 1,
        "name": "Guy",
        "email": "guy@ganker.com",
        "access_level": 1,
        "created_at": "2017-08-22 15:53:06",
        "updated_at": "2017-08-22 15:53:06",
        "view_boxes": {
            "href": "api/v1/user/1",
            "method": "GET"
        }
    }
}

解决方案


我需要知道我哪里出错了。我是改装新手,所以我确定我实施了一些错误,但我看不到问题。

提前感谢您的帮助。

【问题讨论】:

  • 是否调用了用户回调?你在堆栈跟踪中有任何错误吗?您的清单中有互联网权限吗?
  • 它正在被调用,不,我没有收到任何错误
  • 你可以放置一个“断点”(developer.android.com/studio/debug/index.html#breakPoints)来查看发生了什么,或者你可以打印一个日志,检查它不会进入空的 else 条件。
  • 现在我看到了,你设置数据后,它什么也没做,你想对响应做什么?
  • 我正在尝试从响应中构建用户类型的用户。目前我只是使用调试器来检查 onResponse 块内的响应值。它正在被调用,就像我说的那样,我得到了一个带有正确 url 的 200 响应,但是用户数据的属性都是空的

标签: android retrofit2


【解决方案1】:

我认为问题在于您有Call&lt;User&gt;,但是对于您的json,您在服务器的响应中获得了UserResult,因此它必须是Call&lt;UserResult&gt;,并且在userCallback 中相同,而不是

Callback<User> userCallback = new Callback<User>

应该是

Callback<UserResult> userCallback = new Callback<UserResult>

在响应中也一样

public void onResponse(Call<UserResult> call, Response<UserResult> response) {
            if (response.isSuccessful()) {
                User data = new User();
                data = response.body().user;
            } else {

            }
        }

【讨论】:

  • 这看起来是正确的。因此遗憾的是,Retrofit2 在将 json 转换为 java 失败时并没有发送任何形式的调试信息或日志消息。非常不幸。对于初次使用的用户来说,它会成为一个时间窃贼,这与 Retrofit2 的目标正好相反
  • "new User()" 不是必须的
【解决方案2】:

尝试这样做

 protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    createCdenAPI();
    Response<User> response = cdenAPI.getUser(requested_with, content_type, "1").execute();

    User user = response.body();
 }

【讨论】:

  • 我对实现这一点的线程不够熟悉。哪个类应该实现runnable?
  • 如果你正在使用改造,我认为你不需要使用 Runnable。
【解决方案3】:

在你的MainActivity.java

删除

User data = new User();
data = response.body();

替换成

User data = response.body();

【讨论】:

    【解决方案4】:

    关于模型类,您可以尝试使用相同的模型类 网络、视图和数据库访问,但每个都有一些怪癖,所以最好有一个通用模型类,数据库和网络模型可以相互转换。

    关于房间和改造。 Room 似乎不喜欢儿童列表,如果改造得到 200(成功)错误代码但没有数据,问题可能是 转换过程失败,改造不会给你任何信息。

    尝试直接从 json 重新生成 netwotrk 模型类并使用它们。 Android Studio 插件 JsonToKotlinClass 创建数据类 ALT-K 或右键 包 -> 新建 -> 来自 JSON 的 Kotlin 数据类

    【解决方案5】:
            @GET("/users")
            Call<ResponseBody> listRepos();//function to call api
        }
    
        RetrofitService service = retrofit.create(RetrofitService.class);
        Call<ResponseBody> result = service.listRepos(username);
        result.enqueue(new Callback<ResponseBody>() {
    
        @Override
        public void onResponse(Response<ResponseBody> response) {
            try {
                System.out.println(response.body().string());//convert reponse to string
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        @Override
        public void onFailure(Throwable t) {
            e.printStackTrace();
        }
    });
    

    【讨论】:

    • 你应该在你的代码中加上一些解释,这里只有一些代码有 2 个答案,对我来说也没有多大意义。
    【解决方案6】:
    
    
    response.body().string();
    
    //you get this 
    
      {
        "msg": "User information",
        "user": {
            "id": 1,
            "name": "Guy",
            "email": "guy@ganker.com",
            "access_level": 1,
            "created_at": "2017-08-22 15:53:06",
            "updated_at": "2017-08-22 15:53:06",
            "view_boxes": {
                "href": "api/v1/user/1",
                "method": "GET"
            }
        }
    
    
    //instead of this
     
    Response{protocol=http/1.1,
     code=200, 
    message=OK, 
    url=http://192.168.1.249/api/v1/user/1}
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-30
    • 1970-01-01
    • 2020-12-20
    • 2019-12-10
    • 2020-09-02
    • 2016-02-27
    相关资源
    最近更新 更多