Java 如何从 Retrofit2 获取字符串响应?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36523972/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 17:57:55  来源:igfitidea点击:

How to get string response from Retrofit2?

javaandroidhttpretrofit2

提问by Matthew Darnell

I am doing android, looking for a way to do a super basic http GET/POST request. I keep getting an error:

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

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

Webservice:

网络服务:

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

then in my java:

然后在我的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();

I'm literally just trying to query jquery.org/projects with a GET request and return the String that it responds with. What is wrong?

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

If I try to implement a custom Converter (I've found a few examples online) it complains that I didn't implement the abstract method convert(F), which none of the examples do.

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

Thanks.

谢谢。

回答by ugur

I take a look at Retrofit library and noticed that it parses response according to the type class inside Call<T>. So you have two option: 1st: create a class according to the response from the server.

我看了一下 Retrofit 库,注意到它根据里面的类型类解析响应Call<T>。所以你有两个选择:第一:根据服务器的响应创建一个类。

2nd: get the response and handle it yourself (Not recommended Retrofit already handles it. So why do you use Retrofit as it is tailored for this job). Anyway instead of Call<String>use Call<ResponseBody>and Call<ResponseBody> signin = service.jquery();after this put the following

第二:得到响应并自己处理(不推荐 Retrofit 已经处理了。那么你为什么要使用 Retrofit,因为它是为这项工作量身定制的)。无论如何,而不是Call<String>使用Call<ResponseBody>Call<ResponseBody> 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
  }
});

回答by BNK

You can try the following:

您可以尝试以下操作:

build.gradlefile:

build.gradle文件:

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

WebAPIService:

网络API服务:

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

Activity file:

活动档案:

        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());
            }
        });

I have tested with my Web serivce (ASP.Net WebAPI):

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

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

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

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

Hope it helps!

希望能帮助到你!

回答by Faraz

To get the response as a String, you have to write a converterand pass it when initializing Retrofit.

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

Here are the steps.

以下是步骤。

Initializing retrofit.

初始化改造。

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

Converter class for converting Retrofit's ResponseBodyto String

转换转换器类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;
    }
}

And after executing service.jquery();, signinwill contain JSON response.

执行后service.jquery();signin将包含 JSON 响应。

回答by Neyomal

Add Retrofit2 add ScalarsConverterFactory to your Retrofit.Builder.

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

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

To use ScalarsCoverter add following dependency to your build graddle

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

compile 'com.squareup.retrofit2:converter-scalars:2.1.0'
compile 'com.squareup.retrofit2:retrofit:2.1.0' //Adding Retrofit2

For API Call use: ``

对于 API 调用使用:``

Call <String> *****

Android Code :

安卓代码:

.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();
            }
        }

回答by Android Dev

String body = new String(((TypedByteArray) response.getBody()).getBytes());

if you found

如果你发现

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

then put this in your RestAdapter

然后把它放在你的 RestAdapter 中

.setLogLevel(RestAdapter.LogLevel.FULL)

for Example:

例如:

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

回答by Imran Samed

make sure its JsonObjectnot a JSONObject

确保它JsonObject不是JSONObject

Call<JsonObject> call = api.getJsonData(url);
    call.enqueue(new Callback<JsonObject>() {
        @Override
        public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
            String str = response.body().toString();
            Log.e(TAG, "onResponse: " + str);
        }

        @Override
        public void onFailure(Call<JsonObject> call, Throwable t) {
            Log.e(TAG, "onFailure: " + t.getMessage());

        }
    });

By using JsonObjectyou can get any type of response in string format.

通过使用,JsonObject您可以获得字符串格式的任何类型的响应。

回答by Ahamadullah Saikat

    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) {
        }
    });

回答by Tapa Save

Just use log level BODYin intercepror:

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

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

And you can see body in logcat like:

你可以在 logcat 中看到 body 像:

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

This solution for debug only, not for get String directly in code.

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

回答by Joseph Daudi

thought it might be late to answer just use response.body()?.string()and you'll have your response as a string.

认为回答只是使用可能会迟到,response.body()?.string()您的回复将作为字符串。