web-dev-qa-db-fra.com

Une annotation de méthode HTTP de rattrapage 2 est requise (par exemple, @GET, @POST, etc.)

Quel est le problème avec ma configuration Retrofit? J'ai cette erreur lorsque j'ajoute une authentification de base avec OkHttpClient, mais lorsque j'utilise le client par défaut sans Interceptor, cela fonctionne. Ou y a-t-il un problème avec mes dépendances Gradle?

E/AndroidRuntime﹕ FATAL EXCEPTION: main
        Java.lang.IllegalArgumentException
    : HTTP method annotation is required (e.g., @GET, @POST, etc.).
            for method APIService.getRegAccrDetails
                    at retrofit.Utils.methodError(Utils.Java:177)
                    at retrofit.Utils.methodError(Utils.Java:167)
                    at retrofit.RequestFactoryParser.parseMethodAnnotations(RequestFactoryParser.Java:135)
                    at retrofit.RequestFactoryParser.parse(RequestFactoryParser.Java:59)
                    at retrofit.MethodHandler.create(MethodHandler.Java:30)
                    at retrofit.Retrofit.loadMethodHandler(Retrofit.Java:151)
                    at retrofit.Retrofit$1.invoke(Retrofit.Java:132)
                    at $Proxy0.getRegAccrDetails(Native Method)
                    at alvin.test.myapplication.MainActivity.liferayAccess(MainActivity.Java:136)
                    at alvin.test.myapplication.MainActivity.access$000(MainActivity.Java:28)
                    at alvin.test.myapplication.MainActivity$1.onClick(MainActivity.Java:49)
                    at Android.view.View.performClick(View.Java:3511)
                    at Android.view.View$PerformClick.run(View.Java:14105)
                    at Android.os.Handler.handleCallback(Handler.Java:605)
                    at Android.os.Handler.dispatchMessage(Handler.Java:92)
                    at Android.os.Looper.loop(Looper.Java:137)
                    at Android.app.ActivityThread.main(ActivityThread.Java:4424)
                    at Java.lang.reflect.Method.invokeNative(Native Method)
                    at Java.lang.reflect.Method.invoke(Method.Java:511)
                    at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:784)
                    at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:551)
                    at dalvik.system.NativeStart.main(Native Method)

Voici mon service API à appeler

  @GET("Triu-services-portlet.regaccrdetails/get-all-reg-accr-details-by-num-branch-code/num/{num}/branch-code/{branch-code}")
    public Observable<List<RegAccrDetails>> getRegAccrDetails(@Path("num") String num, @Path("branch-code")String branchCode);

Mon intercepteur OkHttpClient

private static OkHttpClient createOkHttpClient() {
   String username = "[email protected]";
   String password = "TEST";
   String credentials = username + ":" + password;
   final String basic =
           "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.DEFAULT);//no_wrap



    OkHttpClient client = new OkHttpClient();
    client.interceptors().add(new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Response response = chain.proceed(chain.request());

            Request original = chain.request();

            // Customize the request
            Request request = original.newBuilder()
                    .header("Authorization", basic)
                    .header("Accept", "application/json")
                    //.header("Authorization", "auth-token")//add token for service A4oslsSXZxfbLdk
                    .method(original.method(), original.body())
                    .build();

            response = chain.proceed(request);

            // Customize or return the response
            return response;
        }
    });

   return client;
}

Voici mon appel pour mon API

private void liferayAccess(){
    Log.d("liferayAccess", "Entered");
    APIService service =  ServiceGenerator.createService(APIService.class);
    Observable<List<RegAccrDetails>> liferayResponse = service.getRegAccrDetails("004589209", "001");

    liferayResponse.subscribeOn(Schedulers.newThread()).map(listResponse -> "response index 0 " + listResponse.get(0).getRegNum())
            .subscribe( response-> Log.d("Liferay Num", response),
                        error -> Log.d("Error", error.toString())
                    );
}

Voici mes dépendances Gradle

 compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.Android.support:appcompat-v7:23.1.1'

compile 'io.reactivex:rxjava:1.0.16'
compile 'io.reactivex:rxandroid:1.1.0'
compile 'com.squareup.retrofit:adapter-rxjava:2.0.0-beta2'
compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2'

//compile 'com.squareup.retrofit:converter-simplexml:2.0.0-beta2'
/*compile 'com.squareup.okhttp:okhttp:2.2.0'*/
compile ('com.squareup.retrofit2:retrofit:2.0.0-beta3') {//com.squareup.retrofit2:retrofit:2.0.0-beta3
    // exclude Retrofit’s OkHttp peer-dependency module and define your own module import
    //exclude module: 'okhttp'
}
compile 'com.squareup.okhttp3:okhttp:3.0.0'
compile 'com.squareup.okhttp3:logging-interceptor:3.0.1'

Voici mon fichier Gradle App

apply plugin: 'com.Android.application'
apply plugin: 'me.tatarka.retrolambda'
Android {
    compileSdkVersion 23
    buildToolsVersion "23.0.2"

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    packagingOptions {
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/NOTICE'
    }




    defaultConfig {
        applicationId "alvin.test.myapplication"
        minSdkVersion 15
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-Android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.Android.support:appcompat-v7:23.1.1'

    compile 'io.reactivex:rxjava:1.0.16'
    compile 'io.reactivex:rxandroid:1.1.0'
    compile 'com.squareup.retrofit:adapter-rxjava:2.0.0-beta2'
    compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2'

    //compile 'com.squareup.retrofit:converter-simplexml:2.0.0-beta2'
    /*compile 'com.squareup.okhttp:okhttp:2.2.0'*/
    compile ('com.squareup.retrofit2:retrofit:2.0.0-beta3') {//com.squareup.retrofit2:retrofit:2.0.0-beta3
        // exclude Retrofit’s OkHttp peer-dependency module and define your own module import
        //exclude module: 'okhttp'
    }
    compile 'com.squareup.okhttp3:okhttp:3.0.0'
    compile 'com.squareup.okhttp3:logging-interceptor:3.0.1'

    //compile 'com.squareup.retrofit:retrofit:2.0.0-beta2'
    compile 'com.google.Android.gms:play-services-gcm:7.3.0'
    compile 'com.google.Android.gms:play-services:7.8.0'
}
retrolambda {
    jdk "C:\\Program Files\\Java\\jdk1.8.0_20"
}

Mon Proguard. J'ai également essayé d'ajouter et de le supprimer, mais le même journal d'erreur se produit

-keepattributes *Annotation*
-keep class retrofit.** { *; }
-keepclasseswithmembers class * {
@retrofit.http.* <methods>; }
-keepattributes Signature


-keep class com.google.gson.** { *; }
-keep class com.google.inject.** { *; }
-keep class org.Apache.http.** { *; }
-keep class org.Apache.james.mime4j.** { *; }
-keep class javax.inject.** { *; }
-keep class retrofit.** { *; }
12
DreamBigAlvin

Problème

Vous utilisez des versions bêta2 de plug-ins de modification, qui dépendent de la version bêta2 de la modification, qui existe toujours dans le package com.squreup.retrofit.

compile 'com.squareup.retrofit:adapter-rxjava:2.0.0-beta2'
compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2'

Ensuite, vous importez la version beta3 de retrofit elle-même, qui réside dans le package retrofit2. Fondamentalement, il peut être utilisé avec la version beta2.

compile 'com.squareup.retrofit2:retrofit:2.0.0-beta3'

Vous n'utilisez pas du tout la beta3, car elle est incompatible avec les plugins beta2 et vous risquez des erreurs de compilation. Vérifiez vos importations pour vérifier.

Ce qui s’est passé, c’est (très probablement) que vous utilisez tout du paquet com.square.retrofit à l’exception de la classe @GET qui provient du paquet retrofit2. Malgré leur nom identique, ces classes ne sont pas les mêmes.

Solution

Déplacer vers les packages beta4 et retrofit2. Fixez vos importations. Profit.

compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4'
compile 'com.squareup.retrofit2:adapter-rxjava:2.0.0-beta4'
compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4'
10
Eugen Pechanec

Utiliser le mauvais "@GET"

Cela peut aider quelqu'un venant de retrofit1, je recevais la même erreur et le correctif était simple. Dans mon interface, je ne savais pas que j'utilisais @GET de retrofit.http et non pas @GET de retrofit2.http, changer l'annotation de retrofit.http en retrofit2.http était tout ce que j'avais à faire.

 enter image description here

36
Jraco11

On dirait que vous utilisez proguard et que vous supprimez les annotations. Pour en enregistrer des nouvelles, ajoutez ces lignes à votre proguard-rules.pro

-keepattributes *Annotation*
-keep class retrofit.** { *; }
-keepclasseswithmembers class * {
@retrofit.http.* <methods>; }
-keepattributes Signature

si vous n’utilisez pas proguard, assurez-vous que vous n’avez pas écrit quelque chose dans votre application build.gradle quelque chose comme ça

buildTypes {
    release {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-Android-optimize.txt'), 'proguard-rules.pro'
    }
}

Remarque: Android ne vient pas normalement avec la plupart des bibliothèques javax.annotation par défaut.

si ce n'est pas le cas, essayez d'ajouter ceci dans votre dépendance de gradle (build.gradle).

provided 'org.glassfish:javax.annotation:10.0-b28'
4
Harsh Sharma

Comme Eugen Pechanec l'a déclaré, le problème réside généralement dans un conflit entre la mise à niveau et la mise à niveau 2. Dans mon cas, l'erreur "l'annotation de la méthode HTTP est requise @GET @POST" a été provoquée par l'utilisation d'une structure incorrecte Builder of HTTPLoggingInterceptor.

Par conséquent, assurez-vous d'utiliser okhttp3 avec retrofit2  

Donc, la bonne structure ressemble à THIS :

import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

...

Retrofit provideRetrofit(){

// get base url for endpoint
String endpointUrl = BuildConfig.apiEndpointUrl;

// add logging interceptor
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(logging).build();

// build retrofit instance
Retrofit retrofit = new Retrofit.Builder()
        .baseUrl(endpointUrl)
        .client(client)
        .addConverterFactory(GsonConverterFactory.create())
        .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
        .build();

return retrofit;
}

Et l'application/build.gradle

compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4'
compile 'com.squareup.retrofit2:adapter-rxjava:2.0.0-beta4'
compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4'
compile 'com.squareup.okhttp3:logging-interceptor:3.2.0'
compile 'com.squareup.okhttp3:okhttp:3.2.0'
0
murt