클래스 예제에 대한 호출 어댑터를 만들 수 없습니다.
SimpleXml과 함께 retrofit 2.0.0-beta1을 사용하고 있습니다. REST 서비스에서 단순 (XML) 리소스를 검색하고 싶습니다. SimpleXML로 Simple 개체를 마샬링 / 마샬링 해제하면 잘 작동합니다.
이 코드를 사용하는 경우 (2.0.0 이전 코드로 변환 된 형식) :
final Retrofit rest = new Retrofit.Builder()
.addConverterFactory(SimpleXmlConverterFactory.create())
.baseUrl(endpoint)
.build();
SimpleService service = rest.create(SimpleService.class);
LOG.info(service.getSimple("572642"));
서비스:
public interface SimpleService {
@GET("/simple/{id}")
Simple getSimple(@Path("id") String id);
}
이 예외가 발생합니다.
Exception in thread "main" java.lang.IllegalArgumentException: Unable to create call adapter for class example.Simple
for method SimpleService.getSimple
at retrofit.Utils.methodError(Utils.java:201)
at retrofit.MethodHandler.createCallAdapter(MethodHandler.java:51)
at retrofit.MethodHandler.create(MethodHandler.java:30)
at retrofit.Retrofit.loadMethodHandler(Retrofit.java:138)
at retrofit.Retrofit$1.invoke(Retrofit.java:127)
at com.sun.proxy.$Proxy0.getSimple(Unknown Source)
내가 무엇을 놓치고 있습니까? 반품 유형을 Call
작품으로 포장하는 것을 알고 있습니다. 그러나 서비스가 비즈니스 개체를 유형으로 반환하고 동기화 모드에서 작동하기를 원합니다.
최신 정보
추가 종속성을 추가하고 .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
다른 답변에서 제안한 대로이 오류가 계속 발생합니다.
Caused by: java.lang.IllegalArgumentException: Could not locate call adapter for class simple.Simple. Tried:
* retrofit.RxJavaCallAdapterFactory
* retrofit.DefaultCallAdapter$1
짧은 대답 : Call<Simple>
서비스 인터페이스로 돌아갑니다 .
Retrofit 2.0이 서비스 인터페이스에 대한 프록시 개체를 만드는 방법을 찾으려고하는 것 같습니다. 다음과 같이 작성해야합니다.
public interface SimpleService {
@GET("/simple/{id}")
Call<Simple> getSimple(@Path("id") String id);
}
그러나 .NET Framework를 반환하고 싶지 않을 때 여전히 멋지게 재생되고 유연하기를 원합니다 Call
. 이를 지원하기 위해, 그것은의 개념이 CallAdapter
적응하는 방법을 알고 가정된다, Call<Simple>
로를 Simple
.
의 사용은 RxJavaCallAdapterFactory
반환하려는 경우에만 유용합니다 rx.Observable<Simple>
.
가장 간단한 해결책은 Call
Retrofit이 예상 하는 대로 반환하는 것입니다. CallAdapter.Factory
정말로 필요한 경우를 작성할 수도 있습니다 .
종속성 추가 :
compile 'com.squareup.retrofit:retrofit:2.0.0-beta1'
compile 'com.squareup.retrofit:adapter-rxjava:2.0.0-beta1'
compile 'com.squareup.retrofit:converter-gson:2.0.0-beta1'
다음과 같이 어댑터를 만듭니다.
Retrofit rest = new Retrofit.Builder()
.baseUrl(endpoint)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(SimpleXmlConverterFactory.create())
.build();
addCallAdapterFactory ()
그리고 addConverterFactory ()
둘 필요가 호출된다.
서비스:
public interface SimpleService {
@GET("/simple/{id}")
Call<Simple> getSimple(@Path("id") String id);
}
로 수정 Simple
하십시오 Call<Simple>
.
새로운 Retrofit (2. +)을 사용하면 addCallAdapterFactory를 추가해야합니다. 이것은 일반 또는 RxJavaCallAdapterFactory (Observables 용) 일 수 있습니다. 둘 다 추가 할 수도 있다고 생각합니다. 어떤 것을 사용할 것인지 자동으로 확인합니다. 아래의 작동 예를 참조하십시오. 자세한 내용은 이 링크 를 확인할 수도 있습니다 .
Retrofit retrofit = new Retrofit.Builder().baseUrl(ApiConfig.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build()
사용을 원 retrofit2
하고 항상 return을 원하지 않는 경우 예상대로 간단한 유형을 반환하는 retrofit2.Call<T>
자체를 만들어야합니다 CallAdapter.Factory
. 간단한 코드는 다음과 같습니다.
import retrofit2.Call;
import retrofit2.CallAdapter;
import retrofit2.Retrofit;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
public class SynchronousCallAdapterFactory extends CallAdapter.Factory {
public static CallAdapter.Factory create() {
return new SynchronousCallAdapterFactory();
}
@Override
public CallAdapter<Object, Object> get(final Type returnType, Annotation[] annotations, Retrofit retrofit) {
// if returnType is retrofit2.Call, do nothing
if (returnType.toString().contains("retrofit2.Call")) {
return null;
}
return new CallAdapter<Object, Object>() {
@Override
public Type responseType() {
return returnType;
}
@Override
public Object adapt(Call<Object> call) {
try {
return call.execute().body();
} catch (Exception e) {
throw new RuntimeException(e); // do something better
}
}
};
}
}
그런 다음 SynchronousCallAdapterFactory
Retrofit에 등록하면 문제가 해결됩니다.
Retrofit rest = new Retrofit.Builder()
.baseUrl(endpoint)
.addConverterFactory(SimpleXmlConverterFactory.create())
.addCallAdapterFactory(SynchronousCallAdapterFactory.create())
.build();
그 후 retrofit2.Call
.
public interface SimpleService {
@GET("/simple/{id}")
Simple getSimple(@Path("id") String id);
}
개조 2에 대한 다음 종속성 추가
compile 'com.squareup.retrofit2:retrofit:2.1.0'
GSON 용
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
관찰 가능한
compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'
XML의 경우 다음 종속성을 포함해야합니다.
compile 'com.squareup.retrofit2:converter-simplexml:2.1.0'
아래와 같이 서비스 콜을 업데이트하십시오.
final Retrofit rest = new Retrofit.Builder()
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(SimpleXmlConverterFactory.create())
.baseUrl(endpoint)
.build();
SimpleService service = rest.create(SimpleService.class);
제 경우에는 이것을 사용하여
compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
이것으로
new Retrofit.Builder().addCallAdapterFactory(RxJava2CallAdapterFactory.create())...
아무것도 작동하지 않을 때 문제를 해결했습니다.
마이그레이션 중이거나 Rx를 사용하지 않는 사용자 또는 동기 호출을 원하는 사용자를 위해 Call 예제를 더 명확하게 만들기 위해 Call은 기본적으로 응답을 대체 (래핑)합니다.
Response<MyObject> createRecord(...);
된다
Call<MyObject> createRecord(...);
그리고 아닙니다
Call<Response<MyObject>> createRecord(...);
(아직 어댑터가 필요함)
그러면 호출이 isSuccessful
실제로 응답을 반환하므로 계속 사용할 수 있습니다 . 따라서 다음과 같이 할 수 있습니다.
myApi.createRecord(...).execute().isSuccessful()
또는 다음과 같이 유형 (MyObject)에 액세스합니다.
MyObject myObj = myApi.createRecord(...).execute().body();
RxJava를 사용하지 않는 경우 개조를 위해 RxJava를 추가하는 것은 적절하지 않습니다. 다른 라이브러리 나 어댑터를 추가하지 않고도 사용할 수있는 내장 2.5.0
지원 CompletableFuture
이 있습니다.
build.gradle.kts
implementation("com.squareup.retrofit2:retrofit:2.5.0")
implementation("com.squareup.retrofit2:retrofit-converters:2.5.0")
Api.kt
interface Api {
@GET("/resource")
fun listCompanies(): CompletableFuture<ResourceDto>
}
용법:
Retrofit.Builder()
.addConverterFactory(SimpleXmlConverterFactory.create())
.baseUrl("https://api.example.com")
.build()
.create(Api::class.java)
콜백을 구현하고 onResponse 함수에서 Simple을 얻을 수 있습니다.
public class MainActivity extends Activity implements Callback<Simple> {
protected void onCreate(Bundle savedInstanceState) {
final Retrofit rest = new Retrofit.Builder()
.addConverterFactory(SimpleXmlConverterFactory.create())
.baseUrl(endpoint)
.build();
SimpleService service = rest.create(SimpleService.class);
Call<Simple> call = service.getSimple("572642");
//asynchronous call
call.enqueue(this);
return true;
}
@Override
public void onResponse(Response<Simple> response, Retrofit retrofit) {
// response.body() has the return object(s)
}
@Override
public void onFailure(Throwable t) {
// do something
}
}
public interface SimpleService {
@GET("/simple/{id}")
Simple getSimple(@Path("id") String id);
}
Communication with the network is done with the separate thread so you should change your Simple with that.
public interface SimpleService {
@GET("/simple/{id}")
Call<Simple> getSimple(@Path("id") String id);
}
In my case I used
com.squareup.retrofit2:adapter-rxjava:2.5.0 //notice rxjava
instead of
com.squareup.retrofit2:adapter-rxjava2:2.5.0 //notice rxjava2
you should be using com.squareup.retrofit2:adapter-rxjava2:2.5.0
when using io.reactivex.rxjava2
The way I fixed this issue was adding this to the application gradle file, if the configuration is not set there will be conflicts, maybe this will be fixed in the stable release of the library:
configurations {
compile.exclude group: 'stax'
compile.exclude group: 'xpp3'
}
dependencies {
compile 'com.squareup.retrofit:retrofit:2.0.0-beta1'
compile 'com.squareup.retrofit:converter-simplexml:2.0.0-beta1'
}
and create your adapter this way:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(endPoint)
.addConverterFactory(SimpleXmlConverterFactory.create())
.build();
Hope it helps!
참고URL : https://stackoverflow.com/questions/32269064/unable-to-create-call-adapter-for-class-example-simple
'Program Tip' 카테고리의 다른 글
파이썬의 urllib를 사용하여 헤더를 어떻게 설정합니까? (0) | 2020.11.16 |
---|---|
파일에서 읽고 utf-8에 저장하는 Python (0) | 2020.11.16 |
PHP : 분할 문자열 (0) | 2020.11.16 |
내 루트 MySQL 암호를 어떻게 찾습니까? (0) | 2020.11.16 |
TextWrangler에서 탭을 4 개의 공백으로 자동 변환 하시겠습니까? (0) | 2020.11.16 |