展开菜单
首页 精品内容 本月促销 装机必备 Windows PDF教程 macOS软件 IOS软件 Android AI 专题
全部分类

当前位置:

首页 > 系统应用 > 7.1.3 Android HTTP请求方式:HttpURLConnection

7.1.3 Android HTTP请求方式:HttpURLConnection

Android Studio macOS版
Android Studio macOS版

Android Studio 是 Google 面向安卓应用开发提供的官方集成开发环境,基于 IntelliJ IDEA 构建。它整合智能代码编辑、Gradle 构建、界面预览、设备模拟、性能分析、调试测试及 APK 分析等工具。

Mac 2026-10-13
数据库 编程开发 服务器管理 集成开发环境
立即下载

本节引言: 前面两节我们学习的都是一些概念性的东西,Http的协议以及协议头的一些东东,而本节我们 就要堆码了,而本节学习的是Android为我们提供的Http请求方式之一:HttpURLConnection, 除了这种,还有一种还有一种HttpClient,后者我们会下一节讲!不过前者一旦请求复杂

本文目录

    本节引言:

    前面两节我们学习的都是一些概念性的东西,Http的协议以及协议头的一些东东,而本节我们 就要堆码了,而本节学习的是Android为我们提供的Http请求方式之一:HttpURLConnection, 除了这种,还有一种还有一种HttpClient,后者我们会下一节讲!不过前者一旦请求复杂起来,使用起来 非常麻烦,而后者我们Ja va抓包也经常会用到,是Apache的,毕竟不是谷歌亲儿子,而在4.4版本 HttpURLConnection已被替换成OkHttp了!好吧,与时俱进,决定讲完HttpClient也来会会这个 OkHttp!对了,一般我们实际开发并不会用HttpURLConnection和HttpClient,使用别人封装 好的第三方网络请求框架,诸如:Volley,android-async-http,loopj等,因为网络操作涉及到 异步以及多线程,自己动手撸的话,很麻烦,所以实际开发还是直接用第三方!!当然学习下也 无妨,毕竟第三方也是在这些基础上撸起来的,架构逼格高,各种优化!好的,话不多说,开始 本节内容!

    1.HttpURLConnection的介绍

    答:一种多用途、轻量极的HTTP客户端,使用它来进行HTTP操作可以适用于大多数的应用程序。 虽然HttpURLConnection的API提供的比较简单,但是同时这也使得我们可以更加容易地去使 用和扩展它。继承至URLConnection,抽象类,无法直接实例化对象。通过调用openCollection() 方法获得对象实例,默认是带gzip压缩的;

    2.HttpURLConnection的使用步骤

    使用HttpURLConnection的步骤如下:

    • 创建一个URL对象: URL url = new URL(https://www.baidu.com);
    • 调用URL对象的openConnection( )来获取HttpURLConnection对象实例: HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    • 设置HTTP请求使用的方法:GET或者POST,或者其他请求方式比如:PUT conn.setRequestMethod("GET");
    • 设置连接超时,读取超时的毫秒数,以及服务器希望得到的一些消息头 conn.setConnectTimeout(6*1000); conn.setReadTimeout(6 * 1000);
    • 调用getInputStream()方法获得服务器返回的输入流,然后输入流进行读取了 InputStream in = conn.getInputStream();
    • 最后调用disconnect()方法将HTTP连接关掉 conn.disconnect();

    PS:除了前面这些,有时候还得顺手判断一下响应码,比如是不是 200:if(conn.getResponseCode() != 200)然后再做相应处理。还有一种情况也很常见:并不需要传什么参数,只是单纯访问一个页面,这时可以直接写:final InputStream in = new URL("url").openStream(); 然后直接去读流就行。 不过,这种写法更适合“直接访问页面”这类场景,原因也不复杂,它底层其实就是 return openConnection().getInputStream()。问题在于,这样一来一些请求头就没法自己设置了。所以这种方式能不能用、该不该用,还是得根据具体场景仔细权衡。

    3.HttpURLConnection使用示例

    这里我们主要针对GET和POST请求写两个不同的使用示例,我们可以conn.getInputStream() 获取到的是一个流,所以我们需要写一个类将流转化为二进制数组!工具类如下:

    StreamTool.ja va:

    /**
     * Created by Jay on 2015/9/7 0007.
     */
    public class StreamTool {
        //从流中读取数据
        public static byte[] read(InputStream inStream) throws Exception{
            ByteArrayOutputStream outStream = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            while((len = inStream.read(buffer)) != -1)
            {
                outStream.write(buffer,0,len);
            }
            inStream.close();
            return outStream.toByteArray();
        }
    }

    接下来就可以开始撸我们的示例了!

    1)HttpURLConnection发送GET请求代码示例

    运行效果图:

    核心部分代码:

    布局:activity_main.xml

    
    
    
    
    
        
    
    

    获取数据类:GetData.ja va:

    /**
     * Created by Jay on 2015/9/7 0007.
     */
    public class GetData {
        // 定义一个获取网络图片数据的方法:
        public static byte[] getImage(String path) throws Exception {
            URL url = new URL(path);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            // 设置连接超时为5秒
            conn.setConnectTimeout(5000);
            // 设置请求类型为Get类型
            conn.setRequestMethod("GET");
            // 判断请求Url是否成功
            if (conn.getResponseCode() != 200) {
                throw new RuntimeException("请求url失败");
            }
            InputStream inStream = conn.getInputStream();
            byte[] bt = StreamTool.read(inStream);
            inStream.close();
            return bt;
        }
    // 获取网页的html源代码
        public static String getHtml(String path) throws Exception {
            URL url = new URL(path);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setConnectTimeout(5000);
            conn.setRequestMethod("GET");
            if (conn.getResponseCode() == 200) {
                InputStream in = conn.getInputStream();
                byte[] data = StreamTool.read(in);
                String html = new String(data, "UTF-8");
                return html;
            }
            return null;
        }
    }

    MainActivity.ja va:

    public class MainActivity extends AppCompatActivity {
    private TextView txtMenu, txtshow;
        private ImageView imgPic;
        private WebView webView;
        private ScrollView scroll;
        private Bitmap bitmap;
        private String detail = "";
        private boolean flag = false;
        private final static String PIC_URL = "https://ww2.sinaimg.cn/large/7a8aed7bgw1evshgr5z3oj20hs0qo0vq.jpg";
        private final static String HTML_URL = "https://www.baidu.com";
    // 用于刷新界面
        private Handler handler = new Handler() {
            public void handleMessage(android.os.Message msg) {
                switch (msg.what) {
                    case 0x001:
                        hideAllWidget();
                        imgPic.setVisibility(View.VISIBLE);
                        imgPic.setImageBitmap(bitmap);
                        Toast.makeText(MainActivity.this, "图片加载完毕", Toast.LENGTH_SHORT).show();
                        break;
                    case 0x002:
                        hideAllWidget();
                        scroll.setVisibility(View.VISIBLE);
                        txtshow.setText(detail);
                        Toast.makeText(MainActivity.this, "HTML代码加载完毕", Toast.LENGTH_SHORT).show();
                        break;
                    case 0x003:
                        hideAllWidget();
                        webView.setVisibility(View.VISIBLE);
                        webView.loadDataWithBaseURL("", detail, "text/html", "UTF-8", "");
                        Toast.makeText(MainActivity.this, "网页加载完毕", Toast.LENGTH_SHORT).show();
                        break;
                    default:
                        break;
                }
            }
    ;
        };
    @Override
        protected void onCreate(Bundle sa vedInstanceState) {
            super.onCreate(sa vedInstanceState);
            setContentView(R.layout.activity_main);
            setViews();
        }
    private void setViews() {
            txtMenu = (TextView) findViewById(R.id.txtMenu);
            txtshow = (TextView) findViewById(R.id.txtshow);
            imgPic = (ImageView) findViewById(R.id.imgPic);
            webView = (WebView) findViewById(R.id.webView);
            scroll = (ScrollView) findViewById(R.id.scroll);
            registerForContextMenu(txtMenu);
        }
    // 定义一个隐藏所有控件的方法:
        private void hideAllWidget() {
            imgPic.setVisibility(View.GONE);
            scroll.setVisibility(View.GONE);
            webView.setVisibility(View.GONE);
        }
    @Override
        // 重写上下文菜单的创建方法
        public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
            MenuInflater inflator = new MenuInflater(this);
            inflator.inflate(R.menu.menus, menu);
            super.onCreateContextMenu(menu, v, menuInfo);
        }
    // 上下文菜单被点击是触发该方法
        @Override
        public boolean onContextItemSelected(MenuItem item) {
            switch (item.getItemId()) {
                case R.id.one:
                    new Thread() {
                        public void run() {
                            try {
                                byte[] data = GetData.getImage(PIC_URL);
                                bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                            handler.sendEmptyMessage(0x001);
                        }
    ;
                    }.start();
                    break;
                case R.id.two:
                    new Thread() {
                        public void run() {
                            try {
                                detail = GetData.getHtml(HTML_URL);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                            handler.sendEmptyMessage(0x002);
                        };
                    }.start();
                    break;
                case R.id.three:
                    if (detail.equals("")) {
                        Toast.makeText(MainActivity.this, "先请求HTML先嘛~", Toast.LENGTH_SHORT).show();
                    } else {
                        handler.sendEmptyMessage(0x003);
                    }
                    break;
            }
            return true;
        }
    }

    最后别忘了加上联网权限:

    注意事项:

    用handler的原因就不用讲了吧~ 另外我们加载html代码的使用的是webView的loadDataWithBaseURL而非LoadData, 如果用LoadData又要去纠结中文乱码的问题,so…用loadDataWithBaseURL就可以不用纠结那么多了 另外有些页面可能需要我们提交一些参数,比如账号密码:我们只需把对应参数拼接到url尾部即可,比如: http://192.168.191.1:8080/ComentServer/LoginServlet?passwd=123&name=Jack 然后服务端getParamater("passwd")这样就可以获得相应的参数了,我们请求时这些东西都会看得清清楚楚 ,所以说GET方式并不安全!另外还有一点要注意的就是Android从4.0开始就不允许在非UI线程中进行UI操作!

    2)HttpURLConnection发送POST请求代码示例

    有GET自然有POST,我们通过openConnection获取到的HttpURLConnection默认是进行Get请求的, 所以我们使用POST提交数据,应提前设置好相关的参数:conn.setRequestMethod("POST"); 还有:conn.setDoOutput(true);conn.setDoInput(true);设置允许输入,输出 还有:conn.setUseCaches(false); POST方法不能缓存,要手动设置为false, 具体实现看代码:

    运行效果图:

    核心代码:

    PostUtils.ja va

    public class PostUtils {
        public static String LOGIN_URL = "http://172.16.2.54:8080/HttpTest/ServletForPost";
        public static String LoginByPost(String number,String passwd)
        {
            String msg = "";
            try{
                HttpURLConnection conn = (HttpURLConnection) new URL(LOGIN_URL).openConnection();
                //设置请求方式,请求超时信息
                conn.setRequestMethod("POST");
                conn.setReadTimeout(5000);
                conn.setConnectTimeout(5000);
                //设置运行输入,输出:
                conn.setDoOutput(true);
                conn.setDoInput(true);
                //Post方式不能缓存,需手动设置为false
                conn.setUseCaches(false);
                //我们请求的数据:
                String data = "passwd="+ URLEncoder.encode(passwd, "UTF-8")+
                        "&number="+ URLEncoder.encode(number, "UTF-8");
                //这里可以写一些请求头的东东...
                //获取输出流
                OutputStream out = conn.getOutputStream();
                out.write(data.getBytes());
                out.flush();
                 if (conn.getResponseCode() == 200) {  
                        // 获取响应的输入流对象  
                        InputStream is = conn.getInputStream();  
                        // 创建字节输出流对象  
                        ByteArrayOutputStream message = new ByteArrayOutputStream();  
                        // 定义读取的长度  
                        int len = 0;  
                        // 定义缓冲区  
                        byte buffer[] = new byte[1024];  
                        // 按照缓冲区的大小,循环读取  
                        while ((len = is.read(buffer)) != -1) {  
                            // 根据读取的长度写入到os对象中  
                            message.write(buffer, 0, len);  
                        }  
                        // 释放资源  
                        is.close();  
                        message.close();  
                        // 返回字符串  
                        msg = new String(message.toByteArray());  
                        return msg;
                 }
            }catch(Exception e){e.printStackTrace();}
            return msg;
        }
    }

    PS:因为电脑没装MyEclipse,而且时间关系,就不另外写demo了,用回之前的Eclipse的那个demo! 其实从直接看核心代码就够了~ 代码下载:HttpURLConnection例子.zip

    4.Cookie问题的处理

    说这个之前,首先我们要理解两个概念:Session和Cookie Cookie只是Session机制的一种常用形式,我们也可以使用其他方式来作为客户端的一个唯一标识, 这个由服务器决定,唯一能够证明一个客户端标识就好!除了这种方式外,我们还可以使用URL重写! 方法来实现!所以以后别傻傻的跟别人说:Session不就是Cookie!

    下面通过一个例子来帮助大家理解这个Cookie: 小猪输入账号密码后登陆下学校的教务系统,然后访问课表信息成功, 然后如果你用的是Chrome,按F12进入开发模式:来到Resources界面可以看到我们的Cookies:

    点击后我们可以看到里面保存的内容,由名称;值;cookie所在的域(domain); cookie所在的目录(path)Asp.net默认为/即根目录;过期时间;Cookie大小:

    我们可以看到请求头中有一个Cookie的字段:

    恩呢,现在我们把Cookie清掉(或者等几分钟),然后再访问下述链接:

    这时候,页面竟然自动跳回登陆页面了!当然一些其他的网站可能会弹出一个对话框说 "登陆超时"之类的东西!

    小结下Http请求登陆的一个简单流程: 一般是登陆的时候:服务器通过Set-Cookie响应头,返回一个Cookie,浏览器默认保存这个Cookie, 后续访问相关页面的时候会带上这个Cookie,通过Cookie请求头来完成访问,如果没Cookie或者 Cookie过期,就提示用户没登陆,登陆超时,访问需要登陆之类的信息!

    而我们使用HttpClient和HttpURLConnection其实也就是模拟这一个流程,登陆后拿到cookie 拿着它去发送请求: 关键代码如下: 获得Cookie:conn.getHeaderField("Set-Cookie"); 请求时带上Cookie:conn.setRequestProperty("Cookie",cookie);

    另外,除了这种设置请求头的方式外,还可以用另一种折衷的方法:URL重写: 就是在原先请求链接的基础上,加上一个…&sessionid=xxxxx这样的参数,然后由服务器来解析 判断!Get可以这么写,而Post写法如下:

    这里我们用的是JSON字符串的形式,接到请求时服务端取出session里的内容,然后做下查询即可~

    5.使用HttpURLConnection发送PUT请求

    很多人对Put请求其实不算熟,毕竟日常开发里最常打交道的还是GET和POST。刚开始接触时,这块也容易让人有点发懵,不过后面就会发现,它和POST在用法上其实挺接近,很多时候只需要在POST的基础上做一点调整就能直接用起来。与此同时,HttpClient本身也提供了一个HttpPut的API,下面放一段项目里实际写过的请求代码:

    public static String LoginByPut(Context mContext, String mobile, String password, int from, 
              String devid,String version_name, int remember_me) {
        String resp = "";
        try {
            HttpURLConnection conn = (HttpURLConnection) new URL(LOGIN_URL).openConnection();
            conn.setRequestMethod("PUT");
            conn.setReadTimeout(5000);
            conn.setConnectTimeout(5000);
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setUseCaches(false);
    String data = "mobile=" + mobile + "&password=" + password + "&from=" + from + "&devid=" + "devid"
                    + "&version_name=" + "version_name" + "&remember_me=" + remember_me;
            ;
            // 获取输出流:
            OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());
            writer.write(data);
            writer.flush();
            writer.close();
    // 获取相应流对象:
            InputStream in = conn.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            StringBuilder response = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null)
                response.append(line);
            SPUtils.put(mContext, "session", conn.getHeaderField("Set-Cookie"));
            // 资源释放:
            in.close();
            // 返回字符串
            Log.e("HEHE", response.toString());
            return response.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    本节小结:

    好的,本节关于HttpUrlConnection的使用介绍就到这里,另外,HTTP这一小节大部分来自于小猪 以前写的一个小合集Android之Http通信,如果看过这个系列的可以跳过这节,大部分内容都是 一样的!嗯,就说这么多,谢谢~

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    系统应用 Android
    相关文章 更多
    精品专题 更多
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    macOS软件

    正软商城macOS软件专区,精选适用于Mac电脑的办公、设计、影音、效率、开发和系统工具,提供软件功能介绍、macOS兼容版本、正版授权及购买下载服务。

    IOS软件

    正软商城iOS软件专区,精选适用于iPhone和iPad的办公、学习、影音、设计、效率及AI应用,提供功能介绍、适用设备、系统要求和正版获取方式等信息。

    AI

    正软商城AI软件专区,汇集AI写作、AI绘画、AI视频、AI办公、AI编程、AI翻译、智能客服和数据分析等人工智能工具,提供功能介绍、适用平台、收费方式及正版购买信息。

    Mac软件 更多
    Aperty macOS版
    Aperty macOS版

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    火山引擎 网页版
    火山引擎 网页版

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    立刻MV 网页版
    立刻MV 网页版

    立刻MV 面向音乐人、内容创作者和品牌团队,帮助用户低成本完成歌曲 MV、歌词视频、AI 分镜、图生视频与最终合成。

    蛙蛙写作 网页版
    蛙蛙写作 网页版

    蛙蛙写作 AI 创作工具,覆盖小说、剧本、文案,一键生成文稿,打通文字转视频全流程,高效解决创作难题。

    讯飞智作 网页版
    讯飞智作 网页版

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    超级简历WonderCV 网页版
    超级简历WonderCV 网页版

    超级简历WonderCV是面向应届生和AI小白的智能求职平台,覆盖简历、面试与职业规划。

    音述AI 网页版
    音述AI 网页版

    音述AI,是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区。

    AionClaw macOS版
    AionClaw macOS版

    AionClaw 是可在桌面端运行的任务型 AI 助手,通过数字专家与技能市场组合办公、创作、数据和开发能力。

    Loomy macOS版
    Loomy macOS版

    Loomy 是科大讯飞推出的桌面 AI 助手,可通过对话、任务与工作目录协助处理办公、内容创作和资料整理。

    AirBuddy 3 macOS版
    AirBuddy 3 macOS版

    AirBuddy 3 是面向 macOS 的蓝牙外设增强工具,可集中查看 AirPods、Beats 与苹果设备电量,提供快速连接、播放控制、电量提醒、桌面小组件和多台 Mac 外设接力等功能。

    AirServer macOS版
    AirServer macOS版

    AirServer macOS版可把 Mac 转换为无线投屏接收端,通过 AirPlay 或 Google Cast 接收手机、平板和电脑画面,并支持多设备同时连接、高清镜像及会话录制,适合家庭娱乐、课堂教学、会议演示和应用展示。

    AnyDesk macOS版
    AnyDesk macOS版

    AnyDesk macOS版是一款适用于远程办公、设备维护和客户支持的远程桌面工具,可连接并操作异地计算机,支持文件传输、无人值守访问、会话权限控制及跨平台协作。

    WINDOWS 更多
    讯飞绘文 网页版
    讯飞绘文 网页版

    讯飞绘文网页版是科大讯飞推出的AI图文创作与内容运营工具,覆盖热点选题、文章生成、稿件校对、智能配图、排版发布和数据复盘等环节,适合自媒体创作者及内容团队在线使用。

    Maya(Autodesk Maya) Windows版
    Maya(Autodesk Maya) Windows版

    Autodesk Maya 是面向影视、电视、动画和游戏行业的专业三维制作软件,集多边形与 NURBS 建模、角色绑定、关键帧和动作捕捉动画、Bifrost 特效模拟、材质开发及 Arnold 渲染于一体,

    Aperty Windows版
    Aperty Windows版

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    火山引擎 网页版
    火山引擎 网页版

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    立刻MV 网页版
    立刻MV 网页版

    立刻MV 面向音乐人、内容创作者和品牌团队,帮助用户低成本完成歌曲 MV、歌词视频、AI 分镜、图生视频与最终合成。

    蛙蛙写作 网页版
    蛙蛙写作 网页版

    蛙蛙写作 AI 创作工具,覆盖小说、剧本、文案,一键生成文稿,打通文字转视频全流程,高效解决创作难题。

    讯飞智作 网页版
    讯飞智作 网页版

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    超级简历WonderCV 网页版
    超级简历WonderCV 网页版

    超级简历WonderCV是面向应届生和AI小白的智能求职平台,覆盖简历、面试与职业规划。

    音述AI 网页版
    音述AI 网页版

    音述AI,是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区。

    AionClaw Windows版
    AionClaw Windows版

    AionClaw 是可在桌面端运行的任务型 AI 助手,通过数字专家与技能市场组合办公、创作、数据和开发能力。

    Loomy Windows版
    Loomy Windows版

    Loomy 是科大讯飞推出的桌面 AI 助手,可通过对话、任务与工作目录协助处理办公、内容创作和资料整理。

    AirServer Windows版
    AirServer Windows版

    AirServer Windows版可把电脑变成AirPlay、Google Cast和Miracast无线投屏接收端,适合会议演示、课堂教学及家庭大屏分享。发送设备通常无需另装客户端,并可同时接收和智能排列多个镜像会话。

    即将离开本站
    您即将前往第三方网站,请确认是否继续?