【问题标题】:How to get string response from Retrofit2?如何从 Retrofit2 获得字符串响应?
【发布时间】:2016-07-31 03:44:25
【问题描述】:

我正在做 android,正在寻找一种方法来做一个超级基本的 http GET/POST 请求。我不断收到错误消息:

java.lang.IllegalArgumentException: Unable to create converter for class java.lang.String

网络服务:

public interface WebService {
    @GET("/projects")
    Call<String> jquery();
}

然后在我的java中:

    Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("https://jquery.org")
       // .addConverterFactory(GsonConverterFactory.create())
        .build();

    WebService service = retrofit.create(WebService.class);
    Call<String> signin = service.jquery();

    Toast.makeText(this, signin.toString(), Toast.LENGTH_LONG).show();

我实际上只是尝试使用 GET 请求查询 jquery.org/projects 并返回它响应的字符串。怎么了?

如果我尝试实现自定义转换器(我在网上找到了一些示例),它会抱怨我没有实现抽象方法 convert(F),而这些示例都没有。

谢谢。

【问题讨论】:

    标签: java android http retrofit2


    【解决方案1】:

    将 Retrofit2 和 ScalarsConverterFactory 添加到您的 Retrofit.Builder。

    adapterBuilder = new Retrofit.Builder()
                   .addConverterFactory(ScalarsConverterFactory.create())
                   .addConverterFactory(GsonConverterFactory.create());
    

    要使用 ScalarsCoverter,请将以下依赖项添加到您的构建 graddle

    implementation 'com.squareup.retrofit2:converter-scalars:2.9.0' 
    implementation 'com.squareup.retrofit2:retrofit:2.9.0' //Adding Retrofit2
    
    For API Call use: 
        Call <String> *****
    

    安卓代码:

    .enqueue(new Callback<String>() {
        @Override
        public void onResponse(Call<String> call, Response<String> response) {
            Log.i("Response", response.body().toString());
            //Toast.makeText()
            if (response.isSuccessful()){
                if (response.body() != null){
                    Log.i("onSuccess", response.body().toString());
                }else{
                    Log.i("onEmptyResponse", "Returned empty response");//Toast.makeText(getContext(),"Nothing returned",Toast.LENGTH_LONG).show();
                }
            }
    

    【讨论】:

    • 优秀的答案...添加单行 .addConverterFactory(ScalarsConverterFactory.create()) 解决了我的问题....
    • 很好,它适用于 response.body().toString()。但是如果 response.errorBody().toString() 不起作用,请帮助我
    • adapterBuilder = new Retrofit.Builder() .addConverterFactory(ScalarsConverterFactory.create()) .addConverterFactory(GsonConverterFactory.create());这段代码对我有用。我有 2 个调用接口(第一个 JSON,第二个字符串)
    • compile 已过时,已替换为 implementation。两个库的最新版本都是 2.9.0 依赖项应该如下: implementation 'com.squareup.retrofit2:converter-scalars:2.9.0' implementation 'com.squareup.retrofit2:retrofit:2.9.0' //Adding Retrofit2
    【解决方案2】:

    我查看了 Retrofit 库,发现它根据 Call&lt;T&gt; 中的类型类解析响应。所以你有两个选择: 第一种:根据服务器的响应创建一个类。

    第二个:获取响应并自己处理(不推荐Retrofit已经处理它。那么为什么要使用Retrofit,因为它是为这项工作量身定制的)。无论如何,而不是Call&lt;String&gt; 使用Call&lt;ResponseBody&gt;Call&lt;ResponseBody&gt; signin = service.jquery(); 在此之后放置以下

    call.enqueue(new Callback<ResponseBody>() {
      @Override
      public void onResponse(Response<ResponseBody> response, Retrofit retrofit) {
        // handle success
       String result = response.body().string();
    
      }
    
      @Override
      public void onFailure(Throwable t) {
        // handle failure
      }
    });
    

    【讨论】:

    • 什么是贡献者?它找不到它。
    • 我编辑了它是 ResponseBody 其他变化是 body().string()
    • 使用 ResponseBody 代替 String 有效。谢谢@ugur
    【解决方案3】:

    要以字符串形式获取响应,您必须编写一个转换器并在初始化Retrofit时传递它。

    这里是步骤。

    初始化改造。

    Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl(API_URL_BASE)
                    .addConverterFactory(new ToStringConverterFactory())
                    .build();
            return retrofit.create(serviceClass);
    

    用于将Retrofit's ResponseBody 转换为String 的转换器类

    public class ToStringConverterFactory extends Converter.Factory {
        private static final MediaType MEDIA_TYPE = MediaType.parse("text/plain");
    
    
        @Override
        public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
                                                                Retrofit retrofit) {
            if (String.class.equals(type)) {
                return new Converter<ResponseBody, String>() {
                    @Override
                    public String convert(ResponseBody value) throws IOException
                    {
                        return value.string();
                    }
                };
            }
            return null;
        }
    
        @Override
        public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations,
                                                              Annotation[] methodAnnotations, Retrofit retrofit) {
    
            if (String.class.equals(type)) {
                return new Converter<String, RequestBody>() {
                    @Override
                    public RequestBody convert(String value) throws IOException {
                        return RequestBody.create(MEDIA_TYPE, value);
                    }
                };
            }
            return null;
        }
    }
    

    并且在执行service.jquery(); 之后,signin 将包含 JSON 响应。

    【讨论】:

      【解决方案4】:

      您可以尝试以下方法:

      build.gradle 文件:

      dependencies {
          ...
          compile 'com.squareup.retrofit2:retrofit:2.0.1'
          ...
      }
      

      WebAPIService:

      @GET("/api/values")
      Call<String> getValues();
      

      活动文件:

              Retrofit retrofit = new Retrofit.Builder()
                      .baseUrl(API_URL_BASE)                    
                      .build();
      
              WebAPIService service = retrofit.create(WebAPIService.class);
      
              Call<String> stringCall = service.getValues();
              stringCall.enqueue(new Callback<String>() {
                  @Override
                  public void onResponse(Call<String> call, Response<String> response) {
                      Log.i(LOG_TAG, response.body());
                  }
      
                  @Override
                  public void onFailure(Call<String> call, Throwable t) {
                      Log.e(LOG_TAG, t.getMessage());
                  }
              });
      

      我已经使用我的 Web 服务 (ASP.Net WebAPI) 进行了测试:

      public class ValuesController : ApiController
      {
              public string Get()
              {
                  return "value1";
              }
      }
      

      Android Logcat 输出:04-11 15:17:05.316 23097-23097/com.example.multipartretrofit I/AsyncRetrofit2: value1

      希望对你有帮助!

      【讨论】:

        【解决方案5】:
            call.enqueue(new Callback<Object>() {
                @Override
                public void onResponse(@NonNull Call<Object> call, @NonNull Response<Object> response) {
                    if (response.isSuccessful()) {
                        Gson gson = new Gson();
                        String successResponse = gson.toJson(response.body());
                        Log.d(LOG_TAG, "successResponse: " + successResponse);
                    } else {
                        try {
                            if (null != response.errorBody()) {
                                String errorResponse = response.errorBody().string();
                                Log.d(LOG_TAG, "errorResponse: " + errorResponse);
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
        
                @Override
                public void onFailure(@NonNull Call<Object> call, @NonNull Throwable t) {
                }
            });
        

        【讨论】:

          【解决方案6】:

          只需在 intercepror 中使用日志级别BODY

                  OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder()....
                  HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
                  httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
                  clientBuilder.addNetworkInterceptor(httpLoggingInterceptor);
          

          你可以在 logcat 中看到 body,如下所示:

                  D/OkHttp: {"blablabla":1,.... }
                  D/OkHttp: <-- END HTTP (1756-byte body)
          

          此解决方案仅用于调试,不适用于直接在代码中获取字符串。

          【讨论】:

            【解决方案7】:

            我更改了响应类型,而不是像这样添加 ScalarsConverterFactory

            interface YourApiService {
            @GET("/endpoint")
                fun getResponse(): Call<ResponseBody>
            }
            

            然后就可以通过

            获取字符串对象了

            val str = response.body().toString()

            【讨论】:

              【解决方案8】:

              认为现在回答可能为时已晚,只需使用response.body()?.string(),您的回复就会以字符串形式出现。

              【讨论】:

                【解决方案9】:
                String body = new String(((TypedByteArray) response.getBody()).getBytes());
                

                如果你找到了

                java.lang.ClassCastException: retrofit.client.UrlConnectionClient$TypedInputStream cannot be cast to retrofit.mime.TypedByteArray
                

                然后把它放在你的 RestAdapter 中

                .setLogLevel(RestAdapter.LogLevel.FULL)
                

                例如:

                RestAdapter restAdapter = new RestAdapter.Builder()
                            .setLogLevel(RestAdapter.LogLevel.FULL)
                            .setEndpoint(Root_url)
                            .build();
                

                【讨论】:

                  猜你喜欢
                  • 2016-06-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2017-10-13
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多