Rtrofit+Rxjava网络请求封装

2023-12-14 01:28:11

好几年前封装的框架一直没上传,趁现在升级写下。

? ? ?简介Retrofit是android的网络请求库,是一个RESTful的HTTP网络请求框架的封装(基于okhttp)。它内部网络请求的工作,本质上是通过OkHttp完成,而Retrofit仅负责网络请求接口的封装。

目录

一、引包

二、网络请求分为三个包分别为data、httptool、request三个pakage包。

三、pakage包分析

? ? ? ?3.1.data

? ? ? ? ? ? ? 3.1.1HttpBaseResponse

? ?3.1.2.HttpDisposable

????????3.1.3.HttpResponseInterface

3.2.httptool 为http工具类的封装

? ? 3.2.1 添加cookie拦截

? 3.2.2.HttpException自定义异常抛出

? 3.2.3?HttpInterceptor请求拦截器

3.2.4.ResponseConverterFactory处理服务器返回数据将数据转换成对象

?3.2.5?UploadUtils 文件上传

3.3 request

3.3.1.ApiAddress网络请求接口地址

3.3.2.HttpFactory网络请求

3.3.3HttpRequest

3.3.4ServerAddress

四、使用

4.1.在应用的applacation中初始化

4.2.请求示例


一、引包

    //    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
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。