web-dev-qa-db-ja.com

Retrofit2から文字列応答を取得する方法は?

私はAndroidをやっており、超基本的なhttp GET/POSTリクエストを行う方法を探しています。エラーが発生し続けます:

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

ウェブサービス:

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

私は文字通り、GETリクエストでjquery.org/projectsをクエリし、それが応答するStringを返そうとしています。なにが問題ですか?

カスタムコンバーターを実装しようとすると(オンラインでいくつかの例を見つけました)、抽象メソッドconvert(F)を実装しなかったと文句を言います。

ありがとう。

28
Matthew Darnell

Retrofit2を使用して、ScalarsConverterFactoryをRetrofit.Builderに追加します。

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

ScalarsCoverterを使用するには、ビルドグラドルに次の依存関係を追加します

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

Retrofitライブラリを見ると、_Call<T>_内の型クラスに従って応答を解析していることがわかりました。したがって、2つのオプションがあります。1番目:サーバーからの応答に応じてクラスを作成します。

2番目:応答を取得して自分で処理します(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
  }
});
_
7
ugur

応答を文字列として取得するには、converterを記述し、Retrofitを初期化するときにそれを渡す必要があります。

手順は次のとおりです。

レトロフィットの初期化。

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

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

service.jquery();を実行すると、signinにJSON応答が含まれます。

5
FAЯAƸ

以下を試すことができます:

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

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

それが役に立てば幸い!

4
BNK

JsonObjectJSONObjectではないことを確認してください

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

        }
    });

JsonObjectを使用することにより、文字列形式であらゆるタイプの応答を取得できます。

0
Imran Samed
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();
0
Hardik Lakhani

response.body()?.string()を使用するだけで答えるのが遅れるかもしれないと思ったので、文字列として応答します。

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