Retrofit 2 需要HTTP方法注解(如@GET、@POST等)
Retrofit 2 HTTP method annotation is required (e.g., @GET, @POST, etc.)
我的 Retrofit 配置有什么问题?当我使用 OkHttpClient 添加基本身份验证时出现此错误,但是当我使用没有拦截器的默认客户端时它正在工作。还是我的 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.invoke(Retrofit.java:132)
at $Proxy0.getRegAccrDetails(Native Method)
at alvin.test.myapplication.MainActivity.liferayAccess(MainActivity.java:136)
at alvin.test.myapplication.MainActivity.access[=11=]0(MainActivity.java:28)
at alvin.test.myapplication.MainActivity.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)
这是我要调用的 API 服务
@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);
我的 OkHttpClient 拦截器
private static OkHttpClient createOkHttpClient() {
String username = "test@liferay.com";
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;
}
这是我对 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())
);
}
Here is my Gradle 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'
Here is my App Gradle File
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"
}
My Proguard. I also tried add and remove it but same error log happen
-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.** { *; }
您似乎在使用 proguard,它正在剥离注释。
要从中保存,请将此行添加到您的 proguard-rules.pro
-keepattributes *Annotation*
-keep class retrofit.** { *; }
-keepclasseswithmembers class * {
@retrofit.http.* <methods>; }
-keepattributes Signature
如果不使用混淆器,请确保您没有在您的应用程序中编写任何东西build.gradle 像这样的东西
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
Note: Android does not come normally with many of the javax.annotation library by default.
如果不是这样,请尝试将其添加到您的 gradle 依赖项中 (build.gradle)
provided 'org.glassfish:javax.annotation:10.0-b28'
问题
您正在使用 beta2 版本的 retrofit 插件,它依赖于 beta2 版本的 retrofit,它仍然存在于 com.squreup.retrofit
包中。
compile 'com.squareup.retrofit:adapter-rxjava:2.0.0-beta2'
compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2'
然后您将导入位于 retrofit2
包中的改造本身的 beta3 版本。基本上它可以和beta2版本一起使用。
compile 'com.squareup.retrofit2:retrofit:2.0.0-beta3'
您根本没有真正使用 beta3,因为它与 beta2 插件不兼容,并且您会遇到编译时错误。检查您的导入以进行验证。
发生的事情(很可能)是您使用了 com.square.retrofit
包中的所有内容,除了来自 retrofit2
包的 @GET
class。尽管它们的名称相同,但这些 class 并不相同。
解决方案
移动到 beta4 和 retrofit2
包。修复你的进口。利润。
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'
使用错误的“@GET”
这可能对来自 retrofit1 的人有所帮助,我也遇到了同样的错误,修复很简单。在我的界面中,我没有意识到我使用的是来自 retrofit.http 的 @GET 而不是来自 retrofit2.http 的 @GET,我需要做的就是将注释从 retrofit.http 更改为 retrofit2.http .
正如 Eugen Pechanec 所说,问题通常在于改造和改造 2 之间的冲突。在我的例子中,错误“需要 HTTP 方法注释@GET @POST " 是由于使用 HTTPLoggingInterceptor.
的错误结构生成器引起的
因此请确保您使用的是 okhttp3 和 retrofit2
所以正确的结构看起来像 :
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;
}
还有 app/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'
我的 Retrofit 配置有什么问题?当我使用 OkHttpClient 添加基本身份验证时出现此错误,但是当我使用没有拦截器的默认客户端时它正在工作。还是我的 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.invoke(Retrofit.java:132)
at $Proxy0.getRegAccrDetails(Native Method)
at alvin.test.myapplication.MainActivity.liferayAccess(MainActivity.java:136)
at alvin.test.myapplication.MainActivity.access[=11=]0(MainActivity.java:28)
at alvin.test.myapplication.MainActivity.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)
这是我要调用的 API 服务
@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);
我的 OkHttpClient 拦截器
private static OkHttpClient createOkHttpClient() {
String username = "test@liferay.com";
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;
}
这是我对 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())
);
}
Here is my Gradle 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'
Here is my App Gradle File
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"
}
My Proguard. I also tried add and remove it but same error log happen
-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.** { *; }
您似乎在使用 proguard,它正在剥离注释。 要从中保存,请将此行添加到您的 proguard-rules.pro
-keepattributes *Annotation* -keep class retrofit.** { *; } -keepclasseswithmembers class * { @retrofit.http.* <methods>; } -keepattributes Signature
如果不使用混淆器,请确保您没有在您的应用程序中编写任何东西build.gradle 像这样的东西
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
Note: Android does not come normally with many of the javax.annotation library by default.
如果不是这样,请尝试将其添加到您的 gradle 依赖项中 (build.gradle)
provided 'org.glassfish:javax.annotation:10.0-b28'
问题
您正在使用 beta2 版本的 retrofit 插件,它依赖于 beta2 版本的 retrofit,它仍然存在于 com.squreup.retrofit
包中。
compile 'com.squareup.retrofit:adapter-rxjava:2.0.0-beta2'
compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2'
然后您将导入位于 retrofit2
包中的改造本身的 beta3 版本。基本上它可以和beta2版本一起使用。
compile 'com.squareup.retrofit2:retrofit:2.0.0-beta3'
您根本没有真正使用 beta3,因为它与 beta2 插件不兼容,并且您会遇到编译时错误。检查您的导入以进行验证。
发生的事情(很可能)是您使用了 com.square.retrofit
包中的所有内容,除了来自 retrofit2
包的 @GET
class。尽管它们的名称相同,但这些 class 并不相同。
解决方案
移动到 beta4 和 retrofit2
包。修复你的进口。利润。
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'
使用错误的“@GET”
这可能对来自 retrofit1 的人有所帮助,我也遇到了同样的错误,修复很简单。在我的界面中,我没有意识到我使用的是来自 retrofit.http 的 @GET 而不是来自 retrofit2.http 的 @GET,我需要做的就是将注释从 retrofit.http 更改为 retrofit2.http .
正如 Eugen Pechanec 所说,问题通常在于改造和改造 2 之间的冲突。在我的例子中,错误“需要 HTTP 方法注释@GET @POST " 是由于使用 HTTPLoggingInterceptor.
的错误结构生成器引起的因此请确保您使用的是 okhttp3 和 retrofit2
所以正确的结构看起来像
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;
}
还有 app/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'