day17 HTTP协议、get与post请求

HTTP协议

HTTP协议(Hyper Text Transfer Protocol,超文本传输协议),是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。HTTP基于客户端/服务端(C/S)架构模型,通过一个可靠的链接来交换信息,是一个无状态的请求/响应协议。它是互联网上应用最为广泛的一种网络协议。HTTP是一种应用层协议,它是基于TCP/IP协议之上的请求/响应式的协议,即一个客户端与服务器建立连接后,向服务器发送一个请求;服务器接到请求后,给予相应的响应信息。

请求协议和响应协议
HTTP请求由请求行、请求头、请求体三部分组成:

1.请求行:包括请求方式Method、资源路径URL、协议版本Version;
①是请求方法,GET和POST是最常见的HTTP方法,除此以外还包括DELETE、HEAD、OPTIONS、PUT、TRACE。
②为请求对应的URL地址,它和报文头的Host属性组成完整的请求URL。
③是协议名称及版本号。

2.请求头:包括一些访问的域名、用户代理、Cookie等信息;
④是HTTP的报文头,报文头包含若干个属性,格式为“属性名:属性值”,服务端据此获取客户端的信息。与缓存相关的规则信息,均包含在header中
首部字段名有如下:
Accept 指定客户端能够接收的内容格式类型
Accept-Language 指定客户端能够接受的语言类型
Accept-Ecoding 指定客户端能够接受的编码类型
User-Agent 用户代理,向服务器说明自己的操作系统、浏览器等信息
Connection 是否开启持久连接(keepalive)
Host 服务器域名

3.请求体:就是HTTP请求的数据。

get请求无请求体
HTTP响应由三部分组成:响应行、响应头、响应体

1.响应行:
①报文协议及版本;
②状态码及状态描述;

2.响应头:
③响应报文头,也是由多个属性组成;

首部字段名如下:
Server 服务器软件名,Apache/Nginx
Date 服务器发出响应报文的时间
Last-Modified 请求资源的最后的修改时间

3.响应体:
④响应报文体,即我们真正要的“干货”

响应状态码

HTTP的响应状态码由5段组成:
1xx 消息,一般是告诉客户端,请求已经收到了,正在处理,别急…
2xx 处理成功,一般表示:请求收悉、我明白你要的、请求已受理、已经处理完成等信息.
3xx 重定向到其它地方。它让客户端再发起一个请求以完成整个处理。
4xx 处理发生错误,责任在客户端,如客户端的请求一个不存在的资源,客户端未被授权,禁止访问等。
5xx 处理发生错误,责任在服务端,如服务端抛出异常,路由出错,HTTP版本不支持等。

常见状态码及含义:

200—OK/请求已经正常处理完毕
301—/请求永久重定向
302—/请求临时重定向
304—/请求被重定向到客户端本地缓存
400—/客户端请求存在语法错误
401—/客户端请求没有经过授权
403—/客户端的请求被服务器拒绝,一般为客户端没有访问权限
404—/客户端请求的URL在服务端不存在
500—/服务端永久错误
503—/服务端发生临时错误

HTTP协议版本更替

HTTP/0.9
HTTP协议的最初版本,功能简陋,仅支持请求方式GET,并且仅能请求访问HTML格式的资源。

HTTP/1.0
在0.9版本上做了进步,增加了请求方式POST和HEAD;不再局限于0.9版本的HTML格式,根据Content-Type可以支持多种数据格式,即MIME多用途互联网邮件扩展,例如text/html、image/jpeg等;同时也开始支持cache,就是当客户端在规定时间内访问统一网站,直接访问cache即可。
但是1.0版本的工作方式是每次TCP连接只能发送一个请求,当服务器响应后就会关闭这次连接,下一个请求需要再次建立TCP连接,就是不支持keepalive。

HTTP/1.1
解决了1.0版本的keepalive问题,1.1版本加入了持久连接,一个TCP连接可以允许多个HTTP请求; 加入了管道机制,一个TCP连接同时允许多个请求同时发送,增加了并发性;新增了请求方式PUT、PATCH、DELETE等。
但是还存在一些问题,服务端是按队列顺序处理请求的,假如一个请求处理时间很长,则会导致后边的请求无法处理,这样就造成了队头阻塞的问题;同时HTTP是无状态的连接,因此每次请求都需要添加重复的字段,降低了带宽的利用率。

HTTP/2.0
为了解决1.1版本利用率不高的问题,提出了HTTP/2.0版本。增加双工模式,即不仅客户端能够同时发送多个请求,服务端也能同时处理多个请求,解决了队头堵塞的问题;HTTP请求和响应中,状态行和请求/响应头都是些信息字段,并没有真正的数据,因此在2.0版本中将所有的信息字段建立一张表,为表中的每个字段建立索引,客户端和服务端共同使用这个表,他们之间就以索引号来表示信息字段,这样就避免了1.0旧版本的重复繁琐的字段,并以压缩的方式传输,提高利用率。
另外也增加服务器推送的功能,即不经请求服务端主动向客户端发送数据。
当前主流的协议版本还是HTTP/1.1版本。

重点

1.get请求和post请求的区别
get请求直接将请求参数暴露在url,不安全+一般用于向服务器请求数据
post请求将请求参数放在请求体里面,安全的+一般用于向服务器提交数据

2.网络七层
应用层:应用程序,用户看的见 http协议
表示层:将人看的懂的转成计算机看的懂
会话层:发起一个连接
传输层:规定传输协议和端口号 tcp协议 udp协议
网络层:规定网络ip ip协议
数据链路层:
物理层:光缆、网线

3.8种请求方式:
1、OPTIONS
返回服务器针对特定资源所支持的HTTP请求方法,也可以利用向web服务器发送‘*’的请求来测试服务器的功能性
2、HEAD
向服务器索与GET请求相一致的响应,只不过响应体将不会被返回。这一方法可以再不必传输整个响应内容的情况下,就可以获取包含在响应小消息头中的元信息。
3、GET
向特定的资源发出请求。它本质就是发送一个请求来取得服务器上的某一资源。资源通过一组HTTP头和呈现数据(如HTML文本,或者图片或者视频等)返回给客户端。
4、POST
向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。
5、PUT
向指定资源位置上传其最新内容
6、DELETE
请求服务器删除Request-URL所标识的资源
7、TRACE
回显服务器收到的请求,主要用于测试或诊断
8、CONNECT
HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。

文件上传和下载

使用hfs软件做文件服务器

上传文件:post请求
1.设置请求头信息:
Content-Length:请求体的长度
Content-Type:multipart/form-data; boundary=7e324741816d4(随便)
2.请求体:2部分
第一部分:要有换行
-----------------------------7e324741816d4(一上面随便的一模一样)
Content-Disposition: form-data; name=“file”; filename=“上传到服务器的名字”
Content-Type: media/mp4或者media/mp3或者image/jpeg或者image/png
空行

public class NetUtils {

    public static void download(String strUrl,String path){
        InputStream inputStream = null;
        BufferedInputStream bis = null;
        FileOutputStream fos =null;
        try {
            URL url = new URL(strUrl);
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setReadTimeout(5000);
            urlConnection.setConnectTimeout(5000);
            urlConnection.connect();
            if (urlConnection.getResponseCode() == 200){
                inputStream = urlConnection.getInputStream();
                bis = new BufferedInputStream(inputStream);
                fos = new FileOutputStream(path);
                int len = 0;
                byte[] b = new byte[1024*8];
                while ((len = bis.read(b)) != -1){
                    fos.write(b,0,len);
                }
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if (fos != null){
                    fos.close();
                }
                if (bis != null){
                    bis.close();
                }
                if (inputStream != null){
                    inputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    public static void upload(String strUrl,String path){
        URL url = null;
        FileInputStream fis = null;
        OutputStream outputStream = null;
        try {
            File file = new File(path);
            StringBuffer sb = new StringBuffer();
            String[] split = file.getName().split("[/.]");
            sb.append("-----------------------------8qwert123"+"\r\n");
            String encode = URLEncoder.encode(file.getName());
            sb.append("Content-Disposition: form-data; name=\"file\"; filename=\""+encode+"\""+"\r\n");
            // 如果服务器端有文件类型的校验,必须明确指定ContentType
            if (split[1].equals("jpg")){
                sb.append("Content-Type: image/jpeg" + "\r\n");
            }
            if (split[1].equals("mp3")){
                sb.append("Content-Type: media/mp3" + "\r\n");
            }
            if (split[1].equals("mp4")){
                sb.append("Content-Type: media/mp4" + "\r\n");
            }

            sb.append("\r\n");
            byte[] bytes = sb.toString().getBytes("UTF-8");

            url = new URL(strUrl);
            fis = new FileInputStream(path);
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setRequestMethod("POST");
            urlConnection.setReadTimeout(5000);
            urlConnection.setConnectTimeout(5000);
            urlConnection.setDoOutput(true);
            urlConnection.setRequestProperty("Content-Length",bytes.length+file.length()+"");
            urlConnection.setRequestProperty("Content-Type", "multipart/form-data; boundary="+"8qwert123");

            outputStream = urlConnection.getOutputStream();
            int len = 0;
            byte[] b = new byte[1024*8];
            outputStream.write(bytes);
            while ((len = fis.read(b)) != -1){
                outputStream.write(b,0,len);
            }
            if (urlConnection.getResponseCode() == 200){
                Log.e("@@@@", "upload: success");
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if (outputStream != null){
                    outputStream.close();
                }
                if (fis != null){
                    fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

断点续传
断点续传设置请求头:
Range:bytes=起始位置-终点位置
比如:Range:bytes=0-100
随机访问流响应码 206

线程:

public class Breakpoint_Resume extends Thread {

    private String strUrl;
    private String path;
    private Handler handler;
    private int start;
    private int end;
    private int max;

    public Breakpoint_Resume(String strUrl, String path, Handler handler) {
        this.strUrl = strUrl;
        this.path = path;
        this.handler = handler;
    }

    @Override
    public void run() {
        super.run();
        InputStream inputStream = null;
        RandomAccessFile randomAccessFile = null;
        try {
            URL url = new URL(strUrl);
            HttpURLConnection connection = (HttpURLConnection)url.openConnection();
            Message obtain = Message.obtain();
            max = connection.getContentLength();
            obtain.what = Constant.BREAKPOINT_RESUME_MAX;
            obtain.obj = max;
            handler.sendMessage(obtain);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            File file = new File(path);
            if(file.exists()){
                start= (int) file.length();
            }
            end = max;
            URL url = new URL(strUrl);
            HttpURLConnection connection = (HttpURLConnection)url.openConnection();
            connection.setRequestProperty("Range","bytes="+start+"-"+end);
            if (connection.getResponseCode() == 206){
                inputStream = connection.getInputStream();
                randomAccessFile = new RandomAccessFile(path, "rw");
                randomAccessFile.seek(start);
                byte[] b=new byte[1024];
                int len=0;
                int count=start;
                while ((len = inputStream.read(b)) != -1){
                    randomAccessFile.write(b,0,len);
                    Message obtain = Message.obtain();
                    obtain.what = Constant.BREAKPOINT_RESUME_CURRENT;
                    count+=len;
                    obtain.obj = count;
                    handler.sendMessage(obtain);
                    //线程通讯
                    synchronized (StringBuffer.class){
                        if(FileNetModel.flag){
                            StringBuffer.class.wait();
                        }
                    }
                }
                handler.sendEmptyMessage(Constant.BREAKPOINT_RESUME_FINISH);
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            try {
                if (inputStream != null){
                    inputStream.close();
                }
                if (randomAccessFile != null){
                    randomAccessFile.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

moudle层

public class FileNetModel implements FileNetInterface {

    Breakpoint_Resume breakpoint_resume;
    public static boolean flag = false;
    int flag2;
    @SuppressLint("HandlerLeak")
    public Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what == Constant.start){
                if (flag2==0){
                    breakpoint_resume.start();
                    flag2++;
                }else {
                    flag=false;
                    synchronized (StringBuffer.class){
                        StringBuffer.class.notify();
                    }
                }
            }else if (msg.what == Constant.end){
                    flag = true;
            }
        }
    };

    @Override
    public void download(String strUrl, String path, Handler handler) {
        new DownloadThread(strUrl, path, handler).start();
    }

    @Override
    public void upload(String strUrl, String path, Handler handler) {
        new UploadThread(strUrl, path, handler).start();
    }
    //断点续传
    @Override
    public void breakpoint_resume(String strUrl, String path, Handler handler) {
        breakpoint_resume = new Breakpoint_Resume(strUrl, path, handler);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值