ventanas ventana una tiempo para metodo interfaz hacer grafica ejecutar crear como codigo clase cierto cada java rest retrofit simple-framework

ventana - interfaz grafica java swing



No se puede crear el adaptador de llamada para el ejemplo de clase. (12)

Estoy usando retrofit 2.0.0-beta1 con SimpleXml. Quiero recuperar un recurso Simple (XML) de un servicio REST. Alinear / Descomponer el objeto Simple con SimpleXML funciona bien.

Al usar este código (código convertido de forma pre 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"));

Servicio:

public interface SimpleService { @GET("/simple/{id}") Simple getSimple(@Path("id") String id); }

Me sale esta excepción:

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)

¿Qué me estoy perdiendo? Sé que envolver el tipo de retorno por una Call funciona. Pero quiero que el servicio devuelva objetos comerciales como tipo (y que funcione en modo de sincronización).

ACTUALIZAR

Después de agregar las dependencias adicionales y .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) como lo sugieren diferentes respuestas, sigo recibiendo este error:

Caused by: java.lang.IllegalArgumentException: Could not locate call adapter for class simple.Simple. Tried: * retrofit.RxJavaCallAdapterFactory * retrofit.DefaultCallAdapter$1


Agregue las siguientes dependencias para la actualización 2

compile ''com.squareup.retrofit2:retrofit:2.1.0''

para GSON

compile ''com.squareup.retrofit2:converter-gson:2.1.0''

para observables

compile ''com.squareup.retrofit2:adapter-rxjava:2.1.0''

En su caso para XML, debería incluir las siguientes dependencias

compile ''com.squareup.retrofit2:converter-simplexml:2.1.0''

Actualice la llamada de servicio de la siguiente manera

final Retrofit rest = new Retrofit.Builder() .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .addConverterFactory(SimpleXmlConverterFactory.create()) .baseUrl(endpoint) .build(); SimpleService service = rest.create(SimpleService.class);


Con el nuevo Retrofit (2. +) necesita agregar addCallAdapterFactory, que puede ser normal o RxJavaCallAdapterFactory (para Observables). Creo que también puedes agregar más que ambos. Comprueba automáticamente cuál usar. Vea un ejemplo de trabajo a continuación. También puede consultar este enlace para más detalles.

Retrofit retrofit = new Retrofit.Builder().baseUrl(ApiConfig.BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .build()


En mi caso usé

com.squareup.retrofit2:adapter-rxjava:2.5.0 //notice rxjava

en lugar de

com.squareup.retrofit2:adapter-rxjava2:2.5.0 //notice rxjava2

debería usar com.squareup.retrofit2:adapter-rxjava2:2.5.0 cuando usa io.reactivex.rxjava2


La forma en que solucioné este problema fue agregando esto al archivo gradle de la aplicación, si la configuración no está configurada habrá conflictos, tal vez esto se solucionará en la versión estable de la biblioteca:

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'' }

y crea tu adaptador de esta manera:

Retrofit retrofit = new Retrofit.Builder() .baseUrl(endPoint) .addConverterFactory(SimpleXmlConverterFactory.create()) .build();

¡Espero eso ayude!


Puede implementar una devolución de llamada, obtener la función Simple de onResponse.

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


Respuesta corta: devuelve Call<Simple> en tu interfaz de servicio.

Parece que Retrofit 2.0 está tratando de encontrar una forma de crear el objeto proxy para su interfaz de servicio. Espera que escribas esto:

public interface SimpleService { @GET("/simple/{id}") Call<Simple> getSimple(@Path("id") String id); }

Sin embargo, todavía quiere jugar bien y ser flexible cuando no desea devolver una Call . Para respaldar esto, tiene el concepto de un CallAdapter , que se supone que sabe cómo adaptar una Call<Simple> a Simple .

El uso de RxJavaCallAdapterFactory solo es útil si está intentando devolver rx.Observable<Simple> .

La solución más simple es devolver una Call como espera Retrofit. También puede escribir un CallAdapter.Factory si realmente lo necesita.


Si desea utilizar retrofit2 y no siempre desea devolver retrofit2.Call<T> , debe crear su propio CallAdapter.Factory que devuelve el tipo simple como esperaba. El código simple puede verse así:

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

Luego, el simple registro de SynchronousCallAdapterFactory en Retrofit debería resolver su problema.

Retrofit rest = new Retrofit.Builder() .baseUrl(endpoint) .addConverterFactory(SimpleXmlConverterFactory.create()) .addCallAdapterFactory(SynchronousCallAdapterFactory.create()) .build();

Después de eso, puede devolver el tipo simple sin retrofit2.Call .

public interface SimpleService { @GET("/simple/{id}") Simple getSimple(@Path("id") String id); }


Si no está utilizando RxJava, no tiene sentido agregar RxJava solo para la actualización. 2.5.0 tiene soporte para CompletableFuture integrado en el que puede usar sin agregar ninguna otra biblioteca o adaptador.

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

Uso:

Retrofit.Builder() .addConverterFactory(SimpleXmlConverterFactory.create()) .baseUrl("https://api.example.com") .build() .create(Api::class.java)


Solo para aclarar los ejemplos de llamadas para las personas que están migrando, que no usan Rx o que desean llamadas sincrónicas: la llamada esencialmente reemplaza (ajusta) la respuesta, lo que significa:

Response<MyObject> createRecord(...);

se convierte

Call<MyObject> createRecord(...);

y no

Call<Response<MyObject>> createRecord(...);

(que aún requerirá un adaptador)

La Llamada le permitirá seguir usando isSuccessful ya que en realidad devuelve una Respuesta. Entonces puedes hacer algo como:

myApi.createRecord(...).execute().isSuccessful()

O acceda a su Tipo (MyObject) como:

MyObject myObj = myApi.createRecord(...).execute().body();


agregar dependencias:

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''

cree su adaptador de esta manera:

Retrofit rest = new Retrofit.Builder() .baseUrl(endpoint) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .addConverterFactory(SimpleXmlConverterFactory.create()) .build();

addCallAdapterFactory () y addConverterFactory () necesitan ser llamados.

Servicio:

public interface SimpleService { @GET("/simple/{id}") Call<Simple> getSimple(@Path("id") String id); }

Modifique Simple to Call<Simple> .


en mi caso usando esto

compile ''com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0''

con este

new Retrofit.Builder().addCallAdapterFactory(RxJava2CallAdapterFactory.create())...

resolvió el problema cuando nada más funcionaba


public interface SimpleService { @GET("/simple/{id}") Simple getSimple(@Path("id") String id); }

La comunicación con la red se realiza con el hilo separado, por lo que debe cambiar su Simple con eso.

public interface SimpleService { @GET("/simple/{id}") Call<Simple> getSimple(@Path("id") String id); }