Retrofit网络请求框架使用简析——Android网络请求框架(四)


题记:——

很累,累到想要放弃,但是放弃之后将会是一无所有,又不能放弃,

唯有坚持,唯有给自忆打气,才能更勇敢的走下去,因为无路可退,只能前行,

时光一去不复返,每一天都不可追回,所以要更珍惜每一存光阴


不阅世界百态,怎懂沧桑世故四字,

不观千娇百媚花开,岂知繁华与浮华,

唯有经历,才能明了



使用思路简析与准备工作:

Retrofit网络请求框架使用简析——Android网络请求框架(四)

Retrofit网络请求框架使用简析——Android网络请求框架(四)



1.获取网络请求工具类对象实例(在这里是新建了一个网络请求工具类)

public class RetrofitRxJavaHttpUtils {
    public static final String BASE_URL = "http://192.168.1.103:8080/";



    private RetrofitRxJavaHttpUtils() {
        /**
         * 在调用构造的时候分别对OkhttpClient 与Retrofit进行初时化操作
         */
        client = getHttpClientInstance();
        retrofit = getRetrofitInstance();
    }
    /**
     * 获取网络请求工具类单例对象
     */
    private static RetrofitRxJavaHttpUtils utils;
    public static RetrofitRxJavaHttpUtils getInstance() {
        if (utils == null) {
            synchronized (RetrofitRxJavaHttpUtils.class) {
                utils = new RetrofitRxJavaHttpUtils();
            }
        }
        return utils;
    }
}

2.获取OkhttpClient实例对象 (在工具类的构造中进行调用)

在获取okhttpClient实例对象的时候,设置了一些通用的信息,例如请求头信息,请求参数信息,以及网络超时,Cookie等等所以下面的这一段代码量比较大

 /**
     * 获取oKhttpClient 的实例
     * 在初始化的时候设置一些统一性的操作
     */
    private static OkHttpClient client;

    private OkHttpClient getHttpClientInstance() {
        if (client == null) {
            synchronized (RetrofitRxJavaHttpUtils.class) {
                OkHttpClient.Builder builder = new OkHttpClient.Builder();
                /**
                 *  设置添加公共的请求参数
                 */
                Interceptor addQueryParameterInterceptor = new Interceptor() {
                    @Override
                    public Response intercept(Chain chain) throws IOException {
                        Request originalRequest = chain.request();
                        Request request;
                        String method = originalRequest.method();
                        Headers headers = originalRequest.headers();
                        HttpUrl modifiedUrl = originalRequest.url().newBuilder()
                                // Provide your custom parameter here
                                .addQueryParameter("commonKey", "android")
                                .addQueryParameter("version", "1.0.0")
                                .build();
                        request = originalRequest.newBuilder().url(modifiedUrl).build();
                        return chain.proceed(request);
                    }
                };


                builder.addInterceptor(addQueryParameterInterceptor);

                /**
                 * 添加请求头
                 */
                Interceptor headerInterceptor = new Interceptor() {
                    @Override
                    public Response intercept(Chain chain) throws IOException {
                        Request originalRequest = chain.request();
                        Request.Builder requestBuilder = originalRequest.newBuilder()
                                .header("AppType", "TPOS")
                                .header("Content-Type", "application/json")
                                .header("Accept", "application/json")
                                .method(originalRequest.method(), originalRequest.body());
                        Request request = requestBuilder.build();
                        return chain.proceed(request);
                    }
                };
                builder.addInterceptor(headerInterceptor);

                /**
                 * 服务端可能需要保持请求是同一个cookie,主要看各自需求
                 * compile 'com.squareup.okhttp3:okhttp-urlconnection:3.2.0'
                 */
                CookieManager cookieManager = new CookieManager();
                cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
                builder.cookieJar(new JavaNetCookieJar(cookieManager));

                /**
                 * 设置请求超时时间
                 */
                builder.connectTimeout(15, TimeUnit.SECONDS);
                builder.readTimeout(20, TimeUnit.SECONDS);
                builder.writeTimeout(20, TimeUnit.SECONDS);
                /**
                 * 设置请求加载错误不重新连接
                 */
                builder.retryOnConnectionFailure(false);

                client = builder.build();

            }
        }

        return client;
    }



3.获取Retrofit实例对象

 /**
     * 获取Retrofit实例
     * 这里面使用到了OkhttpClient ,在这之前先要将client对象进行初始化操作
     */
    private  static  Retrofit retrofit;
    private Retrofit getRetrofitInstance(){
        if (retrofit==null){
            synchronized (RetrofitRxJavaHttpUtils.class){
                if(retrofit==null){
                    retrofit = new Retrofit.Builder()
                            .baseUrl(BASE_URL)
                            //设置 Json 转换器
                            .addConverterFactory(GsonConverterFactory.create())
                            //RxJava 适配器
                            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                            .client(client)
                            .build();
                }
            }
        }
        return retrofit;
    }


4. Post请求提交参数形式为Key - Value 

在发起请求的时候 ,先通过retrofit对象create服务对象,然后再调起异步请求


定义服务请求接口

public interface RetrofitRxInterface {

    /**
     * 提交KEY VALEU 形式的参数到服务器
     * @param retrofit
     * @param str
     * @return
     */
    @POST("/OkhttpAppLication//test")
    Observable<HttpResult> request(@Query("username") String retrofit, @Query("password") String str);

    /**
     * 提交一个Json数据到服务器
     * @param apiInfo
     * @return
     */
    @POST("/OkhttpAppLication//test")
    Call<ResponseBody> username(@Body UserInfo apiInfo);

    /**
     * 提交一个数组信息到服务器
     * @param id
     * @param linked
     * @return
     */
    @GET("/OkhttpAppLication//test")
    Call<ResponseBody> submitArray(@Query("id") String id, @Query("linked[]") String... linked);


    /**
     * 上传单个文件
     * @param description
     * @param imgs
     * @return
     */
    @Multipart
    @POST("/OkhttpAppLication/LoadFileServlet")
    Call<ResponseBody> uploadFile(@Part("fileName") String description,
                             @Part("file")RequestBody imgs);

    /**
     * 上传多个文件
     * @param pictureName
     * @param params
     * @return
     */
    @Multipart
    @POST("/OkhttpAppLication/LoadFileServlet")
    Call<ResponseBody> uploadFiles(@Part("pictureName") RequestBody pictureName, @PartMap Map<String, RequestBody> params);
}

然后再在发起请求的时候通过retrofit来使用

    /**
     * 提交参数为KEY - VALUE 形式
     * @param name
     * @param password
     */
    public void asyncPostKeyValueRequest(String name, String password) {

        RetrofitRxInterface user = retrofit.create(RetrofitRxInterface.class);

        Observable<HttpResult> observable = user.request(name, password);

        observable.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<HttpResult>() {
                    @Override
                    public void onCompleted() {
                        /**
                         * 请求执行完毕执行此方法
                         */
                        System.out.println("complete ");
                    }

                    @Override
                    public void one rror(Throwable e) {
                        System.out.println("error: " + e.getMessage());
                    }

                    @Override
                    public void onNext(HttpResult user) {
                        /**
                         * 获取服务器数据
                         */
                        System.out.println("" + user.toString());
                    }
                });

    }

在页面中的使用方法

public class MainActivity extends AppCompatActivity {
  
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        String username = "admin";
        String password = "12345";

        RetrofitRxJavaHttpUtils.getInstance().asyncPostKeyValueRequest(username,password);


}
}

备注:

1.使用到了一个RetrofitRxInterface,这是为Retrofit网络请求框架进行服务的接口,

2.使用到了一个HttpResult,这个类是用来接收服务器返回数据的与服务器端保持一至就可以,


5.Post请求提交JSON数据到服务器

 /**
     * 提交JSON数据到服务器
     */
    public void asyncPostJsonRequest(){

        /**
         * 获取服务接口
         */
        RetrofitRxInterface user1 = retrofit.create(RetrofitRxInterface.class);

        /**
         * 构造提交数据
         */
        UserInfo userInfo = new UserInfo();
        userInfo.username = "xhao longs";
        userInfo.password = "admin";

        /**
         * 发起回调请求
         */
        Call<ResponseBody> username = user1.username(userInfo);

        username.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, retrofit2.Response<ResponseBody> response) {
                /**
                 * 请求成功相关回调
                 */
                ResponseBody body = response.body();
                try {
                    String string = body.string();
                    System.out.println(string);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                String s = body.toString();

                System.out.println("body string "+s);
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {

            }
        });
    }

调用方法:

public class MainActivity extends AppCompatActivity {
    public static final String BASE_URL = "http://192.168.1.103:8080/OkhttpAppLication/test";
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        RetrofitRxJavaHttpUtils.getInstance().asyncPostJsonRequest();


}}


提交的数据格式 为:

{"password":"admin","username":"xhao longs"}


6. 上传单个文件 (这里上传的是图片)


 <pre name="code" class="java">public void asyncUpLoadFile(){

        String filename = "/storage/emulated/0/custom/2016/6/18//20160623135328.PNJE";

        /**
         * 封装上传文件
         */
        File picture= new File(filename);
        RequestBody requestFile = RequestBody.create(MediaType.parse("application/octet-stream"), picture);

        /**
         * 调起上传单文件服务请求接口并发起回调请求
         */
        RetrofitRxInterface user = retrofit.create(RetrofitRxInterface.class);
        /**
         * 这里上传的文件名称为dsf
         */
        Call<ResponseBody> responseBodyCall = user.uploadFile("dsf", requestFile);
        responseBodyCall.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, retrofit2.Response<ResponseBody> response) {
                ResponseBody body = response.body();
                try {
                    String string = body.string();
                    System.out.println(string);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
                System.out.println("err:_ "+t.getMessage());
            }
        });
    }



调用方法:

public class MainActivity extends AppCompatActivity {
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        RetrofitRxJavaHttpUtils.getInstance().asyncUpLoadFile();


}
}



7. 上传多文件 

public void asyncUpLoadFiles(){

        String filename = "/storage/emulated/0/custom/2016/6/18//20160623135328.PNJE";

        RequestBody pictureNameBody = RequestBody.create(MediaType.parse("Content-Disposition"), "form-data;name=pictureName");
        /**
         * 封装文件
         */
        File picture= new File(filename);
        /**
         * 获取请求RequestBody
         */
        RequestBody requestFile = RequestBody.create(MediaType.parse("application/octet-stream"), picture);
        /**
         * 封装上传文件信息
         * 这里只封装了一张图片
         */
        Map<String, RequestBody> params = new HashMap<>();
        params.put("picture\"; filename=\"" + picture.getName() + "", requestFile);

        /**
         * 调起服务请求接口并发起回调请求
         */
        RetrofitRxInterface user = retrofit.create(RetrofitRxInterface.class);

        Call<ResponseBody> responseBodyCall = user.uploadFiles(pictureNameBody, params);

        responseBodyCall.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, retrofit2.Response<ResponseBody> response) {
                ResponseBody body = response.body();
                try {
                    String string = body.string();
                    System.out.println(string);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
                System.out.println("err:_ "+t.getMessage());
            }
        });
    }

调用方法与上传单文件方法一至


上一篇:三方库源码笔记(7)-超详细的 Retrofit 源码解析


下一篇:学习笔记——Annotation注解(@Override、@Deprecated、@SuppressWarning)