OkHttp简易封装和使用

本文介绍了如何对OkHttp进行简易封装,以减少重复代码。封装后,调用者只需一行代码即可发送Post请求。内容包括Android端的封装类如CommonRequest、RequestParams、ResponseListener、ResultCallback和OkHttpUtil的详细说明,以及测试代码示例,涵盖GET、POST请求及文件上传等操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

常规情况下,OkHttp发送一个Post请求:

OkHttpClient okHttpClient = new OkHttpClient.Builder().build();
        FormBody.Builder formBodyBuilder = new FormBody.Builder();
        formBodyBuilder.add("username", "star");
        formBodyBuilder.add("password", "123");
        FormBody formBody = formBodyBuilder.build();
        Request request = new Request.Builder().url("http://10.0.2.2:8080/Struts2/app_postForm").post(formBody).build();
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.i("debug", "postRequest().... onFailure" + e.getMessage());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                Log.i("debug", "postRequest().... onResponse");
                final String result = response.body().string();
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        textView.setText(result);
                    }
                });
            }
        });

由此可见,在没有封装的情况下,如果发送请求有多处,那么代码量还是蛮多的。

而封装之后的调用为:
OkHttpUtil.post(url,params,callback)

进入主题:

一:服务端
使用Struts2搭建,主要包括两个Action,AppAction和UploadAction.

public class AppAction extends ActionSupport {

    private String username;

    private String password;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String postForm() {
        System.out.println("postForm......................");
        System.out.println("Android: username=" + username + ",password="
                + password);
        return SUCCESS;
    }

    public String postJson() throws Exception {
        HttpServletRequest request = ServletActionContext.getRequest();
        InputStream is = request.getInputStream();
        int len = 0;
        StringBuilder sb = new StringBuilder();
        byte[] buffer = new byte[1024];
        while ((len = is.read(buffer)) != -1) {
            sb.append(new String(buffer, 0, len));
        }
        System.out.println("接收到的json= " + sb.toString());
        return SUCCESS;
    }

    public String get() throws IOException {
        System.out.println("Android: username=" + username);
        HttpServletResponse response = ServletActionContext.getResponse();
        response.getWriter().write("get success");
        return SUCCESS;
    }

    public String getParams() {
        System.out.println("username=" + username);
        return SUCCESS;
    }

}
public class UploadAction extends ActionSupport {

    private String username;

    private String password;

    private File file; // pic名称必须和文件表单项中的name属性值相同。

    private String fileFileName; // 文件名称必须为文件表单项中的name属性值为前缀,后缀必须是FileName

    private String fileContentType;// 文件名称必须为文件表单项中的name属性值为前缀,后缀必须是ContentType

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public File getFile() {
        return file;
    }

    public void setFile(File file) {
        this.file = file;
    }

    public String getFileFileName() {
        return fileFileName;
    }

    public void setFileFileName(String fileFileName) {
        this.fileFileName = fileFileName;
    }

    public String getFileContentType() {
        return fileContentType;
    }

    public void setFileContentType(String fileContentType) {
        this.fileContentType = fileContentType;
    }

    /**
     * 处理上传文件和表单
     * 
     * @return
     * @throws Exception
     */
    public String uploadFileForm() throws Exception {
        System.out.println("uploadFileForm()........");
        System.out.println("fileName = " + fileFileName);
        System.out.println("username = " + username + ",password=" + password);
        HttpServletRequest request = ServletActionContext.getRequest();
        String path = request.getRealPath("/file");
        InputStream is = new FileInputStream(file);
        OutputStream os = new FileOutputStream(new File(path, fileFileName));
        byte[] buffer = new byte[1024];
        int len = 0;
        while ((len = is.read(buffer)) != -1) {
            os.write(buffer, 0, len);
        }
        os.close();
        is.close();
        return SUCCESS;
    }

    /**
     * 处理上传文件
     * 
     * @return
     * @throws Exception
     */
    public String uploadFile() throws Exception {
        System.out.println("upload file......");
        HttpServletRequest request = ServletActionContext.getRequest();
        ServletInputStream is = request.getInputStream();
        String path = request.getRealPath("/file");
        File file = new File(path, "Android.png");
        OutputStream os = new FileOutputStream(file);
        byte[] buffer = new byte[1024];
        int len = 0;
        while ((len = is.read(buffer)) != -1) {
            os.write(buffer, 0, len);
        }
        os.close();
        is.close();
        return NONE;
    }

}

二:Android端
封装的类有:

  • CommonRequest:负责创建Request对象
  • RequestParams:封装请求参数,key为参数名,value为参数值
  • ResponseListener:回调接口
  • ResultCallback:实现OkHttp中Callback接口
  • OkHttpUtil:OkHttp工具类,供外界调用其方法

1. RequestParams

public class RequestParams {

    public String key;

    public String value;

    public RequestParams() {
    }

    public RequestParams(String key, String value) {
        this.key = key;
        this.value = value;
    }

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }


    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    @Override
    public String toString() {
        return "RequestParams{" +
                "key='" + key + '\'' +
                ", value='" + value + '\'' +
                '}';
    }
}

2.回调接口

public interface ResponseListener {

    void onSuccess(Object obj);

    void onFailure(Object error);

}

3. 通过Handler将请求结果回调到主线程中

public class ResultCallback implements Callback {

    private Handler mHandler = null;

    private ResponseListener listener;

    public ResultCallback(ResponseListener listener) {
        this.listener = listener;
        mHandler = new Handler(Looper.getMainLooper());
    }

    @Override
    public void onResponse(Call call, Response response) throws IOException {
        String result = response.body().string();
        sendSuccessCallback(call, result);
    }


    @Override
    public void onFailure(Call call, IOException e) {
        sendFailureCallback(call, e);
    }


    private void sendFailureCallback(Call call, final IOException e) {
        //Handler post到主线程中
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                listener.onFailure(e.getMessage());
            }
        });
    }


    private void sendSuccessCallback(Call call, final String result) {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                listener.onSuccess(result);
            }
        });
    }

}

4 . CommonRequest封装创建Request对象

public class CommonRequest {

    private static final MediaType TYPE_JSON = MediaType.parse("application/json; charset=utf-8");

    private static final MediaType TYPE_STREAM = MediaType.parse("application/octet-stream");

    /**
     * 创建 Get 请求,将参数拼装成Url
     *
     * @return
     */
    public static Request createGetRequest(String url, List<RequestParams> paramsList) {
        String realUrl = url;
        Request.Builder requestBuilder = new Request.Builder();
        StringBuffer sb = new StringBuffer(url);
        if (paramsList != null) {
            sb.append("?");
            for (RequestParams params : paramsList) {
                sb.append(params.key).append("=").append(params.value).append("&");
            }
            realUrl = sb.substring(0, sb.length() - 1);
        }
        Request request = requestBuilder.url(realUrl).get().build();
        return request;
    }

    /**
     * 创建 Post 请求,填充Form表单
     *
     * @param url
     * @param paramsList
     * @return
     */
    public static Request createPostRequest(String url, List<RequestParams> paramsList) {
        Request.Builder requestBuilder = new Request.Builder();
        FormBody.Builder formBodyBuilder = new FormBody.Builder();
        if (paramsList != null) {
            for (RequestParams params : paramsList) {
                formBodyBuilder.add(params.key, params.value);
            }
        }
        RequestBody requestBody = formBodyBuilder.build();
        Request request = requestBuilder.url(url).post(requestBody).build();
        return request;
    }

    /**
     * 创建 Post json 请求,
     *
     * @param url
     * @param jsonStr
     * @return
     */
    public static Request createPostJsonRequest(String url, String jsonStr) {
        Request.Builder requestBuilder = new Request.Builder();
        RequestBody requestBody = RequestBody.create(TYPE_JSON, jsonStr);
        Request request = requestBuilder.url(url).post(requestBody).build();
        return request;
    }

    /**
     * post 上传文件
     *
     * @param url
     * @param file
     * @return
     */
    public static Request createPostFileRequest(String url, File file) {
        Request.Builder requestBuilder = new Request.Builder();
        RequestBody requestBody = RequestBody.create(TYPE_STREAM, file);
        Request request = requestBuilder.url(url).post(requestBody).build();
        return request;
    }

    /**
     * post上传文件并提交表单
     *
     * @param url        服务端处理请求的url
     * @param fileKey    表单中上传文件域的名字,服务端定义的File变量,名称要和这个相同。
     * @param file       要上传的文件
     * @param paramsList 要提交的表单数据
     * @return
     */
    public static Request createMultiPostRequest(String url, String fileKey, File file, List<RequestParams> paramsList) {
        MultipartBody.Builder multipartBodyBuilder = new MultipartBody.Builder();
        for (RequestParams params : paramsList) {
            multipartBodyBuilder.addFormDataPart(params.key, params.value);
        }
        //文件上传enctype必须设置为 multipart/form-data
        MultipartBody multipartBody = multipartBodyBuilder.setType(MultipartBody.FORM)
                .addFormDataPart(fileKey, file.getName(), RequestBody.create(TYPE_STREAM, file))
                .build();
        Request request = new Request.Builder().url(url).post(multipartBody).build();
        return request;
    }
}

5 . OkHttp工具类,外界通过调用公共方法实现HTTP请求。

/**
 * OkHttp封装的工具类,应用层通过该类调用get,post静态方法完成相应的请求
 */

public class OkHttpUtil {

    private static final int TIME = 30;

    private static OkHttpClient okHttpClient;

    static {
        OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder();
        okHttpClientBuilder.connectTimeout(TIME, TimeUnit.SECONDS);  //设置连接超时时间
        okHttpClientBuilder.readTimeout(TIME, TimeUnit.SECONDS);    //设置读取超时时间
        okHttpClientBuilder.writeTimeout(TIME, TimeUnit.SECONDS);  //设置写入超时时间
        okHttpClient = okHttpClientBuilder.build();
    }

    /*-------------对外提供的接口--------------*/

    /**
     * 不带参数的get请求
     *
     * @param url
     * @param callback
     */
    public static void get(String url, ResultCallback callback) {
        get(url, null, callback);
    }

    /**
     * GET 请求,带参数
     *
     * @param url
     * @param paramsList
     * @param callback
     */
    public static void get(String url, List<RequestParams> paramsList, ResultCallback callback) {
        Call call = okHttpClient.newCall(CommonRequest.createGetRequest(url, paramsList));
        call.enqueue(callback);
    }

    /**
     * POST 请求,完成表单的提交
     *
     * @param url
     * @param paramsList
     * @param callback
     */
    public static void post(String url, List<RequestParams> paramsList, ResultCallback callback) {
        Call call = okHttpClient.newCall(CommonRequest.createPostRequest(url, paramsList));
        call.enqueue(callback);
    }


    /* POST 提交json字符串给服务端*/
    public static void postJson(String url, String jsonStr, ResultCallback callback) {
        Call call = okHttpClient.newCall(CommonRequest.createPostJsonRequest(url, jsonStr));
        call.enqueue(callback);
    }


    /* POST 上传文件 */
    public static void postFile(String url, File file, ResultCallback callback) {
        Call call = okHttpClient.newCall(CommonRequest.createPostFileRequest(url, file));
        call.enqueue(callback);
    }

    /**
     * 上传文件,并提交表单
     */
    public static void postFileAndForm(String url, String fileKey, File file, List<RequestParams> paramsList, ResultCallback callback) {
        Call call = okHttpClient.newCall(CommonRequest.createMultiPostRequest(url, fileKey, file, paramsList));
        call.enqueue(callback);
    }
}

6 测试代码:

(1) 发送一个GET请求

private void get() {
        OkHttpUtil.get("http://10.0.2.2:8080/Struts2/app_get", new ResultCallback(new ResponseListener() {
            @Override
            public void onSuccess(Object obj) {
                textView.setText(obj.toString());
            }

            @Override
            public void onFailure(Object error) {

            }
        }));
    }

这里写图片描述

(2) 发送一个post请求

private void post() {
        // post request
        List<RequestParams> paramsList = new ArrayList<>();
        paramsList.add(new RequestParams("username", "star123"));
        paramsList.add(new RequestParams("password", "111"));
        OkHttpUtil.post("http://10.0.2.2:8080/Struts2/app_postForm", paramsList, new ResultCallback(new ResponseListener() {
            @Override
            public void onSuccess(Object obj) {
                Log.i("debug", obj.toString());
                Toast.makeText(MainActivity.this, "success", Toast.LENGTH_LONG).show();
            }

            @Override
            public void onFailure(Object error) {
                Log.i("debug", "onFailure" + error.toString());
            }
        }));
    }

这里写图片描述
-
(3) 仅仅上传文件

private void postFile() {
        File file = new File("/mnt/sdcard", "logo1.png");
        if (!file.exists()) {
            Log.i("debug", "picture not exists");
            return;
        }
        OkHttpUtil.postFile("http://10.0.2.2:8080/Struts2/action_uploadFile", file, new ResultCallback(new ResponseListener() {
            @Override
            public void onSuccess(Object obj) {
                Log.i("debug", "post file success");
            }

            @Override
            public void onFailure(Object error) {
                Log.i("debug", "post file failed");
            }
        }));
    }

这里写图片描述

(4) 上传文件,并提交表单数据

private void postFileAndForm() {
        File file = new File("/mnt/sdcard", "logo1.png");
        if (!file.exists()) {
            Log.i("debug", "file not exists");
            return;
        }
        List<RequestParams> paramsList = new ArrayList<>();
        paramsList.add(new RequestParams("username", "xiaohei"));
        paramsList.add(new RequestParams("password", "hei@xiao"));
        OkHttpUtil.postFileAndForm("http://10.0.2.2:8080/Struts2/action_uploadFileForm", "file", file, paramsList, new ResultCallback(new ResponseListener() {
            @Override
            public void onSuccess(Object obj) {
                Log.i("debug", "post file-form success");
            }

            @Override
            public void onFailure(Object error) {
                Log.i("debug", "post file-form failed");
            }
        }));
    }

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值