在Retrofit 2中,必须返回表示http方法的服务方法Call.
Call 是一个泛型,必须采用表示http方法的返回对象的类型.
例如,
@GET("/members/{id}")
Call<Member> getMember(@Path("id") Long id);
Run Code Online (Sandbox Code Playgroud)
对于诸如删除之类的http方法,不返回任何内容.在这种情况下,应该提供什么参数Call?
我在android中使用retrofit来连接服务器.
public class ApiClient {
public static final String BASE_URL = "https://example.com/";
private static Retrofit retrofit = null;
public static Retrofit getClient() {
if (retrofit==null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的开发.服务器,我想禁用证书检查.我该如何在这段代码中实现?
错误:javax.net.ssl.SSLHandshakeException:java.security.cert.CertPathValidatorException:未找到证书路径的信任锚.
我需要在改装2.0中添加cookie.如果我理解正确,cookie - 与标题相同.必须添加此Cookie:
private HashMap<String, String> cookies = new HashMap();
cookies.put("sessionid", "sessionId");
cookies.put("token", "token");
Run Code Online (Sandbox Code Playgroud)
这个与Jsoup lib一起使用:
String json = Jsoup.connect(apiURL + "/link")
.cookies(cookies)
.ignoreHttpErrors(true)
.ignoreContentType(true)
.execute()
.body();
Run Code Online (Sandbox Code Playgroud)
这是我的代码与改造请求:
@GET("link")
Call<CbGet> getData(@Header("sessionid") String sessionId, @Header("token") String token);
Run Code Online (Sandbox Code Playgroud)
但它不起作用...我得到403错误代码,所以请求中没有cookie ...
任何的想法?
@GET("user/token/")
Observable<String> gToken(@Url String url, @Query("usertype") int userType);
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
Process: com.gouhuoapp.say, PID: 12519
rx.exceptions.OnErrorNotImplementedException: @Url cannot be used with @GET URL (parameter #1)
for method ApiService.getToken
at rx.internal.util.InternalObservableUtils$ErrorNotImplementedAction.call(InternalObservableUtils.java:386)
at rx.internal.util.InternalObservableUtils$ErrorNotImplementedAction.call(InternalObservableUtils.java:383)
at rx.internal.util.ActionSubscriber.onError(ActionSubscriber.java:44)
at rx.observers.SafeSubscriber._onError(SafeSubscriber.java:153)
at rx.observers.SafeSubscriber.onError(SafeSubscriber.java:115)
at rx.exceptions.Exceptions.throwOrReport(Exceptions.java:216)
at rx.observers.SafeSubscriber.onNext(SafeSubscriber.java:139)
at rx.observers.SerializedObserver.onNext(SerializedObserver.java:91)
at rx.observers.SerializedSubscriber.onNext(SerializedSubscriber.java:94)
at rx.internal.operators.OperatorTakeUntil$1.onNext(OperatorTakeUntil.java:45)
at rx.internal.operators.OperatorThrottleFirst$1.onNext(OperatorThrottleFirst.java:53)
at com.jakewharton.rxbinding.view.ViewClickOnSubscribe$1.onClick(ViewClickOnSubscribe.java:23)
at android.view.View.performClick(View.java:4909)
at android.view.View$PerformClick.run(View.java:20390)
at android.os.Handler.handleCallback(Handler.java:815)
at android.os.Handler.dispatchMessage(Handler.java:104)
at android.os.Looper.loop(Looper.java:192)
at android.app.ActivityThread.main(ActivityThread.java:5784)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1084)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:850)
Caused by: java.lang.IllegalArgumentException: @Url cannot be used with @GET …Run Code Online (Sandbox Code Playgroud) 我正在使用带有okhttp 2.4.0的Retrofit 1.9.到目前为止,我们在服务器端禁用了SPDY协议(我通过此检查).服务器端的启用协议是HTTP/2(我通过此检查).
所以我认为okhttp将尝试使用HTTP/2(最新的一个协议)进行api调用,但它在Android设备4.2.2 samsung S4上使用HTTP/1.1 -
D/Retrofit : OkHttp-Selected-Protocol: http/1.1
Run Code Online (Sandbox Code Playgroud)
有人告诉我Android设备直到5.0 才支持SPDY(我没有任何证据),因此该设备从未尝试过使用SPDY连接.但我确信我们的服务器根本没有使用SPDY我自己使用上面的链接检查了它.
并且okhttp开始支持HTTP/2,因为它是2.3.0版本,请参见此处.
如果我在上面的Android 5.0中使用相同的东西,我在生产应用程序上获得了相同配置(okhttp 2.4.0和Retrofit 1.9)的异常 -
java.net.ProtocolException: Expected ':status' header not present at
com.squareup.okhttp.internal.http.SpdyTransport.readNameValueBlock(SpdyTransport.java:197)at com.squareup.okhttp.internal.http.SpdyTransport.readResponseHeaders(SpdyTransport.java:104)
at com.squareup.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:917)
at com.squareup.okhttp.internal.http.HttpEngine.access$300(HttpEngine.java:95)
at com.squareup.okhttp.internal.http.HttpEngine$NetworkInterceptorChain.proceed(HttpEngine.java:902)
at com.squareup.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:760)
at com.squareup.okhttp.Call.getResponse(Call.java:274)
at com.squareup.okhttp.Call$ApplicationInterceptorChain.proceed(Call.java:230)
at com.squareup.okhttp.Call.getResponseWithInterceptorChain(Call.java:201)
at com.squareup.okhttp.Call.execute(Call.java:81)
at retrofit.client.OkClient.execute(OkClient.java:53)
at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:326)
at retrofit.RestAdapter$RestHandler.access$100(RestAdapter.java:220)
at retrofit.RestAdapter$RestHandler$2.obtainResponse(RestAdapter.java:278)
at retrofit.CallbackRunnable.run(CallbackRunnable.java:42)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at retrofit.Platform$Android$2$1.run(Platform.java:142)
at java.lang.Thread.run(Thread.java:818)
Run Code Online (Sandbox Code Playgroud)
有两个修复 -
强制okhttp只使用http/1.1 -
OkHttpClient客户端=新的OkHttpClient(); client.setProtocols(Arrays.asList(Protocol.HTTP_1_1));
注意 - 我们不能使用Protocol.HTTP_2或Protocol.SPDY_3,因为如果 …
我有一些具有相同baseUrl的服务URL.对于某些网址,会有一些常用的参数,例如apiVersion或locale.但它们不必存在于每个URL中,因此我无法将它们添加到baseUrl中.
.../api/{apiVersion}/{locale}/event/{eventId}
.../api/{apiVersion}/{locale}/venues
.../api/{apiVersion}/configuration
Run Code Online (Sandbox Code Playgroud)
我不想在改装界面中添加这些参数.在改造1中,我制作了一个拦截器并用于RequestFacade.addPathParam(..., ...)填充每个URL的这些常用路径参数.
对于改造2,我似乎找不到用okhttp做这个的正确方法.我现在看到这种可能性的唯一方法是HttpUrl从Chain.request().httpUrl();一个okhttp中获取Interceptor并自己操纵那个,但我不知道这是否是最好的方法.
有没有人遇到过更好的方法来替换okhttp中的路径参数Interceptor?
在撰写本文时,我正在使用改进:2.0.0-beta2和okhttp:2.7.2.
我想在Retrofit 2中实现多个并行请求.我有以下结构来发出3个请求:
HistoricalRApi.IStockChart service=HistoricalRApi.getMyApiService();
//^BVSP,^DJI,^IXIC
Call<HistoricalDataResponseTimestamp> call1= service.get1DHistoricalDataByStock("^IXIC");
Call<HistoricalDataResponseTimestamp> call2= service.get1DHistoricalDataByStock("^DJI");
Call<HistoricalDataResponseTimestamp> call3= service.get1DHistoricalDataByStock("^GSPC");
call1.enqueue(retrofitCallbackAmerica());
call2.enqueue(retrofitCallbackAmerica());
call3.enqueue(retrofitCallbackAmerica());
}
Run Code Online (Sandbox Code Playgroud)
我已经在Retrofit1中看到,在定义其余适配器时,可以使用.setExecutor定义并行请求,如下所示:
RestAdapter adapter = new RestAdapter.Builder()
.setEndpoint(END_POINT)
.setLogLevel(RestAdapter.LogLevel.FULL)
.setExecutors(Executors.newFixedThreadPool(3), null)
.build();
Run Code Online (Sandbox Code Playgroud)
我的问题是如何在Retrofit 2中实现同样的目标?提前致谢
我在最新的AndroidStudio预览版中使用了RxJava和Retrofit.我的项目启用了java 1.8 suport,如下所示:
compileOptions {
targetCompatibility 1.8
sourceCompatibility 1.8
}
Run Code Online (Sandbox Code Playgroud)
但是当编译并运行代码时,即使我有onError处理程序,一旦发出请求,我就会收到此错误:
java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/devtools/build/android/desugar/runtime/ThrowableExtension;
at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:281)
at retrofit2.adapter.rxjava2.CallExecuteObservable.subscribeActual(CallExecuteObservable.java:58)
at io.reactivex.Observable.subscribe(Observable.java:10179)
at retrofit2.adapter.rxjava2.BodyObservable.subscribeActual(BodyObservable.java:34)
at io.reactivex.Observable.subscribe(Observable.java:10179)
at io.reactivex.internal.operators.flowable.FlowableFromObservable.subscribeActual(FlowableFromObservable.java:31)
at io.reactivex.Flowable.subscribe(Flowable.java:12218)
at io.reactivex.internal.operators.flowable.FlowableOnBackpressureLatest.subscribeActual(FlowableOnBackpressureLatest.java:31)
at io.reactivex.Flowable.subscribe(Flowable.java:12218)
Run Code Online (Sandbox Code Playgroud)
即使我使用Maybe,Single或Observable,也会发生这种情况.如何解决这个问题?
我正在尝试使用Dagger 2(使用Android模块)向我的存储库提供一个Retrofit实例.买我面临错误:
错误:无法访问Retrofit
像毕加索这样的其他实例注入成功,我只是在改造时遇到了问题.
我的模块
@Module
class NetworkModule {
@Provides
@Singleton
fun providesRetrofit(): Retrofit {
return Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(URL_BASE)
.build()
}
@Provides
@Singleton
fun providesPicasso(context: Context): Picasso {
return Picasso.Builder(context)
.loggingEnabled(true)
.build()
}
@Provides
@Singleton
fun providesRemoteRepository(retrofit: Retrofit): RemoteRepository = RemoteRepository(retrofit)
@Provides
@Singleton
fun providesRepository(remote: RemoteRepository): Repository = RepositoryImp(remote)
}
Run Code Online (Sandbox Code Playgroud)
我的应用程序组件
@Singleton
@Component(modules = arrayOf(
AppModule::class, NetworkModule::class, AndroidInjectionModule::class, ActivityBuilder::class
))
interface AppComponent {
@Component.Builder
interface Builder {
@BindsInstance
fun application(app: Application): Builder
fun build(): AppComponent
}
fun inject(application: AppApplication)
} …Run Code Online (Sandbox Code Playgroud) 我在嘲笑APIService的反应.不幸的是它不起作用,我必须发回一个电话,但我不明白如何.问题是如何发送回Call对象.
@RunWith(AndroidJUnit4::class)
class ApiServiceTest {
@Test
fun testSomething() {
val apiService = ApiServiceMock()
val call = apiService.getStep1User()
val result = call.execute()
Assert.assertEquals("SomeUserValue", result.body()!!.getResponse())
}
}
Run Code Online (Sandbox Code Playgroud)
这是模拟服务:
class ApiServiceMock : ApiService {
override fun getStep1User(): Call<UserResponse> {
// How to return an object of type Call<UserResponse> ?
val response = "{ \"Response\": \"SomeUserValue\" }"
val gson = Gson().toJson(response)
return Response.success(gson)
}
}
Run Code Online (Sandbox Code Playgroud)
这是api接口:
interface ApiService {
@GET("/booky/step1user")
fun getStep1User(): Call<UserResponse>
companion object {
val interceptor = HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)
val client = OkHttpClient.Builder() …Run Code Online (Sandbox Code Playgroud)