HTTP协议入门——1.1版本

HTTP协议入门——1.1版本

基本概述

    超文本传输协议(HTTPHyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议。所有的WWW文件都必须遵守这个标准。

    HTTP协议(HyperText Transfer Protocol,超文本传输协议)是用于从WWW服务器传输超文本到本地浏览器的传输协议。它可以使浏览器更加高效,使网络传输减少。它不仅保证计算机正确快速地传输超文本文档,还确定传输文档中的哪一部分,以及哪部分内容首先显示(如文本先于图形)等。

    HTTP是客户端浏览器或其他程序与Web服务器之间的应用层通信协议。在Internet上的Web服务器上存放的都是超文本信息,客户机需要通过HTTP协议传输所要访问的超文本信息。HTTP包含命令和传输信息,不仅可用于Web访问,也可以用于其他因特网/内联网应用系统之间的通信,从而实现各类应用资源超媒体访问的集成。

 

长连接和短连接的区别

解释1

所谓长连接指建立SOCKET连接后不管是否使用都保持连接,但安全性较差,   
所谓短连接指建立SOCKET连接后发送后接收完数据后马上断开连接,一般银行都使用短连接

解释2

长连接就是指在基于tcp的通讯中,一直保持连接,不管当前是否发送或者接收数据。   
而短连接就是只有在有数据传输的时候才进行连接,客户-服务器通信/传输数据完毕就关闭连接。

解释3

长连接和短连接这个概念好像只有移动的CMPP协议中提到了,其他的地方没有看到过。   
通信方式   
各网元之间共有两种连接方式:长连接和短连接。所谓长连接,指在一个TCP连接上可以连续发送多个数据包,在TCP连接保持期间,如果没有数据包发送,需要双方发检测包以维持此连接。短连接是指通信双方有数据交互时,就建立一个TCP连接,数据发送完成后,则断开此TCP连接,即每次TCP连接只完成一对 CMPP消息的发送。   
现阶段,要求ISMG之间必须采用长连接的通信方式,建议SPISMG之间采用长连接的通信方式。

解释4

短连接:比如http的,只是连接、请求、关闭,过程时间较短,服务器若是一段时间内没有收到请求即可关闭连接。   
长连接:有些服务需要长时间连接到服务器,比如CMPP,一般需要自己做在线维持。

 

参考文章:http://blog.csdn.net/shine0181/article/details/7799754

 

HTTP请求部分

基本结构

GET /q547550831?viewmode=contents HTTP/1.1 [请求行]

Host: blog.csdn.net [消息头消息名:内容

Connection: keep-alive 

Cache-Control: max-age=0 

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 

User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36 

Referer: http://blog.csdn.net/q547550831?viewmode=contents 

Accept-Encoding: gzip, deflate, sdch 

Accept-Language: zh-CN,zh;q=0.8

PS:这是我博客主页的请求头,但是这并不代表每个网页的请求头都是这一样的。


请求方式

    请求方式有:

POST,GET,HEAD,OPTIONS,DELETE,TRACE,PUT,CONNECT

参考文档:http://tools.jb51.net/table/http_request_method

常用的有:POSTGET


请求消息头

Host: blog.csdn.net [主机名]

Connection: keep-alive [连接状态:保持连接]

Cache-Control: max-age=0 [指定请求和响应遵循的缓存机制:查看是否有修改并选择更新否]

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 [可接受的格式]

User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36 [浏览器内核]

Referer: http://blog.csdn.net/q547550831?viewmode=contents [从哪个网页跳转到这个网页来的,可以用来防盗链]

Accept-Encoding: gzip, deflate, sdch [可接收的压缩格式]

Accept-Language: zh-CN,zh;q=0.8 [浏览器支持的语言]

 

PS:请求是指浏览器发出向服务器发出,所以这些信息都是浏览器的信息。请求头远远不止这几种,可以参考该文档:http://tools.jb51.net/table/http_header

 

案例:防止盗链

package com.pc;

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

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

public class Servlet6 extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		response.setContentType("text/html;charset=utf-8");
		response.setCharacterEncoding("utf-8");
		PrintWriter out = response.getWriter();
		
		out.println("<a href='http://127.0.0.1:8080/servlet1/Servlet5'>连接到Servlet5</a>");
		
		out.flush();
		out.close();
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		this.doGet(request, response);
	}

}

package com.pc;

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

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

public class Servlet5 extends HttpServlet {
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		response.setCharacterEncoding("utf-8");
		PrintWriter out = response.getWriter();
		// 通过request对象来获取http请求信息
		// 取出Host
		String host = request.getHeader("Host");
		out.println("host=" + host);
		
		// 限制用户
		// 获取用户浏览器的Referer
		// referer可以防止盗链,通过判断链接来至哪里
		String referer = request.getHeader("Referer");
		if(referer == null || !referer.startsWith("http://127.0.0.1:8080/servlet1")){
			out.println("非法盗链");
		} else {
			out.println("referer=" + referer);
		}
		
		
		out.flush();
		out.close();
	}
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 一般开发人员习惯把doGet()和doPost()合二为一
		this.doGet(request, response);
	}
	public void init() throws ServletException {
		// Put your code here
	}

}

PS:该案例中只能允许http://127.0.0.1:8080/servlet1开头的网址进行访问Servlet5


HTTP响应部分

基本结构

HTTP/1.1 200 OK [状态行]

Server: openresty [消息名消息名:内容

Date: Fri, 01 Jan 2016 08:11:04 GMT 

Content-Type: text/html; charset=utf-8 

Transfer-Encoding: chunked 

Connection: keep-alive 

Vary: Accept-Encoding 

Cache-Control: private 

Set-Cookie: uuid=5cad65d6-7a99-4b15-a6e6-5c50e584ca77; expires=Sat, 02-Jan-2016 08:13:49 GMT; path=/ 

Set-Cookie: ViewMode=contents; path=/ 

Content-Encoding: gzip

--------------这是一个空行

消息体

 

响应状态码

    响应状态码分别为1,2,3,4,5开头的三位数字

1**                       

信息,服务器收到请求,需要请求者继续执行操作

2**                      

成功,操作被成功接收并处理

3**                      

重定向,需要进一步的操作以完成请求

4**                      

客户端错误,请求包含语法错误或无法完成请求

5**                      

服务器错误,服务器在处理请求的过程中发生了错误

 

PS:常见的有200(成功)303(重定向)400(Not Found)500(服务器内部错误)

可以参考该文档:http://tools.jb51.net/table/http_status_code

 

响应消息头

Server: openresty [服务器名称]

Date: Fri, 01 Jan 2016 08:11:04 GMT [原始服务器消息发出的时间]

Content-Type: text/html; charset=utf-8 [返回内容的MIME类型]

Transfer-Encoding: chunked [文件传输编码]

Connection: keep-alive [连接状态:保持连接]

Vary: Accept-Encoding [告诉下游代理是使用缓存响应还是从原始服务器请求]

Cache-Control: private [告诉所有的缓存机制是否可以缓存及哪种类型]

Set-Cookie: uuid=********; expires=Sat, 02-Jan-2016 08:13:49 GMT; path=/ [设置Http Cookie]

Set-Cookie: ViewMode=contents; path=/ [设置Http Cookie]

Content-Encoding: gzip [web服务器支持的返回内容压缩编码类型]

 

PS:可以参考该文档http://tools.jb51.net/table/http_header


缓存机制

    浏览器默认情况下,会缓存所访问的页面,这样会出现一个问题:如果用户习惯把光标停留在地址栏,然后回车来取页面,就会默认调用cache中取数据

 

案例1有些网站要求及时性很高,因此要求不缓存页面。

//指定该页面不缓存 Ie

response.setDateHeader("Expires", -1);【针对IE浏览器设置不缓存】

//为了保证兼容性.

response.setHeader("Cache-Control", "no-cache");【针对火狐浏览器等】

response.setHeader("Pragma", "no-cache");【其他浏览器】

 

案例2有些网站要求网页缓存一定时间,比如缓存一个小时

response.setDateHeader("Expires", System.currentTimeMillis()+3600*1000); //后面一个参数表示设置的缓存保持时间,-1表示永远不缓存


Content-Type消息头

    Content-Type,内容类型,一般是指网页中存在的Content-Type,用于定义网络文件的类型和网页的编码,决定浏览器将以什么形式、什么编码读取这个文件

PS:其作用就是告诉浏览器,该服务器返回的网页中消息体是什么格式的,该以什么编码格式来读取这个网页。

因为该类型很多,故给出参考文档,以备后用:http://tools.jb51.net/table/http_content_type



案例1:定时刷新Refresh的使用

 response.setHeader("Refresh", "5;url=/servletPro/Servlet2"); // 5秒后刷新并跳转到url后的链接。通过这个可以实现页面定时刷新。

 

案例2:文件下载

package com.pc;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;

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

public class Servlet7 extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		response.setContentType("text/html;charset=utf-8");
		response.setCharacterEncoding("utf-8");
		// 演示下载文件
		response.setHeader("Content-Disposition", "attachment; filename=EVO_120G.jpg");
		
		// 打开文件
		// 1.获取到要下载文件的全路径
		String path = this.getServletContext().getRealPath("/EVO_120G.jpg");
		// 测试
		System.out.println("path=" + path);
		// 2.创建文件输入流
		FileInputStream fis = new FileInputStream(new File(path));
		// 做一个缓冲字符数组
		byte buff[] = new byte[1024];
		int length = 0;
		// 3.指向response的输出流
		OutputStream os = response.getOutputStream();
		// 4.循环读出
		// length表示每次实际读入的字节数
		while((length = fis.read(buff)) != -1){
			os.write(buff, 0, length);
		}
		
		// 关闭
		os.close();
		fis.close();
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		this.doGet(request, response);
	}

}

 




----------参考《韩顺平.细说Servlet


你可能感兴趣的:(http,servlet,http协议,状态码,消息头)