标签: retrofit2

如何使用Retrofit 2.0和新的MockRetrofit类来模拟服务?

使用Retrofit 1,我们用来模拟Web服务并模拟网络延迟,如下所示:

MockRestAdapter mockRestAdapter = MockRestAdapter.from(restAdapter);
return mockRestAdapter.create(MyService.class, new MyServiceMock());
Run Code Online (Sandbox Code Playgroud)

MyService服务接口在哪里(将响应作为Rx Observables返回),并且MyServiceMock是实现此接口的类.

在Retrofit 2.0.0-beta3中,有一个全新的模拟系统(参见:https://github.com/square/retrofit/pull/1343)尚未记录.当我尝试类似的东西,我得到:

MockRetrofit mockRetrofit = new MockRetrofit.Builder(retrofit).build();
BehaviorDelegate<AuthService> delegate = mockRetrofit.create(MyService.class);
Run Code Online (Sandbox Code Playgroud)

我该如何转接电话MyServiceMock

java rx-java retrofit2

15
推荐指数
1
解决办法
1万
查看次数

Retrofit 2 - 在api级别添加标头的优雅方式

我的Retrofit 2(2.0.2当前)客户端需要为请求添加自定义标头.

我正在使用an Interceptor将这些标头添加到所有请求中:

OkHttpClient httpClient = new OkHttpClient();
httpClient.networkInterceptors().add(new Interceptor() {
    @Override
    public Response intercept(Chain chain) throws IOException {
        final Request request = chain.request().newBuilder()
                .addHeader("CUSTOM_HEADER_NAME_1", "CUSTOM_HEADER_VALUE_1")
                .addHeader("CUSTOM_HEADER_NAME_2", "CUSTOM_HEADER_VALUE_2")
                ...
                .addHeader("CUSTOM_HEADER_NAME_N", "CUSTOM_HEADER_VALUE_N")
                .build();

        return chain.proceed(request);
    }
});


Retrofit retrofitClient = new Retrofit.Builder()
        .baseUrl(baseUrl)
        .client(httpClient)
        .build();
Run Code Online (Sandbox Code Playgroud)

我总是想添加一些标头,但是我只需要根据特定端点的要求添加一些标头,例如用户是否需要进行身份验证.

我希望能够在api级别控制它,例如使用注释,例如:

public interface MyApi {
    @NO_AUTH
    @POST("register")
    Call<RegisterResponse> register(@Body RegisterRequest data);

    @GET("user/{userId}")
    Call<GetUserResponse> getUser(@Path("userId") String userId);
}
Run Code Online (Sandbox Code Playgroud)

发送请求时register无需添加身份验证令牌,但缺少@NO_AUTH注释的请求将具有令牌头.

根据我的理解,Retrofit 2不支持自定义注释,虽然我发现使用Retrofit 2的自定义注释的这种解决方法,但它看起来有点太多了.

我想避免每个请求传递这些标头的需要,例如:

public interface MyApi …
Run Code Online (Sandbox Code Playgroud)

java annotations header retrofit retrofit2

15
推荐指数
2
解决办法
2万
查看次数

使用retrofit2和OkHttp3时出现此错误.无法解析主机"<host-name>":没有与主机名关联的地址

我正在使用改造2和OkHttp3从服务器请求数据.我刚刚添加了一个离线缓存代码,但它没有按预期工作.我收到错误"无法解析主机"<>":没有与主机名关联的地址."

当它试图从缓存中获取检索数据时(没有互联网连接时)会发生这种情况.下面是一段代码片段.

public static Interceptor provideCacheInterceptor() {
    return new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Response response = chain.proceed(chain.request());

            // re-write response header to force use of cache
            CacheControl cacheControl = new CacheControl.Builder()
                    .maxAge(2, TimeUnit.MINUTES)
                    .build();

            return response.newBuilder()
                    .header(CACHE_CONTROL, cacheControl.toString())
                    .build();
        }
    };
}

public static Interceptor provideOfflineCacheInterceptor() {
    return new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request();

            if (!hasNetwork) {
                CacheControl cacheControl = new CacheControl.Builder()
                        .onlyIfCached()
                        .maxStale(7, TimeUnit.DAYS) …
Run Code Online (Sandbox Code Playgroud)

android offline-caching okhttp retrofit2 okhttp3

15
推荐指数
1
解决办法
6800
查看次数

Android Dagger2 + OkHttp + Retrofit依赖循环错误

嘿,我正在使用Dagger2,Retrofit而且OkHttp我正面临依赖循环问题.

提供时OkHttp:

@Provides
@ApplicationScope
OkHttpClient provideOkHttpClient(TokenAuthenticator auth,Dispatcher dispatcher){
    return new OkHttpClient.Builder()
            .connectTimeout(Constants.CONNECT_TIMEOUT, TimeUnit.SECONDS)
            .readTimeout(Constants.READ_TIMEOUT,TimeUnit.SECONDS)
            .writeTimeout(Constants.WRITE_TIMEOUT,TimeUnit.SECONDS)
            .authenticator(auth)
            .dispatcher(dispatcher)
            .build();
}
Run Code Online (Sandbox Code Playgroud)

提供时Retrofit:

@Provides
@ApplicationScope
Retrofit provideRetrofit(Resources resources,Gson gson, OkHttpClient okHttpClient){
    return new Retrofit.Builder()
            .baseUrl(resources.getString(R.string.base_api_url))
            .addConverterFactory(GsonConverterFactory.create(gson))
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .client(okHttpClient)
            .build();
}
Run Code Online (Sandbox Code Playgroud)

提供时APIService:

@Provides
@ApplicationScope
APIService provideAPI(Retrofit retrofit) {
    return retrofit.create(APIService.class);
}
Run Code Online (Sandbox Code Playgroud)

我的APIService界面:

public interface  APIService {
@FormUrlEncoded
@POST("token")
Observable<Response<UserTokenResponse>> refreshUserToken();

--- other methods like login, register ---

}
Run Code Online (Sandbox Code Playgroud)

我的TokenAuthenticator …

android dependency-injection dagger-2 retrofit2 rx-java2

15
推荐指数
2
解决办法
4188
查看次数

%3F而不是我的Retrofit网址中的问号

我正在尝试将图片发送到服务器.我的网址包含有关手机的一些参数:

api/v2/user/email_register%3F_height=1184&_target=android/2&_width=768 
Run Code Online (Sandbox Code Playgroud)

这是工作变体:

api/v2/user/email_register?_height=1184&_target=android/2&_width=768
Run Code Online (Sandbox Code Playgroud)

(没有刺激%3?代码)

另外,我试图在@Body中传递我的照片:

@POST("/{url}")
Observable<UpdateUserInfoPayload> register(
        @Header("x-device-id") String deviceId,
        @Body RequestBody requestBody,
        @Path(value = "url", encoded = true) String  method
);
Run Code Online (Sandbox Code Playgroud)

使用MultipartBuilder创建它:

protected RequestBody buildAvatar(String avatarPath) {


 MultipartBuilder builder = new MultipartBuilder()
  .type(MultipartBuilder.FORM)
  .addFormDataPart(ParkApiUrl.PARAM_USER_NAME, name.getText().toString())
  .addFormDataPart(ParkApiUrl.PARAM_USER_SECOND_NAME, lastName.getText().toString())
  .addFormDataPart(ParkApiUrl.PARAM_EMAIL, email.getText().toString())
  .addFormDataPart(ParkApiUrl.PARAM_USER_ENCODED_PASSWORD,
   PasswordUtils.encodePassword(encodePassword()))
  .addFormDataPart(ParkApiUrl.PARAM_USER_GENDER,
   male.isChecked() ? EmailProfile.GENDER_MALE : EmailProfile.GENDER_FEMALE)
  .addFormDataPart(ParkApiUrl.PARAM_PARSE_ID,
   ParseInstallation.getCurrentInstallation().getObjectId());


 File file = new File(avatarPath);;
 int size = (int) file.length();
 byte[] bytes = new byte[size];
 try {
  BufferedInputStream buf = new BufferedInputStream(new FileInputStream(file));
  buf.read(bytes, 0, bytes.length);
  buf.close();
  builder.addFormDataPart("photo", …
Run Code Online (Sandbox Code Playgroud)

android retrofit2

14
推荐指数
1
解决办法
3026
查看次数

Android Retrofit 2 + RxJava:听听层出不穷

我可以使用Retrofit + RxJava来聆听无尽的流吗?例如Twitter流.我有的是这个:

public interface MeetupAPI {
    @GET("http://stream.meetup.com/2/rsvps/")
    Observable<RSVP> getRSVPs();
}

MeetupAPI api = new Retrofit.Builder()
            .baseUrl(MeetupAPI.RSVP_API)
            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
            .addConverterFactory(GsonConverterFactory.create())
            .build()
            .create(MeetupAPI.class);

api.getRSVPs()
        .subscribeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(rsvp -> Log.d(TAG, "got rsvp"),
                error -> Log.d(TAG, "error: " + error),
                () -> Log.d(TAG, "onComplete"));
Run Code Online (Sandbox Code Playgroud)

但在解析第一个对象后调用"onComplete".有没有办法告诉Retrofit保持开放直到另行通知?

android rx-java retrofit retrofit2

14
推荐指数
1
解决办法
4203
查看次数

在改造库中禁用SSL证书检查

我在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:未找到证书路径的信任锚.

java ssl android retrofit retrofit2

14
推荐指数
7
解决办法
2万
查看次数

添加cookie以改进2请求

我需要在改装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 ...

任何的想法?

cookies android retrofit retrofit2

14
推荐指数
3
解决办法
2万
查看次数

java.lang.IllegalArgumentException:@Url不能与@GET URL一起使用(参数#1)

@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)

java url get retrofit2

14
推荐指数
1
解决办法
5607
查看次数

HTTP/2协议不能与okhttp一起使用

我正在使用带有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)

有两个修复 -

  1. 强制okhttp只使用http/1.1 -

    OkHttpClient客户端=新的OkHttpClient(); client.setProtocols(Arrays.asList(Protocol.HTTP_1_1));

注意 - 我们不能使用Protocol.HTTP_2或Protocol.SPDY_3,因为如果 …

android retrofit okhttp retrofit2 okhttp3

14
推荐指数
0
解决办法
1473
查看次数