Как получить строковый ответ от Retrofit2?

Я делаю андроид, ища способ сделать супер базовый запрос HTTP GET/POST. Я получаю сообщение об ошибке:

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

Webservice:

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

Я буквально просто пытаюсь запросить jquery.org/projects с помощью запроса GET и вернуть строку, на которую он отвечает. Что не так?

Если я попытаюсь реализовать собственный конвертер (я нашел несколько примеров в Интернете), он жалуется, что я не реализовал абстрактный метод convert (F), который ни один из примеров не делает.

Спасибо.

Ответ 1

С Retrofit2 добавьте ScalarsConverterFactory в ваш Retrofit.Builder.

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

Чтобы использовать ScalarsCoverter, добавьте следующую зависимость к вашему конструктору graddle

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

Для использования API-вызовов: ``

Call <String> *****

Код Android:

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

Ответ 2

Я просматриваю библиотеку Retrofit и замечаю, что он анализирует ответ в соответствии с типом класса внутри Call<T>. Таким образом, у вас есть два варианта: 1-й: создать класс в соответствии с ответом сервера.

2nd: получите ответ и обработайте его самостоятельно (не рекомендуется, чтобы эта настройка уже обрабатывала его. Так почему вы используете 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
  }
});

Ответ 3

Чтобы получить ответ как String, вам нужно написать конвертер и передать его при инициализации Retrofit.

Вот шаги.

Инициализация модификации.

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

Класс конвертера для преобразования Retrofit 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());
            }
        });

Я тестировал свой веб-сервис (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

Надеюсь, что это поможет!

Ответ 5

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