request url request url 如何用rxjava在retrofit 2.0中获取?
How to get the request url in retrofit 2.0 with rxjava?
我正在尝试升级到 Retrofit 2.0 并在我的 android 项目中添加 RxJava。我正在调用 api 并希望检索 url 并将其与 sqlite 中的响应数据作为缓存
Observable<MyResponseObject> apiCall(@Body body);
并且在 RxJava 调用中:
myRetrofitObject.apiCall(body).subscribe(new Subscriber<MyResponseObject>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(MyResponseObject myResponseObject) {
}
});
在Retrofit 1.9中,我们可以在成功回调中得到url:
@Override
public void success(MyResponseObject object, Response response) {
String url=response.getUrl();
//save object data and url to sqlite
}
你如何使用 RxJava 在 Retrofit 2.0 中做到这一点?
更新:
再次阅读问题后:
如果您想访问原始响应,您需要将 API 接口定义为:
Observable<Response<MyResponseObject>> apiCall(@Body body);
而不是:
Observable<MyResponseObject> apiCall(@Body body);
您可以通过以下方式获得 Url:
response.raw().request().url()
此处:
response
是 Retrofit
的响应
raw
是 OkHttp 的响应
request
是来自 OkHttp 的请求,其中包含 Url
作为 HttpUrl
。
使用 rxjava
从 API
获取响应 使用以下代码
创建class名称API
public class Api {
private static final String BASE_URL="https://your_url";
private static Api instance;
private final IApiCall iApiCallInterface;
private Api() {
Gson gson = new GsonBuilder().setLenient().create();
final OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(60, TimeUnit.SECONDS)
.writeTimeout(60, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
.build();
Retrofit retrofit = new Retrofit.Builder().client(okHttpClient).baseUrl(BASE_URL)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create(gson)).build();
iApiCallInterface = retrofit.create(IApiCall.class);
}
public static Api start() {
return instance = instance == null ? new Api() : instance;
}
public Observable<Example> getSendMoneyCountries() {
return iApiCallInterface.getCategoryList();
}
}
Crete Interface name IApiCall
在这里您可以提出所有其他 API
请求
public interface IApiCall {
//response in in json array
@Headers("Content-Type: application/json")
@GET("/json")
Observable<Example> getCategoryList();
}
在您的 MainActivity.java
中写入以下代码
private static Api api;
api = Api.start();
api.getSendMoneyCountries()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new DisposableObserver<Example>() {
@Override
public void onNext(Example response) {
//Handle logic
try {
populateCountryList(response);
}catch (Exception e)
{
finish();
Toast.makeText(MainActivity.this,"Unable to send money",Toast.LENGTH_SHORT).show();
//MainActivity.showTimeoutDialog();
e.printStackTrace();
}
}
@Override
public void onError(Throwable e) {
//Handle error
Toast.makeText(MainActivity.this, "Error", Toast.LENGTH_SHORT).show();
}
@Override
public void onComplete() {
}
});
好吧,我会告诉你我是怎么做的,使用改造和 rxJava 处理 API。
先创建一个ApiClient.class
public class ApiClient {
private static final String BASE_URL = "https://travellingbook.app/api/v2/";
public static final String IMAGE_BASE_URL = "";
private static File httpCacheDirectory = new File(UpasargaApplication.getAppContext().getCacheDir(), "new_responses");
private static int cacheSize = 10 * 1024 * 1024; // 10 MiB
private static Cache cache = new Cache(httpCacheDirectory, cacheSize);
private static Retrofit retrofit = null;
public static Retrofit getClient() {
OkHttpClient.Builder builder = new OkHttpClient.Builder();
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
if (BuildConfig.DEBUG) {
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
} else {
interceptor.setLevel(HttpLoggingInterceptor.Level.NONE);
}
builder.interceptors().add(interceptor);
builder.authenticator(new ApiTokenAuthenticator());
OkHttpClient httpClient = builder
.readTimeout(15, TimeUnit.SECONDS)
.connectTimeout(15, TimeUnit.SECONDS)
.writeTimeout(15, TimeUnit.SECONDS)
.addInterceptor(new ApiInterceptor())
.build();
Gson gson = new GsonBuilder()
.setLenient()
.create();
RxJava2CallAdapterFactory rxJava2CallAdapterFactory = RxJava2CallAdapterFactory.createWithScheduler(Schedulers.computation());
if (retrofit == null) {
retrofit = new Retrofit.Builder().baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.addCallAdapterFactory(rxJava2CallAdapterFactory)
.client(httpClient)
.build();
}
return retrofit;
}
现在,添加 Interceptor.class 和 TokenAuthenticator.class(基于您的 API 架构. 这是一个示例案例。)
public class ApiInterceptor implements Interceptor {
@NonNull
@Override
public Response intercept(@NonNull Chain chain) throws IOException {
Request originalRequest = chain.request();
if (Utilities.getLoginResponse() == null || TextUtils.isEmpty(Utilities.getLoginUserToken())) {
return chain.proceed(originalRequest);
}
Request request = originalRequest.newBuilder()
.addHeader("Authorization", Utilities.getLoginUserToken())
.addHeader("Accept", "Accept: application/x.school.v1+json")
.header("Cache-Control", String.format("max-age=%d", 50000))
.build();
return chain.proceed(request);
}
}
现在创建一个LoginApiService.java界面。
public interface LoginApiService {
@POST("login")
@FormUrlEncoded
Observable<Login> login(
@Field("email") String email,
@Field("password") String password
);
@POST("forgot_password")
@FormUrlEncoded
Observable<ServerResponse> forgotPassword(
@Field("email") String email
);
}
现在实施 LoginPresenter.java 处理逻辑。
public class LoginPresenter {
private static final String TAG = LoginPresenter.class.getSimpleName();
private WeakReference<View> view;
CompositeDisposable compositeDisposable;
public LoginPresenter(View view) {
this.view = new WeakReference<>(view);
this.compositeDisposable = new CompositeDisposable();
}
private View getView() throws NullPointerException {
if (view != null)
return view.get();
else
throw new NullPointerException("View is unavailable");
}
public void userLogin(String email, String password) {
Observable<Login> loginObservable = ApiClient.getClient().create(LoginApiService.class)
.login(email, password)
.subscribeOn(Schedulers.io())
.retry(AppConstants.API_RETRY_COUNT)
.observeOn(AndroidSchedulers.mainThread());
DisposableObserver<Login> loginDisposableObserver = new DisposableObserver<Login>() {
@Override
public void onNext(Login login) {
if (getView() != null && login != null) {
getView().onUserLoginSuccess(login);
}
}
@Override
public void onError(Throwable e) {
try {
getView().onFailure(UtilitiesFunctions.handleApiError(e));
} catch (Exception ignored) {
}
}
@Override
public void onComplete() {
}
};
compositeDisposable.add(loginObservable.subscribeWith(loginDisposableObserver));
}
public void forgotPassword(String email) {
Observable<ServerResponse> loginObservable = ApiClient.getClient().create(LoginApiService.class)
.forgotPassword(email)
.subscribeOn(Schedulers.io())
.retry(AppConstants.API_RETRY_COUNT)
.observeOn(AndroidSchedulers.mainThread());
DisposableObserver<ServerResponse> loginDisposableObserver = new DisposableObserver<ServerResponse>() {
@Override
public void onNext(ServerResponse serverResponse) {
Log.e("onNext: ", new GsonBuilder().create().toJson(serverResponse));
if (getView() != null && serverResponse != null) {
getView().onForgotPasswordSuccess(serverResponse);
}
}
@Override
public void onError(Throwable e) {
ServerResponse serverResponse = new GsonBuilder().create().fromJson(e.getMessage(), ServerResponse.class);
if (serverResponse != null) {
getView().onFailure(serverResponse.getMessage());
} else {
try {
getView().onFailure(UtilitiesFunctions.handleApiError(e));
} catch (Exception ignored) {
}
}
}
@Override
public void onComplete() {
}
};
compositeDisposable.add(loginObservable.subscribeWith(loginDisposableObserver));
}
public void onActivityStop() {
if (getView() != null) {
compositeDisposable.clear();
}
}
public interface View {
void onUserLoginSuccess(Login login);
void onForgotPasswordSuccess(ServerResponse serverResponse);
void onFailure(String message);
}
最后,我们可以从Activity/Fragment
访问LoginPresenter.class
public class LoginActivity extends AppActivity implements LoginPresenter.View {
private Button btnLogin;
private LoginPresenter loginPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
enter code here
loginPresenter = new LoginPresenter(this);
}
@Override
public void onUserLoginSuccess(Login login) {
if (login != null) {
Utilities.saveLoginResponse(login);
Utilities.saveLoginResponse(login);
hideProgressBarWork();
if (login.getStatus()) {
Utilities.setUserLoginCompleted();
} else {
ShowToastWithMessage("Your account has been disabled.");
}
}
}
@Override
public void onForgotPasswordSuccess(ServerResponse serverResponse) {
}
@Override
public void onFailure(String message) {
hideProgressBarWork();
ShowToastWithMessage(message);
}
}
欢迎提问和建议。
直接调用这个方法
@Override
public void onFailure(Call<List<loginModel>> call, Throwable t) {
Log.v("rese",call.request().url().toString());
}
});
我正在尝试升级到 Retrofit 2.0 并在我的 android 项目中添加 RxJava。我正在调用 api 并希望检索 url 并将其与 sqlite 中的响应数据作为缓存
Observable<MyResponseObject> apiCall(@Body body);
并且在 RxJava 调用中:
myRetrofitObject.apiCall(body).subscribe(new Subscriber<MyResponseObject>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(MyResponseObject myResponseObject) {
}
});
在Retrofit 1.9中,我们可以在成功回调中得到url:
@Override
public void success(MyResponseObject object, Response response) {
String url=response.getUrl();
//save object data and url to sqlite
}
你如何使用 RxJava 在 Retrofit 2.0 中做到这一点?
更新:
再次阅读问题后:
如果您想访问原始响应,您需要将 API 接口定义为:
Observable<Response<MyResponseObject>> apiCall(@Body body);
而不是:
Observable<MyResponseObject> apiCall(@Body body);
您可以通过以下方式获得 Url:
response.raw().request().url()
此处:
response
是 Retrofit
的响应
raw
是 OkHttp 的响应
request
是来自 OkHttp 的请求,其中包含 Url
作为 HttpUrl
。
使用 rxjava
从 API
获取响应 使用以下代码
创建class名称API
public class Api {
private static final String BASE_URL="https://your_url";
private static Api instance;
private final IApiCall iApiCallInterface;
private Api() {
Gson gson = new GsonBuilder().setLenient().create();
final OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(60, TimeUnit.SECONDS)
.writeTimeout(60, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
.build();
Retrofit retrofit = new Retrofit.Builder().client(okHttpClient).baseUrl(BASE_URL)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create(gson)).build();
iApiCallInterface = retrofit.create(IApiCall.class);
}
public static Api start() {
return instance = instance == null ? new Api() : instance;
}
public Observable<Example> getSendMoneyCountries() {
return iApiCallInterface.getCategoryList();
}
}
Crete Interface name IApiCall
在这里您可以提出所有其他 API
请求
public interface IApiCall {
//response in in json array
@Headers("Content-Type: application/json")
@GET("/json")
Observable<Example> getCategoryList();
}
在您的 MainActivity.java
private static Api api;
api = Api.start();
api.getSendMoneyCountries()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new DisposableObserver<Example>() {
@Override
public void onNext(Example response) {
//Handle logic
try {
populateCountryList(response);
}catch (Exception e)
{
finish();
Toast.makeText(MainActivity.this,"Unable to send money",Toast.LENGTH_SHORT).show();
//MainActivity.showTimeoutDialog();
e.printStackTrace();
}
}
@Override
public void onError(Throwable e) {
//Handle error
Toast.makeText(MainActivity.this, "Error", Toast.LENGTH_SHORT).show();
}
@Override
public void onComplete() {
}
});
好吧,我会告诉你我是怎么做的,使用改造和 rxJava 处理 API。
先创建一个ApiClient.class
public class ApiClient {
private static final String BASE_URL = "https://travellingbook.app/api/v2/";
public static final String IMAGE_BASE_URL = "";
private static File httpCacheDirectory = new File(UpasargaApplication.getAppContext().getCacheDir(), "new_responses");
private static int cacheSize = 10 * 1024 * 1024; // 10 MiB
private static Cache cache = new Cache(httpCacheDirectory, cacheSize);
private static Retrofit retrofit = null;
public static Retrofit getClient() {
OkHttpClient.Builder builder = new OkHttpClient.Builder();
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
if (BuildConfig.DEBUG) {
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
} else {
interceptor.setLevel(HttpLoggingInterceptor.Level.NONE);
}
builder.interceptors().add(interceptor);
builder.authenticator(new ApiTokenAuthenticator());
OkHttpClient httpClient = builder
.readTimeout(15, TimeUnit.SECONDS)
.connectTimeout(15, TimeUnit.SECONDS)
.writeTimeout(15, TimeUnit.SECONDS)
.addInterceptor(new ApiInterceptor())
.build();
Gson gson = new GsonBuilder()
.setLenient()
.create();
RxJava2CallAdapterFactory rxJava2CallAdapterFactory = RxJava2CallAdapterFactory.createWithScheduler(Schedulers.computation());
if (retrofit == null) {
retrofit = new Retrofit.Builder().baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.addCallAdapterFactory(rxJava2CallAdapterFactory)
.client(httpClient)
.build();
}
return retrofit;
}
现在,添加 Interceptor.class 和 TokenAuthenticator.class(基于您的 API 架构. 这是一个示例案例。)
public class ApiInterceptor implements Interceptor {
@NonNull
@Override
public Response intercept(@NonNull Chain chain) throws IOException {
Request originalRequest = chain.request();
if (Utilities.getLoginResponse() == null || TextUtils.isEmpty(Utilities.getLoginUserToken())) {
return chain.proceed(originalRequest);
}
Request request = originalRequest.newBuilder()
.addHeader("Authorization", Utilities.getLoginUserToken())
.addHeader("Accept", "Accept: application/x.school.v1+json")
.header("Cache-Control", String.format("max-age=%d", 50000))
.build();
return chain.proceed(request);
}
}
现在创建一个LoginApiService.java界面。
public interface LoginApiService {
@POST("login")
@FormUrlEncoded
Observable<Login> login(
@Field("email") String email,
@Field("password") String password
);
@POST("forgot_password")
@FormUrlEncoded
Observable<ServerResponse> forgotPassword(
@Field("email") String email
);
}
现在实施 LoginPresenter.java 处理逻辑。
public class LoginPresenter {
private static final String TAG = LoginPresenter.class.getSimpleName();
private WeakReference<View> view;
CompositeDisposable compositeDisposable;
public LoginPresenter(View view) {
this.view = new WeakReference<>(view);
this.compositeDisposable = new CompositeDisposable();
}
private View getView() throws NullPointerException {
if (view != null)
return view.get();
else
throw new NullPointerException("View is unavailable");
}
public void userLogin(String email, String password) {
Observable<Login> loginObservable = ApiClient.getClient().create(LoginApiService.class)
.login(email, password)
.subscribeOn(Schedulers.io())
.retry(AppConstants.API_RETRY_COUNT)
.observeOn(AndroidSchedulers.mainThread());
DisposableObserver<Login> loginDisposableObserver = new DisposableObserver<Login>() {
@Override
public void onNext(Login login) {
if (getView() != null && login != null) {
getView().onUserLoginSuccess(login);
}
}
@Override
public void onError(Throwable e) {
try {
getView().onFailure(UtilitiesFunctions.handleApiError(e));
} catch (Exception ignored) {
}
}
@Override
public void onComplete() {
}
};
compositeDisposable.add(loginObservable.subscribeWith(loginDisposableObserver));
}
public void forgotPassword(String email) {
Observable<ServerResponse> loginObservable = ApiClient.getClient().create(LoginApiService.class)
.forgotPassword(email)
.subscribeOn(Schedulers.io())
.retry(AppConstants.API_RETRY_COUNT)
.observeOn(AndroidSchedulers.mainThread());
DisposableObserver<ServerResponse> loginDisposableObserver = new DisposableObserver<ServerResponse>() {
@Override
public void onNext(ServerResponse serverResponse) {
Log.e("onNext: ", new GsonBuilder().create().toJson(serverResponse));
if (getView() != null && serverResponse != null) {
getView().onForgotPasswordSuccess(serverResponse);
}
}
@Override
public void onError(Throwable e) {
ServerResponse serverResponse = new GsonBuilder().create().fromJson(e.getMessage(), ServerResponse.class);
if (serverResponse != null) {
getView().onFailure(serverResponse.getMessage());
} else {
try {
getView().onFailure(UtilitiesFunctions.handleApiError(e));
} catch (Exception ignored) {
}
}
}
@Override
public void onComplete() {
}
};
compositeDisposable.add(loginObservable.subscribeWith(loginDisposableObserver));
}
public void onActivityStop() {
if (getView() != null) {
compositeDisposable.clear();
}
}
public interface View {
void onUserLoginSuccess(Login login);
void onForgotPasswordSuccess(ServerResponse serverResponse);
void onFailure(String message);
}
最后,我们可以从Activity/Fragment
访问LoginPresenter.classpublic class LoginActivity extends AppActivity implements LoginPresenter.View {
private Button btnLogin;
private LoginPresenter loginPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
enter code here
loginPresenter = new LoginPresenter(this);
}
@Override
public void onUserLoginSuccess(Login login) {
if (login != null) {
Utilities.saveLoginResponse(login);
Utilities.saveLoginResponse(login);
hideProgressBarWork();
if (login.getStatus()) {
Utilities.setUserLoginCompleted();
} else {
ShowToastWithMessage("Your account has been disabled.");
}
}
}
@Override
public void onForgotPasswordSuccess(ServerResponse serverResponse) {
}
@Override
public void onFailure(String message) {
hideProgressBarWork();
ShowToastWithMessage(message);
}
}
欢迎提问和建议。
直接调用这个方法
@Override
public void onFailure(Call<List<loginModel>> call, Throwable t) {
Log.v("rese",call.request().url().toString());
}
});