Get String response body from retrofit2

14,612

Solution 1

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.

Solution 2

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.

Share:
14,612
Muhammad Umar
Author by

Muhammad Umar

Updated on June 26, 2022

Comments

  • Muhammad Umar
    Muhammad Umar almost 2 years

    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?

  • Ankit Aggarwal
    Ankit Aggarwal about 8 years
    for error check your imports. all your imports should be from retrofit2 and okhttp3 instead of retrofit
  • Muhammad Umar
    Muhammad Umar about 8 years
    I have checked all imorts are retrofit2, however one more important thing, should i do Call<String>login(xxxx) ?
  • Muhammad Umar
    Muhammad Umar about 8 years
    Yes thanks, its good, however the second override function doesnt seem to be ok, if u can please check it, i can't find same params even in superclass
  • Ankit Aggarwal
    Ankit Aggarwal about 8 years
    which beta version of retrofit2 are you using? try to use beta3. also put the imports as i posted. Those are working for me
  • Ankit Aggarwal
    Ankit Aggarwal over 7 years
    @andro The above code was for beta-3. Check the edit for updated code for retrofit 2.1.0
  • ergo
    ergo over 7 years
    thnx man, it's help me to get 340 288 characters of crypt string.
  • Lokesh
    Lokesh over 4 years
    how to ScalarsConverterFactory please add that in answer