web-dev-qa-db-fra.com

Comment obtenir une réponse en chaîne de Retrofit2?

Je fais Android, cherchant un moyen de faire une requête HTTP GET/POST super basique. Je continue d'avoir une erreur:

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

Service Web:

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

puis dans mon 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();

J'essaie littéralement d'interroger jquery.org/projects avec une demande GET et de renvoyer la chaîne avec laquelle il répond. Qu'est-ce qui ne va pas?

Si j'essaie d'implémenter un convertisseur personnalisé (j'ai trouvé quelques exemples en ligne), il se plaint de ne pas avoir implémenté la méthode abstraite convert (F), ce qu'aucun exemple ne fait.

Merci.

21
Matthew Darnell

Avec Retrofit2, ajoutez ScalarsConverterFactory à votre Retrofit.Builder.

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

Pour utiliser ScalarsCoverter, ajoutez la dépendance suivante à votre génération.

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

Pour l'appel API, utilisez: ``

Call <String> *****

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

J'ai jeté un coup d'œil à la bibliothèque Retrofit et j'ai constaté qu'elle analysait la réponse en fonction de la classe de type dans Call<T>. Vous avez donc deux options: 1er: créez une classe en fonction de la réponse du serveur.

2e: obtenez la réponse et gérez-la vous-même (Non recommandé Retrofit la gère déjà. Alors pourquoi utilisez-vous Retrofit car il est adapté à ce travail). Quoi qu’il en soit, au lieu de Call<String>, utilisez Call<ResponseBody> et Call<ResponseBody> signin = service.jquery(); après cela, mettez ce qui suit: 

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

Pour obtenir la réponse sous forme de chaîne, vous devez écrire un convertisseur et le transmettre lors de l'initialisation de Retrofit.

Voici les étapes.

Initialisation de la modernisation.

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

Classe de conversion pour convertir Retrofit's ResponseBody en 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;
    }
}

Et après l'exécution de service.jquery();, signin contiendra une réponse JSON. 

4
FAЯAƸ

Vous pouvez essayer ce qui suit:

build.gradle fichier:

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

WebAPIService:

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

Fichier d'activité:

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

J'ai testé avec mon service Web (ASP.Net WebAPI):

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

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

J'espère que ça aide!

3
BNK
    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) {
        }
    });
1
Ahamadullah Saikat

assurez-vous que sa JsonObject n'est pas une 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());

        }
    });

En utilisant JsonObject, vous pouvez obtenir tout type de réponse au format chaîne.

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

si vous avez trouvé

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

puis mettez ceci dans votre RestAdapter

                .setLogLevel(RestAdapter.LogLevel.FULL)

par exemple:

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

pensé qu'il pourrait être tard pour répondre, utilisez simplement response.body()?.string() et vous obtiendrez votre réponse sous forme de chaîne.

0
Joseph Daudi