HttpURLConnection基本使用

本文关于HttpURLConnection的基本使用,用来做为备忘记录,方便查询。

GET操作

private void requestGet(HashMap<String, String> paramsMap) {
    try {
        String baseUrl = "https://baidu.com/";
        StringBuilder tempParams = new StringBuilder();
        int pos = 0;
        for (String key : paramsMap.keySet()) {
            if (pos > 0) {
                tempParams.append("&");
            }
            tempParams.append(String.format("%s=%s", key, URLEncoder.encode(paramsMap.get(key),"utf-8")));
            pos++;
        }
        String requestUrl = baseUrl + tempParams.toString();
        // 新建一个URL对象
        URL url = new URL(requestUrl);
        // 打开一个HttpURLConnection连接
        HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
        // 设置连接主机超时时间
        urlConn.setConnectTimeout(5 * 1000);
        // 设置从主机读取数据超时
        urlConn.setReadTimeout(5 * 1000);
        // 设置是否使用缓存  默认是true
        urlConn.setUseCaches(true);
        // 设置为Post请求
        urlConn.setRequestMethod("GET");
        // urlConn设置请求头信息
        // 设置请求中的媒体类型信息。
        urlConn.setRequestProperty("Content-Type", "application/json");
        // 设置客户端与服务连接类型
        urlConn.addRequestProperty("Connection", "Keep-Alive");
        // 开始连接
        urlConn.connect();
        // 判断请求是否成功
        if (urlConn.getResponseCode() == 200) {
            // 获取返回的数据
            String result = streamToString(urlConn.getInputStream());
            Log.e(TAG, "Get方式请求成功,result--->" + result);
        } else {
            Log.e(TAG, "Get方式请求失败");
        }
        // 关闭连接
        urlConn.disconnect();
    } catch (Exception e) {
        Log.e(TAG, e.toString());
    }

POST请求

private void requestPost(HashMap<String, String> paramsMap) {
    try {
        String baseUrl = "https://baidu.com/";
        // 合成参数
        StringBuilder tempParams = new StringBuilder();
        int pos = 0;
        for (String key : paramsMap.keySet()) {
            if (pos > 0) {
                tempParams.append("&");
            }
            tempParams.append(String.format("%s=%s", key,  URLEncoder.encode(paramsMap.get(key),"utf-8")));
            pos++;
        }
        String params =tempParams.toString();
        // 请求的参数转换为byte数组
        byte[] postData = params.getBytes();
        // 新建一个URL对象
        URL url = new URL(baseUrl);
        // 打开一个HttpURLConnection连接
        HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
        // 设置连接超时时间
        urlConn.setConnectTimeout(5 * 1000);
        // 设置从主机读取数据超时
        urlConn.setReadTimeout(5 * 1000);
        // Post请求必须设置允许输出 默认false
        urlConn.setDoOutput(true);
        // 设置请求允许输入 默认是true
        urlConn.setDoInput(true);
        // Post请求不能使用缓存
        urlConn.setUseCaches(false);
        // 设置为Post请求
        urlConn.setRequestMethod("POST");
        // 设置本次连接是否自动处理重定向
        urlConn.setInstanceFollowRedirects(true);
        // 配置请求Content-Type
        urlConn.setRequestProperty("Content-Type", "application/json");
        // 开始连接
        urlConn.connect();
        // 发送请求参数
        DataOutputStream dos = new DataOutputStream(urlConn.getOutputStream());
        dos.write(postData);
        dos.flush();
        dos.close();
        // 判断请求是否成功
        if (urlConn.getResponseCode() == 200) {
            // 获取返回的数据
            String result = streamToString(urlConn.getInputStream());
            Log.e(TAG, "Post方式请求成功,result--->" + result);
        } else {
            Log.e(TAG, "Post方式请求失败");
        }
        // 关闭连接
        urlConn.disconnect();
    } catch (Exception e) {
        Log.e(TAG, e.toString());
    }
}

Download操作

private void downloadFile(String fileUrl){
    try {
        // 新建一个URL对象
        URL url = new URL(fileUrl);
        // 打开一个HttpURLConnection连接
        HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
        // 设置连接主机超时时间
        urlConn.setConnectTimeout(5 * 1000);
        // 设置从主机读取数据超时
        urlConn.setReadTimeout(5 * 1000);
        // 设置是否使用缓存  默认是true
        urlConn.setUseCaches(true);
        // 设置为Post请求
        urlConn.setRequestMethod("GET");
        // urlConn设置请求头信息
        // 设置请求中的媒体类型信息。
        urlConn.setRequestProperty("Content-Type", "application/json");
        // 设置客户端与服务连接类型
        urlConn.addRequestProperty("Connection", "Keep-Alive");
        // 开始连接
        urlConn.connect();
        // 判断请求是否成功
        if (urlConn.getResponseCode() == 200) {
            String filePath="";
            File  descFile = new File(filePath);
            FileOutputStream fos = new FileOutputStream(descFile);;
            byte[] buffer = new byte[1024];
            int len;
            InputStream inputStream = urlConn.getInputStream();
            while ((len = inputStream.read(buffer)) != -1) {
                // 写到本地
                fos.write(buffer, 0, len);
            }
        } else {
            Log.e(TAG, "文件下载失败");
        }
        // 关闭连接
        urlConn.disconnect();
    } catch (Exception e) {
        Log.e(TAG, e.toString());
    }
}


上传操作

private void upLoadFile(String filePath, HashMap<String, String> paramsMap) {
    try {
        String baseUrl = "https://baidu.com/uploadFile";
        File file = new File(filePath);
        // 新建url对象
        URL url = new URL(baseUrl);
        // 通过HttpURLConnection对象,向网络地址发送请求
        HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
        // 设置该连接允许读取
        urlConn.setDoOutput(true);
        // 设置该连接允许写入
        urlConn.setDoInput(true);
        // 设置不能适用缓存
        urlConn.setUseCaches(false);
        // 设置连接超时时间
        urlConn.setConnectTimeout(5 * 1000);   // 设置连接超时时间
        // 设置读取超时时间
        urlConn.setReadTimeout(5 * 1000);   // 读取超时
        // 设置连接方法post
        urlConn.setRequestMethod("POST");
        // 设置维持长连接
        urlConn.setRequestProperty("connection", "Keep-Alive");
        // 设置文件字符集
        urlConn.setRequestProperty("Accept-Charset", "UTF-8");
        // 设置文件类型
        urlConn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + "*****");
        String name = file.getName();
        DataOutputStream requestStream = new DataOutputStream(urlConn.getOutputStream());
        requestStream.writeBytes("--" + "*****" + "\r\n");
        // 发送文件参数信息
        StringBuilder tempParams = new StringBuilder();
        tempParams.append("Content-Disposition: form-data; name=\"" + name + "\"; filename=\"" + name + "\"; ");
        int pos = 0;
        int size = paramsMap.size();
        for (String key : paramsMap.keySet()) {
            tempParams.append( String.format("%s=\"%s\"", key, paramsMap.get(key), "utf-8"));
            if (pos < size-1) {
                tempParams.append("; ");
            }
            pos++;
        }
        tempParams.append("\r\n");
        tempParams.append("Content-Type: application/octet-stream\r\n");
        tempParams.append("\r\n");
        String params = tempParams.toString();
        requestStream.writeBytes(params);
        //发送文件数据
        FileInputStream fileInput = new FileInputStream(file);
        int bytesRead;
        byte[] buffer = new byte[1024];
        DataInputStream in = new DataInputStream(new FileInputStream(file));
        while ((bytesRead = in.read(buffer)) != -1) {
            requestStream.write(buffer, 0, bytesRead);
        }
        requestStream.writeBytes("\r\n");
        requestStream.flush();
        requestStream.writeBytes("--" + "*****" + "--" + "\r\n");
        requestStream.flush();
        fileInput.close();
        int statusCode = urlConn.getResponseCode();
        if (statusCode == 200) {
            // 获取返回的数据
            String result = streamToString(urlConn.getInputStream());
            Log.e(TAG, "上传成功,result--->" + result);
        } else {
            Log.e(TAG, "上传失败");
        }
    } catch (IOException e) {
        Log.e(TAG, e.toString());
    }
}

注意:

  • HttpURLConnection的connect()函数,实际上只是建立了一个与服务器的tcp连接,并没有实际发送http请求。 无论是post还是get,http请求实际上直到HttpURLConnection的getInputStream()这个函数里面才正式发送出去。

  • 在用POST方式发送URL请求时,URL请求参数的设定顺序是重中之重,对connection对象的一切配置(那一堆set函数) 都必须要在connect()函数执行之前完成。而对outputStream的写操作,又必须要在inputStream的读操作之前。这些顺序实际上是由http请求的格式决定的。

  • http请求实际上由两部分组成,一个是http头,所有关于此次http请求的配置都在http头里面定义, 一个是正文content。connect()函数会根据HttpURLConnection对象的配置值生成http头部信息,因此在调用connect函数之前,就必须把所有的配置准备好。

  • 在http头后面紧跟着的是http请求的正文,正文的内容是通过outputStream流写入的,实际上outputStream不是一个网络流,充其量是个字符串流,往里面写入的东西不会立即发送到网络, 而是存在于内存缓冲区中,待outputStream流关闭时,根据输入的内容生成http正文。至此,http请求的东西已经全部准备就绪。在getInputStream()函数调用的时候,就会把准备好的http请求 正式发送到服务器了,然后返回一个输入流,用于读取服务器对于此次http请求的返回信息。由于http 请求在getInputStream的时候已经发送出去了(包括http头和正文),因此在getInputStream()函数 之后对connection对象进行设置(对http头的信息进行修改)或者写入outputStream(对正文进行修改)都是没有意义的了,执行这些操作会导致异常的发生。

参考:
https://www.jianshu.com/p/d658a75daa2f

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,657评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,889评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,057评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,509评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,562评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,443评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,251评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,129评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,561评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,779评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,902评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,621评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,220评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,838评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,971评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,025评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,843评论 2 354

推荐阅读更多精彩内容

  • 6.1 公钥密钥加密原理 6.1.1 基础知识 密钥:一般就是一个字符串或数字,在加密或者解密时传递给加密/解密算...
    AndroidMaster阅读 4,011评论 1 8
  • Android中通过HttpRequest与服务器端进行JSON格式数据交互 JSON(JavaScript Ob...
    cxm11阅读 2,101评论 0 0
  • HttpURLConnection和HttpClient 第一篇系列文章中我们说过,volley的底层是使用Htt...
    抽象语法树阅读 454评论 0 0
  • 要使用 HttpURLConnection,最好对一些基础概念有所认识,比如 TCP/IP 协议,HTTP 报文,...
    十二书阅读 28,776评论 2 19
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,656评论 18 139