使用HttpURIConnection和OkHttp访问网络

作者: 亚欧沙龙 | 来源:发表于2018-02-25 17:32 被阅读24次

    NetworkTest

    看精彩的世界——————使用网络技术

    使用HttpURIConnection访问网络

     private void sendRequestWithHttpURIConnection() {
    //        开启线程发起网络请求
        new Thread(new Runnable() {
            @Override
            public void run() {
                HttpURLConnection connection = null;
                BufferedReader reader = null;
                try{
    
                    URL url = new URL("http://www.baidu.com");
                    connection = (HttpURLConnection) url.openConnection();
    
            //GET表示希望从服务器哪里获取数据
                    connection.setRequestMethod("GET");
    
            //设置连接超时,读取超时的毫秒数
                    connection.setConnectTimeout(8000);
                    connection.setReadTimeout(8000);
    
            //调用getInputStream()方法就可以得到服务器返回的输入流了
                    InputStream in = connection.getInputStream();
    //                    下面对获取到的输入流进行读取
                    reader = new BufferedReader(new InputStreamReader(in));
                    StringBuilder response = new StringBuilder();
            //下面是设置行的个数,以便显示所有数据
                    String line;
                    while ((line = reader.readLine()) != null){
                        response.append(line);
                    }
                    showResponse(response.toString());
                }catch (Exception e){
                    e.printStackTrace();
                }finally {
                    if (reader != null){
                        try{
                            reader.close();
                        }catch (IOException e){
                            e.printStackTrace();
                        }
                    }
                    if (connection != null){
                        connection.disconnect();
                    }
                }
            }
        }).start();
    }</pre>
    

    使用OkHttp 访问网络

    • 先在安装的Apache服务器的C:/Apache/htdocs目录下新建一个get_data.xml文件,文件内容:
        <apps>
            <app>
                <id>1</id>
                <name>Google Maps</name>
                <version>1.0</version&gt
            </app>
    
            <app>
            <id>2</id>
            <name>Chrome</name>
            <version>2.1</version>
            </app>
    
            <app
            <id>3</id>
            <name>Google Play</name>
            <version>2.3</version>
            </app>
        </apps>
    
    • 接下来就是访问的主题代码:
        private void sendRequestWithOkhttp() {
                new Thread(new Runnable() {
                @Override
                public void run() {
                    try{
                        OkHttpClient client = new OkHttpClient();
                        Request request = new Request.Builder()
    //                            访问地址为baidu的地址
    //                            .url("http://www.baidu.com")
    //                            指定访问的服务器地址是电脑本机
                                .url("http://10.0.0.2/get_data.xml")
                                .build();
                        Response response = client.newCall(request).execute();
                        String responseData = response.body().string();
    
    //                    showResponse(responseData);
    
    //                    Pull的解析方式
    //                    parseXMLWithPull(responseData);
    //
    //                    SAX的解析方式
                        parseXMLWithSAX(responseData);
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }
            }).start();
        }</pre>
    

    解析XML格式的数据

    • Pull的解析方式
    • SAX的解析方式

    * Pull的解析方式

     private void parseXMLWithPull(String xmlData) {
            try{
                XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
                XmlPullParser xmlPullParser = factory.newPullParser();
                xmlPullParser.setInput(new StringReader(xmlData));
                int eventType = xmlPullParser.getEventType();
                String id = "";
                String name = "";
                String version = "";
                while (eventType == xmlPullParser.END_DOCUMENT){
                    String nodeName = xmlPullParser.getName();
                    switch(eventType){
    //                    开始解析摸个节点
                        case XmlPullParser.START_TAG:{
                            if ("id".equals(nodeName)){
                                id = xmlPullParser.nextText();
                            }else if ("name".equals(nodeName)){
                                name = xmlPullParser.nextText();
                            }else if ("version".equals(nodeName)){
                                version = xmlPullParser.nextText();
                            }
                            break;
                        }
    //                    完成解析某个节点
                        case XmlPullParser.END_TAG:{
                            if ("app".equals(nodeName)){
                                Log.d("MainActivity","id id " + id);
                                Log.d("MainActivity","name is " + name);
                                Log.d("MainActivity","version is " + version);
                            }
                            break;
                        }
                        default:
                            break;
                    }
                    eventType = xmlPullParser.next();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    </pre>
    

    SAX的解析方式

    首先需要建立一个类继承DefaulyHander,并重写父类的5个方法

    public class ContentHander extends DefaultHandler{
    
    }
    
    public void startDocument() throws SAXException {
    
    }
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
    
    }
    
    public void characters(char[] ch, int start, int length) throws SAXException {
    
    }
    
    public void endElement(String uri, String localName, String qName) throws SAXException {
    
    }
    
    public void endDocument() throws SAXException {
    
    }
    

    再在MainActivity里面做如下修改:

    private void parseXMLWithSAX(String xmlData) {
    
            try{
                SAXParserFactory factory = SAXParserFactory.newInstance();
                XMLReader xmlReader = factory.newSAXParser().getXMLReader();
                ContentHander hander = new ContentHander();
    //            将ContentHander的实例设置到XMLReader中
                xmlReader.setContentHandler(hander);
    //            开始执行解析
                xmlReader.parse(new InputSource(new StringReader(xmlData)));
            }catch (Exception e){
                e.printStackTrace();
            }
        }</pre>
    

    解析JSON格式的数据

    • 使用JSONObject
    • 使用GSON

    使用JSONObject

    • 先在安装的Apache服务器的C:/Apache/htdocs目录下新建一个get_data.json文件,文件内容:
    [{"id":"5","version":"5.5","name":"Clash of Clans"},
    {"id":"6","version":"7.0","name":"Boom Beach"},
    {"id":"7","version":"3.5","name":"Clash Royale"}]</pre>
    

    下面是具体的JSONObject解析方式

        ////         JSONObject的解析方式
        private void parseJSONObject(String jsonData) {
            try{
                JSONArray jsonArray = new JSONArray(jsonData);
                for (int i = 0; i < jsonArray.length(); i++) {
                    JSONObject jsonObject = jsonArray.getJSONObject(i);
                    String id = jsonObject.getString("id");
                    String name = jsonObject.getString("name");
                    String version = jsonObject.getString("version");
                    Log.d("MainActivity","id id " + id);
                    Log.d("MainActivity","name is" + name);
                    Log.d("MainActivity","version is " + version);
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }</pre>
    

    下面是具体的GSON解析方式

    • 首先新建一个AppK类,加入id,name,version这几个字段,并写入getter,setter方法

    接着就是解析的方法了:

    private void parseJSONWithGSON(String jsonData) {
            Gson gson = new Gson();
            List<App> appList = gson.fromJson(jsonData, new TypeToken<List<App>>()
            {}.getType());
            for (App app : appList){
                Log.d("MainActivity","id is " + app.getId());
                Log.d("MainActivity","name is " + app.getName());
                Log.d("MainActivity","version is " + app.getVersion());
            }
        }</pre>
    

    当然,以上的方法是有问题的,如果我们每次都去编写一变发送HTTP请求的代码,这显然是费劲的,我们可以把这些通用的网络操作提到一个公共类中,但是不能每次都调用都写一个线程,因为方法会在服务器还没来得及响应的时候就执行结束了,因此我们

    需要先定义一个接口

    public interface HttpCallbackListener{
        void onFinish(String response);
    
        void onError(Exception e);
    }</pre>
    

    j接着写HttpUtil类中的添加方法:

    public static void sendHttpRequest(final String address,final HttpCallbackListener listener){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    HttpURLConnection connection = null;
                    try{
                        URL url = new URL(address);
                        connection = (HttpURLConnection) url.openConnection();
                        connection.setRequestMethod("GET");
                        connection.setConnectTimeout(8000);
                        connection.setReadTimeout(8000);
                        connection.setDoInput(true);
                        connection.setDoOutput(true);
                        InputStream in = connection.getInputStream();
                        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
                        StringBuilder respond = new StringBuilder();
                        String line;
                        while ((line = reader.readLine()) != null){
                            respond.append(line);
                        }
                        if (listener != null){
    //                        调回onFinish()方法
                            listener.onFinish(respond.toString());
                        }
                    }catch (Exception e){
                        if (listener != null){
    //                        回调onError()方法
                            listener.onFinish(e);
                        }
                    }finally {
                        if (connection != null){
                            connection.disconnect();
                        }
                    }
                }
            }).start();
        }</pre>
    

    HttpUtilConnection的写法总体上来说比较复杂,那么使用OkHttp会变简单吗,答案是肯定的

    public static void sendOkHttpRequest(String address,okhttp3.Callback callback){
            OkHttpClient client = new OkHttpClient();
            Request request = new Request.Builder()
                    .url(address)
                    .build();
            client.newCall(request).enqueue(callback);
        }</pre>
    

    相关文章

      网友评论

        本文标题:使用HttpURIConnection和OkHttp访问网络

        本文链接:https://www.haomeiwen.com/subject/hlirxftx.html