Android中的HTTP通信笔记(慕课网)

Android中的HTTP通信笔记(慕课网)

本文是基于慕课网nate老师讲解Android中Http通信,自己做的整理笔记,在此感谢nate老师和慕课网的分享,视频链接如下http://www.imooc.com/learn/304


HTTP协议

HTTP协议是超文本传输协议定义了浏览器怎么向万维网请求万维网文档,及服务器怎么把文档传送给浏览器。从层次的角度看,HTTP协议是面向应用层的协议。

HTTP协议特点

HTTP协议特点包括以下几个方面:

  • 支持客户机服务器模式

  • 简单快速:客户机向服务器请求服务时,只需要传送请求方法和路径。请求的方法包括GET、HEAD、POST等。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的规模小,通信速度快。

  • 灵活:HTTP运行传输任何类型的数据对象。

  • 无连接:限制每次连接只处理一个请求。服务器处理完用户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。

  • 无状态:HTTP协议是无状态协议。无状态是指协议对于事务的处理没有记忆的能力。缺少状态意味着如果后续处理需要前面的信息,则必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。


一个HTTP协议操作成为一个事务,其工作过程可以分为四步:

  1. 首先客户机和服务器之间建立相应的连接,只要单击某个超链接,HTTP就可以工作。

  2. 建立连接之后,客户机发送一个请求给服务器,请求方式的格式为:统一资源标识符(URL)、协议版本号,后边的MIME信息包括请求标识符、客户机信息和可能的内容。

  3. 服务器接收到请求后 ,给予相应的相应信息。其格式为一个状态行,包括信息的协议版本号、一个成功或错误的代码,后边是MIME信息包括服务器信息、实体信息和可能的内容。

  4. 客户端接收服务器所返回的信息通过浏览器显示在用户的现实屏上,然后客户机与服务器断开连接。


统一资源定位符(URL)

统一资源定位符(URL)也被称为网页地址。

URL的格式由三部分组成:

第一部分是协议;

第二部分是存有该资源的主机IP地址(有时也包括端口号);

第三部分是主机资源的具体地址。

eg.http//www.imooc.com/index.jsp

TCP三次握手

SYN是TCP/IP建立连接时使用的握手信号。客户机和服务器之间建立连接,首先客户机发出一个SYN信号,服务器使用SYN+ACK应答表示接收到了这个消息,最后客户机再以ACK消息响应。

ACK即确认符,在数据通信中,接收站给发送站的一种传输类控制字符,表示发来的数据已确认接收无误。

HTTP请求

Http请求由三部分组成,分别是:请求行、消息报头、请求正文。

请求行以一个方法符号开头,以空格分开,后面跟着请求的URI和协议的版本号,格式如下:Method Request-URI HTTP-Version CRLF

其中Method表示请求的方法;Request-URI是一个统一资源标识符;HTTP-Version标识请求的HTTP协议版本;CRLF表示回车和换行(除了作为结尾的CRLF之外,不允许出现单独的CR或LF字符)。

请求方法(所有方法全为大写)有多种,各个方法解释如下:

GET 请求获取Request-URI所标识的资源

POST 在Request-URI所标识的资源后附加新的数据

HEAD 请求获取由Request-URI所标识的资源的响应消息报头

PUT 请求服务器存储一个资源,并用Request-URI作为其标识

DELETE 请求服务器删除Request-URI所标识的资源

TRACE 请求服务器回送收到的请求信息,主要用于测试或诊断

CONNECT 保留将来使用

OPTIONS 请求查询服务器的性能,或者查询与资源相关的选项和需求

应用举例:

GET方法:在浏览器的地址栏输入网址的方式访问网页时,浏览器采用GET方法向服务器获取资源,eg:GET/form.html HTTP/1.1(CRLF)

POST方法:要求被请求服务器接受负载请求后面的数据,常用于提交表单。

HTTP响应

在接收和解释请求消息后,服务器返回一个HTTP响应消息。

HTTP响应也是由三个部分组成,分别是:状态行、消息报头、响应正文。

状态行格式如下:

HTTP-Version Status——Code Reason-Phrase CRLF

其中,HTTP-Version标识服务器HTTP协议的版本;Status-Code标识服务器发回的响应状态代码;Reason-Phrase表示状态代码的文本描述。

状态代码有三位数字组成,第一个数字定义了响应的类别,且有五种可能取值:
1xx:指示信息–表示请求已接收,继续处理
2xx:成功–表示请求已被成功接收、理解、接受
3xx:重定向–要完成请求必须进行更进一步的操作
4xx:客户端错误–请求有语法错误或请求无法实现
5xx:服务器端错误–服务器未能实现合法的请求

常见状态代码、状态描述、说明:
200 OK //客户端请求成功
400 Bad Request //客户端请求有语法错误,不能被服务器所理解
401 Unauthorized //请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用
403 Forbidden //服务器收到请求,但是拒绝提供服务
404 Not Found //请求资源不存在,eg:输入了错误的URL
500 Internal Server Error //服务器发生不可预期的错误
503 Server Unavailable //服务器当前不能处理客户端的请求,一段时间后可能恢复正常
eg:HTTP/1.1 200 OK (CRLF)

HTTP1.0和HTTP1.1区别

HTTP/1.0 每次请求都需要建立新的TCP连接,连接不可复用。
HTTP/1.1 新的请求可以在上次请求建立的TCP连接之上发送,连接可以复用,优点是减少重复进行TCP三次握手的开销,提高效率。
HTTP/1.1 在Request消息头里多了一个HOST域,HTTP1.0则没有这个域。HOST:www.w3.org
HTTP1.1 增加了OPTIONS,PUT,DELETE,TRACE,CONNECT这些Request方法。

HttpURLConnection

在Android中发送HTTP请求的方式一般有两种,HttpURLConnection和HttpClient(Android 5.0中已弃用)在这里我们只介绍HttpURLConnection.

从网上下载图片保存到SD中

  1. 代码

HttpThread.java

package com.excavator.http_01;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;
import android.os.Handler;
import android.webkit.WebView;
import android.widget.ImageView;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;


/**
 * Created by admin on 2015/4/16.
 */
public class HttpThread extends Thread {
    private String url;

    private WebView webView;

    private Handler handler;

    private ImageView imageView;

    public HttpThread(String url, WebView webView, Handler handler) {
        this.url = url;
        this.webView = webView;
        this.handler = handler;
    }

    public HttpThread(String url, ImageView imageView,Handler handler) {
        this.url = url;
        this.handler = handler;
        this.imageView = imageView;
    }

    @Override
    public void run() {
        try {
            URL httpUrl = new URL(url);
            try {
                //从Url建立Http连接
                HttpURLConnection connection = (HttpURLConnection) httpUrl.openConnection();
                connection.setReadTimeout(5000);
                connection.setRequestMethod("GET");
                connection.setDoInput(true);
                //从Http连接获取输入流
                InputStream in = connection.getInputStream();
                FileOutputStream outputStream=null;
                File downloadFile=null;
                String fileName = String.valueOf(System.currentTimeMillis());
                //判断外部SD卡是否存在
                if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
                    File parent = Environment.getExternalStorageDirectory();    //获取SD卡根目录
                    downloadFile=new File(parent,fileName);                     //在SD卡根目录下新建downloadFile
                    outputStream0.000000000000000000 = new FileOutputStream(downloadFile);          //构建写字节到downloadFile的输出流
                }
                //建立缓冲数组
                byte[] b = new byte[2*1024];
                int len;
                if (outputStream!=null){
                    while ((len=in.read(b))!=-1){   //读输入流中的字符缓冲到字节数组b中
                        outputStream.write(b,0,len);//写字节数组b中的字符到输出流中(即到文件downloadFile中)
                    }
                }
                //解码文件路径为位图bitmap
                final Bitmap bitmap = BitmapFactory.decodeFile(downloadFile.getAbsolutePath());
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        imageView.setImageBitmap(bitmap);
                    }
                });
                /*final StringBuffer stringBuffer = new StringBuffer();
                BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                String str;
                while ((str=reader.readLine())!=null) {
                    stringBuffer.append(str);
                }


                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        webView.loadData(stringBuffer.toString(), "text/html;charset=utf-8", null);
                    }
                });*/
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
    }
}

MainActivity.java

package com.excavator.http_01;

import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.ActionBarActivity;
import android.webkit.WebView;
import android.widget.ImageView;


public class MainActivity extends ActionBarActivity {

    private WebView webView;

    private Handler handler=new Handler();

    private ImageView imageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //webView = (WebView) findViewById(R.id.webView);
        imageView = (ImageView) findViewById(R.id.imageView);
        new HttpThread("http://h.hiphotos.baidu.com/image/pic/item/6c224f4a20a446239e8d311c9b22720e0cf3d70d.jpg",imageView,handler).start();
    }
}

GET、POST传递参数

主机服务器代码
MyServlet.java

package com.imooc.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class MyServlet
 */
@WebServlet("/MyServlet")
public class MyServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#HttpServlet()
     */
    public MyServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        this.doPost(request, response);
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        String name=request.getParameter("name");
        String age=request.getParameter("age");
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out=response.getWriter();
        //out.println("name="+new String(name.getBytes("iso-8859-1"),"utf-8")+"age="+age);
        out.println("name="+name+"age="+age);
        //System.out.println("name="+new String(name.getBytes("iso-8859-1"),"utf-8"));
        System.out.println("name="+name);
        System.out.println("age="+age);
    }

}

HttpThread1(从Android端向服务器端提交数据)

package com.excavator.http_01;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Properties;

/**
 * Created by admin on 2015/4/17.
 */
public class HttpThread1 extends Thread {

    String url;

    String name;

    String age;

    public HttpThread1(String url, String name, String age) {
        this.url = url;
        this.name = name;
        this.age = age;
    }

    private  void doGet() {
        try {
            url = url + "?name=" + URLEncoder.encode(name,"utf-8") + "&age=" + age; //此处URLEncoder中的encode方法用于转码,因为Android中编码是utf-8码,若不转码,服务器端接收到中文会是乱码。
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        try {
            URL httpUrl = new URL(url);
            try {
                HttpURLConnection httpURLConnection = (HttpURLConnection) httpUrl.openConnection();
                httpURLConnection.setRequestMethod("GET");
                httpURLConnection.setReadTimeout(5000);
                BufferedReader reader = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream()));
                String str;
                StringBuffer stringBuffer = new StringBuffer();
                while ((str = reader.readLine()) != null) {
                    stringBuffer.append(str);
                }
                System.out.println("result" + stringBuffer.toString());
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
    }

    private void doPost() {
        try {
            Properties properties = System.getProperties();
            properties.list(System.out);


            URL httpUrl = new URL(url);
            try {
                HttpURLConnection httpURLConnection = (HttpURLConnection) httpUrl.openConnection();
                httpURLConnection.setRequestMethod("POST");
                httpURLConnection.setReadTimeout(5000);
                OutputStream out = httpURLConnection.getOutputStream();
                String content = "name=" + name + "&age=" + age;
                out.write(content.getBytes());
                BufferedReader reader = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream()));
                StringBuffer sb = new StringBuffer();
                String str;

                while ((str = reader.readLine()) != null) {
                    sb.append(str);
                }
                System.out.println(sb.toString());

            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        super.run();
        doGet();
//        doPost();
    }

}

这里写图片描述
这里写图片描述

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android Framework核心知识笔记是一本介绍Android Framework核心知识的pdf文档。Android Framework是Android系统的基础,它包含了一系列的类库和API,为开发Android应用程序提供了基本的功能和特性。 这本笔记首先介绍了Android Framework的概述,包括其组成部分和架构。然后详细讲解了Android四大组件(Activity、Service、Broadcast Receiver和Content Provider)的实现原理和使用方法。这些组件是Android应用程序的基本构建模块,理解它们的工作原理对于开发高质量的Android应用程序至关重要。 接着,笔记Android Framework的UI设计进行了深入讲解。它介绍了View和ViewGroup的层次结构以及布局管理器的使用方法,帮助开发者实现灵活且具有吸引力的用户界面。此外,它还讨论了Android的绘图机制和动画效果,使开发者能够创建更加生动和吸引人的界面。 另外,笔记还包含了关于Android Framework的数据存储和访问的内容。它介绍了SharedPreferences、SQLite数据库以及Content Provider等数据持久化的方法,帮助开发者存储和管理应用程序的数据。 此外,笔记还涵盖了与Android Framework相关的其他主题,如网络通信、多媒体处理、传感器和位置服务等。它们帮助开发者实现更多样化和功能强大的应用程序。 总结来说,Android Framework核心知识笔记是一本全面介绍Android Framework的教程,帮助开发者掌握Android应用程序开发的基本技能。对于想要成为Android开发专家的人来说,这是一本不可或缺的参考资料。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值