如何在不使用 GSON 或 android 中的任何其他库的情况下使用改造以字符串形式获得响应 [重复]

Posted

技术标签:

【中文标题】如何在不使用 GSON 或 android 中的任何其他库的情况下使用改造以字符串形式获得响应 [重复]【英文标题】:How to get response as String using retrofit without using GSON or any other library in android [duplicate] 【发布时间】:2015-12-13 13:57:15 【问题描述】:

我正在尝试从以下 Api 获得响应:

https://api.github.com/users/username

但我不知道如何获得String 的响应,以便我可以使用String 解析并获取JSONObject

使用的改装版本:

改造:2.0.0-beta1

到目前为止我已经尝试过了:

public interface GitHubService 
        @GET("/users/user")
        public String listRepos(@Path("user") String user,Callback<String> callback);
    

检索:

GitHubService service = retrofit.create(GitHubService.class);
        service.listRepos("username", new Callback<String>() 
            @Override
            public void onResponse(Response response) 
                System.out.println(response.toString());
            

            @Override
            public void onFailure(Throwable t) 

            
        );

例外:

Caused by: java.lang.IllegalArgumentException: Could not locate call adapter for class java.lang.String. Tried:
    * retrofit.ExecutorCallAdapterFactory
            at retrofit.Utils.resolveCallAdapter(Utils.java:67)
            at retrofit.MethodHandler.createCallAdapter(MethodHandler.java:49)

任何帮助将不胜感激。

【问题讨论】:

但是为此我将不得不使用异步任务,因为我发现改造比异步任务快得多,这就是我想使用改造的原因,必须有某种方法来获取 JSON或字符串或任何方法。我搜索了很多,但没有找到任何东西。 “我发现改造比异步任务快得多”——因为改造很可能使用AsyncTask,我怀疑你的实际问题出在你的任何在您进行比较时对 HTTP 请求进行了处理。 instructure.github.io/blog/2013/12/09/volley-vs-retrofit,我想你很清楚这些事实,但请告诉我任何方法来实现我想要做的事情。 好的,谢谢,但为什么 Twitter Fabric 使用改造来进行 REST API 调用,这只是他们这样做的方式还是背后有任何其他原因? “为什么 Twitter Fabric 使用 Retrofit 进行 REST API 调用”——因为 Retrofit 非常擅长进行 REST 调用,当你想让 Retrofit 真正解析结果时。正如我所写的,这就是 Retrofit 背后的point,让它为你处理 HTTP 和解析管道。无论出于何种原因,您都不希望 Retrofit 进行解析。这很好,但这不是改造的目的。 Square 用于普通 HTTP 操作的库是 OkHttp(如果你的应用中有 OkHttp,Retrotfit 甚至会使用它)。 【参考方案1】:

** 更新 ** 一个标量转换器已添加到改造中,它允许String 响应比我下面的原始答案更简洁。

示例界面--

public interface GitHubService 
    @GET("/users/user")
    Call<String> listRepos(@Path("user") String user);

ScalarsConverterFactory 添加到您的改造构建器中。 注意:如果使用ScalarsConverterFactory 和另一个工厂,首先添加标量工厂。

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl(BASE_URL)
    .addConverterFactory(ScalarsConverterFactory.create())
    // add other factories here, if needed.
    .build();

您还需要在 gradle 文件中包含标量转换器 --

implementation 'com.squareup.retrofit2:converter-scalars:2.1.0'

--- 原始答案(仍然有效,只是更多代码)---

我同意@CommonsWare 的观点,您想拦截请求以自己处理 JSON 似乎有点奇怪。大多数情况下,POJO 拥有您需要的所有数据,因此无需在JSONObject 土地上乱搞。如果您需要操作 JSON,我怀疑使用自定义 gson TypeAdapter 或改造 Converter 可能会更好地解决您的具体问题。但是,改造提供了更多通过 Gson 进行的 JSON 解析。它还管理 REST 请求中涉及的许多其他繁琐任务。仅仅因为您不想使用其中一项功能,并不意味着您必须放弃整个功能。有时您只想获取原始流,所以这里是如何做到的 -

首先,如果您使用的是 Retrofit 2,您应该开始使用 Call API。不要发送一个对象作为类型参数进行转换,而是使用 okhttp 中的ResponseBody --

public interface GitHubService 
    @GET("/users/user")
    Call<ResponseBody> listRepos(@Path("user") String user);

然后你可以创建并执行你的调用 --

GitHubService service = retrofit.create(GitHubService.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());
         catch (IOException e) 
            e.printStackTrace();
        
    

    @Override
    public void onFailure(Throwable t) 
        e.printStackTrace();
    
);

注意 上面的代码在响应对象上调用string(),它将整个响应读入一个字符串。如果您要将主体传递给可以摄取流的东西,则可以改为调用charStream()。请参阅 ResponseBody 文档。

【讨论】:

能否打印堆栈跟踪以防失败?我知道这不是这个问题的重点,但是没有经验的人可能会复制并粘贴此代码。 对于那些只想获取字符串响应的人,可以将 response.body() 转换为字符串使用: private void logJsonPayload(Object object) //Log JSON String try ObjectWriter ow = new ObjectMapper().writer();字符串 jsonPayload = ow.writeValueAsString(object); Log.d("!!!", "JSON 负载:" + jsonPayload); catch (JsonProcessingException e) e.printStackTrace(); 在我的 Retrofit 回调中不同:public void onResponse(Call call, Response response) 在这个响应中没有方法 string() .string() 将 "/url" this 更改为 "\/url" this 确保在使用 Retrofit 2 时使用 okhttp3.ResponseBody 而不是 com.squareup.okhttp.ResponseBody,这会引发与问题中描述的相同的错误。

以上是关于如何在不使用 GSON 或 android 中的任何其他库的情况下使用改造以字符串形式获得响应 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何使用Gson序列化android中的对象?

使用 GSON 库导出/签署 Android 项目

如何在 android 中解析来自 url 或 restful 服务的大量 JSON 数据?没有 GSON

如何使用 GSON 或 Java 中的其他 JSON 库反序列化列表?

C/C++ Linux,如何在不使用 IP 的情况下在网络上查找邻居(仅限 MAC)

如何使用新值对象进行jsonify?