Get String response body from retrofit2

2019-02-15 07:46发布

I am using retrofit1 old style

@GET("/loginUser")
    public Call<Response> login(
            @Query("email") String email,
            @Query("password") String password,
            Callback<Response> callback);

Now i don't want to get "User" class however i want to get a String response.

Previously we were using "Response" However there is no Response in retrofit2,

How can i get string response or full body response from the server without using any json parsing?

3条回答
地球回转人心会变
2楼-- · 2019-02-15 08:24
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(API_BASE_URL)
                .client(getClient())
                .addConverterFactory(ScalarsConverterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .build();

ScalarsConverterFactory above GsonConverterFactory

查看更多
女痞
3楼-- · 2019-02-15 08:29

Create this class

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;

import okhttp3.MediaType;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Converter;
import retrofit2.Retrofit;

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[] annotations, 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;
    }
}

use it with

Retrofit retrofit = new Retrofit.Builder()
                        .addConverterFactory(new ToStringConverterFactory())
                        .build();

EDIT: You have to define it as

@GET("/loginUser")
    public Call<String> login(
            @Query("email") String email,
            @Query("password") String password);

There is no callback supported in retrofit2 so you have to remove that. To make it asynchronous, you have to do

Call<String> call = service.login(username, password);
call.enqueue(new Callback<String>() {}

EDIT The above code was for retrofit2 beta 3. For retrofit:2.1.0, you have to create ToStringConverterFactory as -

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;

import okhttp3.MediaType;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Converter;
import retrofit2.Retrofit;

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

GOOD TO KNOW: Incase you want to have multiple converters (e.g. a String converter as shown above and also a GSON converter):
Make sure you specify the special-purpose converters first (e.g. String converter) and general converters (like Gson) last!

Converters will be called by the order they have been added, if a converter consumed the response, the follwoing converters will not be called.

查看更多
再贱就再见
4楼-- · 2019-02-15 08:47

Retrofit 2.0.0-beta3 adds a converter-scalars module provides a Converter.Factory for converting String, the 8 primitive types, and the 8 boxed primitive types as text/plain bodies. Install this before your normal converter to avoid passing these simple scalars through, for example, a JSON converter.

查看更多
登录 后发表回答