私は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)を実装しなかったと文句を言います。
ありがとう。
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();
}
}
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
}
});
_
応答を文字列として取得するには、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応答が含まれます。
以下を試すことができます:
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
それが役に立てば幸い!
JsonObject
が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());
}
});
JsonObject
を使用することにより、文字列形式であらゆるタイプの応答を取得できます。
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();
response.body()?.string()
を使用するだけで答えるのが遅れるかもしれないと思ったので、文字列として応答します。
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) {
}
});