Rtrofit+Rxjava网络请求封装
2023-12-14 01:28:11
好几年前封装的框架一直没上传,趁现在升级写下。
? ? ?简介Retrofit是android的网络请求库,是一个RESTful的HTTP网络请求框架的封装(基于okhttp)。它内部网络请求的工作,本质上是通过OkHttp完成,而Retrofit仅负责网络请求接口的封装。
目录
二、网络请求分为三个包分别为data、httptool、request三个pakage包。
? ? ? ? ? ? ? 3.1.1HttpBaseResponse
????????3.1.3.HttpResponseInterface
3.2.4.ResponseConverterFactory处理服务器返回数据将数据转换成对象
一、引包
// retrofit2
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
// RxJava
implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'
implementation 'io.reactivex.rxjava2:rxjava:2.1.12'
二、网络请求分为三个包分别为data、httptool、request三个pakage包。
? ? ??data:数据处理封装类
? ? ??httptool:网络请求工具
? ? ? request:请求处理
三、pakage包分析
? ? ? ?3.1.data
? ? ? ? ? ? ? data中有三个对象,分别对应? HttpBaseResponse(http响应处理)、HttpDisposable(与rxjava请求回调处理)、HttpResponseInterface(获取处理掉code和msg后的信息)。
? ? ? ? ? ? ? 3.1.1HttpBaseResponse
/**
* @author shizhiyin
*/
public interface HttpResponseInterface {
/**
* 获取处理掉code和msg后的信息
*
* @param gson
* @param response
* @return
*/
String getResponseData(Gson gson, String response);
}
? ?3.1.2.HttpDisposable
/**
* @author shizhiyin
* 返回数据
*/
public abstract class HttpDisposable<T> extends DisposableObserver<T> {
public HttpDisposable() {
}
@Override
protected void onStart() {
}
@Override
public void onNext(T value) {
success(value);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
public abstract void success(T t);
}
????????3.1.3.HttpResponseInterface
/**
* @author shizhiyin
*/
public interface HttpResponseInterface {
/**
* 获取处理掉code和msg后的信息
*
* @param gson
* @param response
* @return
*/
String getResponseData(Gson gson, String response);
}
3.2.httptool 为http工具类的封装
? ? 3.2.1 添加cookie拦截
public class AddCookiesInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
if (!NetworkUtils.isConnected()) {
throw new HttpException("网络连接异常,请检查网络后重试");
}
Request.Builder builder = chain.request().newBuilder();
HashSet<String> preferences = Hawk.get(Constants.HawkCode.COOKIE);
if (preferences != null) {
for (String cookie : preferences) {
builder.addHeader("Cookie", cookie);
Log.v("OkHttp", "Adding Header: " + cookie);
// This is done so I know which headers are being added; this interceptor is used after the normal logging of OkHttp
}
}
return chain.proceed(builder.build());
}
}
? 3.2.2.HttpException自定义异常抛出
? ??
/**
* 自定义异常抛出
*
* @author shizhiyin
*/
public class HttpException extends RuntimeException {
public HttpException(String message) {
this.message = message;
}
public HttpException(int code, String message) {
this.message = message;
this.code = code;
}
@Override
public String getMessage() {
return TextUtils.isEmpty(message) ? "" : message;
}
public int getCode() {
return code;
}
private int code;
private String message;
}
? 3.2.3?HttpInterceptor请求拦截器
/**
* 自定义
* 请求拦截器
*
* @author shizhiyin
*/
public class HttpInterceptor implements Interceptor {
private static final Charset UTF8 = Charset.forName("UTF-8");
private static String REQUEST_TAG = "请求";
/**
* 通过拦截器
* 添加请求头
* 及
* 打印请求结果
*/
@Override
public Response intercept(Chain chain) throws IOException {
if (!NetworkUtils.isConnected()) {
throw new HttpException("网络连接异常,请检查网络后重试");
}
Request request = chain.request();
request = getHeaderRequest(request);
//打印请求
logRequest(request);
Response response = chain.proceed(request);
//
// if (!response.headers("Set-Cookie").isEmpty()) {
// HashSet<String> cookies = new HashSet<>();
// for (String header : response.headers("Set-Cookie")) {
// cookies.add(header);
// }
// Hawk.put(Constants.HawkCode.COOKIE, cookies);
// }
//
//打印响应
logResponse(response);
return response;
}
/**
* 添加header
*/
public Request getHeaderRequest(Request request) {
// LoginRequestBean loginData =null;
LoginRequestBean loginData = Hawk.get(Constants.HawkCode.LOGIN_TOKEN_INFO);
Request headRequest;
if (loginData != null) {
// Logger.d("===缓存获取token=="+loginData.getToken());
headRequest = request
.newBuilder()
.addHeader("Content-Type", "application/json")
.addHeader("terminal", "doctor")
.addHeader("Authorization", loginData.getToken())
.build();
} else {
headRequest = request
.newBuilder()
.addHeader("Content-Type", "application/json")
.addHeader("terminal", "doctor")
.build();
}
return headRequest;
}
/**
* 打印请求信息
*
* @param request
*/
private void logRequest(Request request) {
Log.d(REQUEST_TAG + "method", request.method());
Log.d(REQUEST_TAG + "url", request.url().toString());
Log.d(REQUEST_TAG + "header", request.headers().toString());
if (request.method().equals("GET")) {
return;
}
try {
RequestBody requestBody = request.body();
String parameter = null;
Buffer buffer = new Buffer();
requestBody.writeTo(buffer);
parameter = buffer.readString(UTF8);
buffer.flush();
buffer.close();
Log.d(REQUEST_TAG + "参数", parameter);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 打印返回结果
*
* @param response
*/
private void logResponse(Response response) {
try {
ResponseBody responseBody = response.body();
String rBody = null;
BufferedSource source = responseBody.source();
source.request(Long.MAX_VALUE);
Buffer buffer = source.buffer();
Charset charset = UTF8;
MediaType contentType = responseBody.contentType();
if (contentType != null) {
try {
charset = contentType.charset(UTF8);
} catch (UnsupportedCharsetException e) {
e.printStackTrace();
}
}
rBody = buffer.clone().readString(charset);
// Logger.d("===business==响应体==="+rBody);
Log.d(REQUEST_TAG + "返回值", rBody);
} catch (IOException e) {
e.printStackTrace();
}
}
}
3.2.4.ResponseConverterFactory处理服务器返回数据将数据转换成对象
/**
* 处理服务器返回数据
* 将数据转换成对象
*
* @author shizhiyin
*/
public class ResponseConverterFactory extends Converter.Factory {
private final Gson mGson;
public ResponseConverterFactory(Gson gson) {
this.mGson = gson;
}
public static ResponseConverterFactory create() {
return create(new Gson());
}
public static ResponseConverterFactory create(Gson gson) {
if (gson == null) throw new NullPointerException("gson == null");
return new ResponseConverterFactory(gson);
}
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
return new BaseResponseBodyConverter(type);
}
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
return GsonConverterFactory.create().requestBodyConverter(type, parameterAnnotations, methodAnnotations, retrofit);
}
private class BaseResponseBodyConverter<T> implements Converter<ResponseBody, T> {
private Type mType;
private BaseResponseBodyConverter(Type mType) {
this.mType = mType;
}
@Override
public T convert(ResponseBody response) {
Object object;
try {
String strResponse = response.string();
if (TextUtils.isEmpty(strResponse)) {
throw new HttpException("返回值是空的—-—");
}
if (HttpFactory.httpResponseInterface == null) {
throw new HttpException("请实现接口HttpResponseInterface—-—");
} else {
// String strData = HttpFactory.httpResponseInterface.getResponseData(mGson, strResponse);
// Logger.d("==login返回值是=="+strData.toString());
// strResponse 保留接口返回的全部数据
// strData 只保留接口返回的data数据
object = mGson.fromJson(strResponse, mType);
}
} catch (Exception e) {
throw new HttpException(e.getMessage());
} finally {
response.close();
}
return (T) object;
}
}
}
?3.2.5?UploadUtils 文件上传
/**
* Created by shizhiyin.
* Time:2023年10月16日.
* Retrofit文件上传
*/
public class UploadUtils {
private static final String FILE_NOT_NULL = "文件不能为空";
private static final String FILE_PATH_NOT_NULL = "文件路径不能为空";
public static MultipartBody.Part getMultipartBody(String path) {
if (TextUtils.isEmpty(path)) throw new NullPointerException(FILE_PATH_NOT_NULL);
File file = new File(path);
if (file.exists()) {
RequestBody requestFile =
RequestBody.create(MediaType.parse("application/octet-stream"), file);
MultipartBody.Part body =
MultipartBody.Part.createFormData("imgFile", file.getName(), requestFile);
return body;
} else {
// throw new NullPointerException(FILE_NOT_NULL);
return null;
}
}
public static MultipartBody.Part getMultipartBody(File file) {
if (file.exists()) {
RequestBody requestFile =
RequestBody.create(MediaType.parse("application/octet-stream"), file);
MultipartBody.Part body =
MultipartBody.Part.createFormData("file", file.getName(), requestFile);
return body;
} else {
throw new NullPointerException(FILE_NOT_NULL);
}
}
public static List<MultipartBody.Part> getMultipartBodysForFile(List<File> files) {
if (files.isEmpty()) throw new NullPointerException(FILE_NOT_NULL);
MultipartBody.Builder builder = new MultipartBody.Builder();
for (File file : files) {
if (file.exists()) {
RequestBody requestFile =
RequestBody.create(MediaType.parse("application/octet-stream"), file);
builder.addFormDataPart("file", file.getName(), requestFile);
} else {
throw new NullPointerException(FILE_NOT_NULL);
}
}
return builder.build().parts();
}
public static List<MultipartBody.Part> getMultipartBodysForPath(List<String> paths) {
if (paths.isEmpty()) throw new NullPointerException(FILE_PATH_NOT_NULL);
MultipartBody.Builder builder = new MultipartBody.Builder();
for (String path : paths) {
File file = new File(path);
if (file.exists()) {
RequestBody requestFile =
RequestBody.create(MediaType.parse("application/octet-stream"), file);
builder.addFormDataPart("file", file.getName(), requestFile);
} else {
throw new NullPointerException(FILE_NOT_NULL);
}
}
return builder.build().parts();
}
}
3.3 request
3.3.1.ApiAddress网络请求接口地址
public interface ApiAddress {
/**
* 新增原生登录接口
* LogingResponseBean
*/
@POST("auth/login")
Observable<LogingResponseBean> LoginPost(@Body JSONObject parmas);
}
3.3.2.HttpFactory网络请求
/**
* @author shizhiyin
* 网络请求
*/
public class HttpFactory {
public static String HTTP_HOST_URL = "";
public static HttpResponseInterface httpResponseInterface = null;
private HttpFactory() {
}
/**
* 设置HttpClient
*/
private static OkHttpClient HTTP_CLIENT =
new Builder()
//添加自定义拦截器
.addInterceptor(new HttpInterceptor())
.addInterceptor(new AddCookiesInterceptor())
//设置超时时间
.connectTimeout(60, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
.build();
private static Retrofit retrofit = null;
public static <T> T getChangeUrlInstance(String url, Class<T> service) {
return new Retrofit.Builder().baseUrl(url)
.addConverterFactory(ResponseConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(HTTP_CLIENT)
.build()
.create(service);
}
public static <T> T getInstance(Class<T> service) {
if (retrofit == null) {
retrofit = new Retrofit.Builder().baseUrl(HTTP_HOST_URL)
.addConverterFactory(ResponseConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(HTTP_CLIENT)
.build();
}
return retrofit.create(service);
}
@SuppressWarnings("unchecked")
public static <T> ObservableTransformer<T, T> schedulers() {
return new ObservableTransformer<T, T>() {
@Override
public ObservableSource<T> apply(Observable<T> upstream) {
return upstream.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
}
};
}
}
3.3.3HttpRequest
/**
* @author shizhiyin
*/
public class HttpRequest {
private static ApiAddress Instance;
public static ApiAddress getInstance() {
if (Instance == null) {
synchronized (HttpRequest.class) {
if (Instance == null) {
Instance = HttpFactory.getInstance(ApiAddress.class);
}
}
}
return Instance;
}
public static ApiAddress getInstance(String url) {
return HttpFactory.getChangeUrlInstance(url, ApiAddress.class);
}
}
3.3.4ServerAddress
/**
* 服务器地址
*
* @author shizhiyin
*/
public class ServerAddress {
public static final String API_DEFAULT_HOST = "https://........com/";
}
四、使用
4.1.在应用的applacation中初始化
/**
* 请求配置
*/
public static void setHttpConfig() {
HttpFactory.HTTP_HOST_URL = ServerAddress.getApiDefaultHost();
HttpFactory.httpResponseInterface = (gson, response) -> {
if (firstOpen) {
firstOpen = false;
return response;
}
HttpBaseResponse httpResponse = gson.fromJson(response, HttpBaseResponse.class);
if (httpResponse.errorCode != 0) {
throw new HttpException(httpResponse.errorCode, httpResponse.errorMsg);
}
return gson.toJson(httpResponse.data);
};
}
4.2.请求示例
private void login(String name, String pwd) {
LoginRequestBean loginRequestBean = new LoginRequestBean(name, pwd);
HttpRequest.getInstance(ServerAddress.BASE_URL)
.LoginPost((JSONObject) JSON.toJSON(loginRequestBean))
.compose(HttpFactory.schedulers())
.subscribe(new HttpDisposable<LogingResponseBean>() {
@Override
public void success(LogingResponseBean bean) {
}
@Override
public void onError(Throwable e) {
super.onError(e);
Logger.d("====login=登录onError==" + e.toString());
}
});
}
最后要感谢玩Android开源平台提供的参考。
文章来源:https://blog.csdn.net/shi450561200/article/details/134845784
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!