zoukankan      html  css  js  c++  java
  • http协议介绍

    本文是servlet的入门篇,主要简单介绍下http协议

    1.什么是http

    __ 1.http协议:__

    1. 复杂解释:
        http(超文本传输协议)是一个基于请求与响应模式的、无状态的、应用层的协议,常基于TCP的连接方式,HTTP1.1版本中给出一种持续连接的机制,绝大多数的Web开发,都是构建在HTTP协议之上的Web应用。
    2. 简单说:
        对浏览器客户端 和 服务器端 之间数据传输的格式规范.
    3. 协议版本:
        http1.0:当前浏览器客户端与服务器端建立连接之后,只能发送一次请求,一次请求之后连接关闭。
        http1.1:当前浏览器客户端与服务器端建立连接之后,可以在一次连接中发送多次请求。(基本都使用1.1)
          请求一次资源就会出现一次请求,比如三张图片,就有三次请求,如果图片是一样 的就只有一次请求;

    2.查看http协议的工具:

    1. chrome(谷歌)浏览器查看:
        右键点击查看元素(inspect element),点击network即可;
      1
    2. 火狐:
        使用火狐的firebug插件(右键->firebug->网络)
    3. 使用系统自带的telnet工具(远程访问工具)
      a)telnet localhost 8080 访问tomcat服务器
      b)ctrl+] 回车.可以看到回显
      c)输入请求内容,回车,即可查看到服务器响应信息。
    GET / HTTP/1.1
    Host: www.baidu.com
    

    2.http协议内容:

    1. 请求:
    GET /HttpSer HTTP/1.1
    Host: localhost:8080
    Connection: keep-alive
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
    Upgrade-Insecure-Requests: 1
    User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/45.0.2454.85 Chrome/45.0.2454.85 Safari/537.36
    Accept-Encoding: gzip, deflate, sdch
    Accept-Language: en-US,en;q=0.8
    
    1. 响应:
    HTTP/1.1 302 Found 
    Server: Apache-Coyote/1.1 
    Location: http://localhost:8080/HttpSer/ 
    Transfer-Encoding: chunked 
    Date: Fri, 09 Oct 2015 08:55:42 GMT
    

    下面将对这两个协议进行介绍:

    3.http请求介绍:

    GET /HttpSer HTTP/1.1-请求行
    Host: localhost:8080--请求头;有多个key-value组成
    Connection: keep-alive
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
    Upgrade-Insecure-Requests: 1
    User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/45.0.2454.85 Chrome/45.0.2454.85 Safari/537.36
    Accept-Encoding: gzip, deflate, sdch
    Accept-Language: en-US,en;q=0.8
    --可选,实体内容;
    

    请求行介绍

    GET /HttpSer HTTP/1.1 -请求行
    1.请求资源的URL和URI比较:
        URL: 统一资源定位符。http://localhost:8080/HttpSer/index.html。只能定位互联网资源。是URI 的子集.
        URI: 统一资源标记符。/HttpSer/index.html。用于标记任何资源。可以是本地文件系统,局域网的资源(//192.168.14.10/HttpSer/index.html),可以是互联网。
    2.请求方式:
        常见的请求方式: GET 、 POST、 HEAD、 TRACE、 PUT、 CONNECT 、DELETE
        常用的请求方式: GET(有将实体信息放在浏览器地址栏) 和 POST(隐藏实体内容)
    3. servlet获得请求行信息:_

    /*** 1.1请求行的获得*/
    System.out.println("请求方式:"+request.getMethod());//获得提交方式
    System.out.println("请求URI:"+request.getRequestURI());//获得uri
    System.out.println("请求url:"+request.getRequestURL());//获得url
    System.out.println("获得协议:"+request.getProtocol());//获得所用协议
    ##输出:
    请求方式:GET
    请求URI:/HttpSer/TestRequst
    请求url:http://localhost:8080/HttpSer/TestRequst
    获得协议:HTTP/1.1
    

    4. 测试提交方式:
    新建立web工程,建立TestMethod.html文件:
    4
    建立Servlet类TestMethod.java修改get和post方法:

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		response.setContentType("text/html;charset=utf-8");
    		PrintWriter out = response.getWriter();
    		out.println("get 方式提交");
    	}
    
    	/**
    	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
    	 */
    	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		response.setContentType("text/html;charset=utf-8");
    		PrintWriter out = response.getWriter();
    		out.println("post 方式提交");
    	}
    

    运行tomcat可以看淡提交方式的不同:浏览器地址栏显示的不同,servlet调用的方法也不同;
    get提交
    2
    post提交
    3
    经过对比请求可以发现
    get方式在请求行多了?name=wang&pass=123
    post多了实体内容:Content-Type: application/x-www-form-urlencoded
    请求内容同如下:

    #get方式:
    GET /HttpSer/TestMethod?name=wang&pass=123 HTTP/1.1
    Host: localhost:8080
    Connection: keep-alive
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
    Upgrade-Insecure-Requests: 1
    User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/45.0.2454.85 Chrome/45.0.2454.85 Safari/537.36
    Referer: http://localhost:8080/HttpSer/testMethod.html
    Accept-Encoding: gzip, deflate, sdch
    Accept-Language: en-US,en;q=0.8
    #post方式:
    POST /HttpSer/TestMethod HTTP/1.1
    Host: localhost:8080
    Connection: keep-alive
    Content-Length: 18
    Cache-Control: max-age=0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
    Origin: http://localhost:8080
    Upgrade-Insecure-Requests: 1
    User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/45.0.2454.85 Chrome/45.0.2454.85 Safari/537.36
    Content-Type: application/x-www-form-urlencoded
    Referer: http://localhost:8080/HttpSer/testMethod.html
    Accept-Encoding: gzip, deflate
    Accept-Language: en-US,en;q=0.8
    

    请求头介绍:

    1. 请求头介绍:
    请求头主要包含一些有用信息:
    1.Host: localhost:8080主机地址和端口
    2.Connection: keep-alive 连接方式
    3.User-Agent:浏览器的一些信息
    4.Referer:来访页面
    5.Content:实体内容;post才有
    2. servlet获得请求头主要的方法:
    request.getHeader("Host"));通过建获得相应请求的内容;
    Enumeration headerNames = request.getHeaderNames();获得请求头所有的键值
    3. 演示如下:
    修改doget方法

    /*** 设置参数查询的编码
    *该方法只能对请求实体内容的数据编码起作用。POST提交的数据在实体内容中,所以该方法对POST方法有效!
    *GET方法的参数放在URI后面,所以对GET方式无效!!!
     */
    request.setCharacterEncoding("utf-8");
    	/**
    		 * 1.1请求行的获得
    		 */
    		System.out.println("请求方式:"+request.getMethod());
    		System.out.println("请求URI:"+request.getRequestURI());
    		System.out.println("请求url:"+request.getRequestURL());
    		System.out.println("获得协议:"+request.getProtocol());
    		/**
    		 * 1.2请求头的获得
    		 */
    		//通过键获得请求头的内容
    		System.out.println("获得host:"+request.getHeader("Host"));
    		System.out.println("获得浏览器的User-Agent:"+request.getHeader("User-Agent"));
    		//通过迭代器迭代,获得键 在取键值
    		Enumeration<String> headerNames = request.getHeaderNames();
    		while(headerNames.hasMoreElements()){
    			String key=headerNames.nextElement();
    			System.out.println(key+":"+request.getHeader(key));
    		}
    		/**
    		 * 得到请求实体内容
    		 * 比如:实体为name=peace&pass=1234
    		 */
    		ServletInputStream in = request.getInputStream();
    		byte[] buf=new byte[1024];
    		int len=0;
    		while((len=in.read(buf))!=-1){
    			String str=new String(buf,0,len);
    			System.out.println(str);
    		}
    #输出如下:
    请求方式:GET
    请求URI:/HttpSer/TestRequst
    请求url:http://localhost:8080/HttpSer/TestRequst
    获得协议:HTTP/1.1
    获得host:localhost:8080
    获得浏览器的User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/45.0.2454.101 Chrome/45.0.2454.101 Safari/537.36
    host:localhost:8080
    connection:keep-alive
    accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
    upgrade-insecure-requests:1
    user-agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/45.0.2454.101 Chrome/45.0.2454.101 Safari/537.36
    referer:http://localhost:8080/HttpSer/testMethod.html
    accept-encoding:gzip, deflate, sdch
    accept-language:en-US,en;q=0.8
    cookie:CNZZDATA1255712369=1133597550-1443969628-%7C1443969628//此去后面文章会介绍;
    

    输入参数的介绍:

    1. 输入参数:
    输入参数:
    对于get来说就是跟在url后面的内容
    /TestParam?name="peace"&password="sisi" ;name="peace"&password="sisi"这就是输入参数
    对于post来说就是实体内容,不可见
    2. Servlet中获得输入参数的方法:
    String name=request.getParameter("name");获得对应输入参数名字的内容
    Enumeration params = request.getParameterNames();获得所有输入参数的名字,返回一个迭代器
    String[] hobits = request.getParameterValues(names);如果对应名字的内容是一个数组,使用这个方法获得,比如复选框

    3. 演示如下:
    1.建立testParam.html
    5
    2.修改doget方法:

    /**
    		 * 设置参数查询的编码
    		 * 该方法只能对请求实体内容的数据编码起作用。POST提交的数据在实体内容中,所以该方法对POST方法有效!
    		 * GET方法的参数放在URI后面,所以对GET方式无效!!!
    		 */
    		request.setCharacterEncoding("utf-8");
    		//获得所有的方式
    		
    		System.out.println("提交方式:"+request.getMethod());
    		//获得输入参数
    		String name=request.getParameter("name");
    		String pass=request.getParameter("password");
    		System.out.println("name:"+name+",pass:"+pass);
    		/*此去为如果get方式提交出现乱码,使用;
    		 * if("GET".equals(request.getMethod())){
    		password = new String(password.getBytes("iso-8859-1"),"utf-8");
    	}*/
    		System.out.println(">>>>>>>>>>>>>>>>>");
    		//获得所有输入参数的名字
    		Enumeration<String> params = request.getParameterNames();
    		while(params.hasMoreElements())
    		{
    			String names=params.nextElement();
    			//如果是复选框,使用getParameterValues(names);方法
    			if("hobit".equals(names)){
    			   System.out.println(names+":");
    			   String[] hobits = request.getParameterValues(names);
    			   for(String s:hobits)
    				   System.out.print(s+",");
    				System.out.println();
    			}
    		
    			else{
    				System.out.println(names+":"+request.getParameter(names));
    			}
    		}
    ##输出结果如下:
    提交方式:POST
    name:peace,pass:124
    >>>>>>>>>>>>>>>>>
    name:peace
    password:124
    gender:男
    籍贯:湖南
    hobit:
    篮球,足球,
    info:一条小鲨鱼peace
    id:001
    

    4.http响应介绍:

    HTTP/1.1 302 Found  ---响应行 
    Server: Apache-Coyote/1.1 ---响应头, 有多个key-value组成
    Location: http://localhost:8080/HttpSer/ 
    Transfer-Encoding: chunked 
    Date: Fri, 09 Oct 2015 08:55:42 GMT
    

    响应行介绍:

    HTTP/1.1 302 Found
    1基本介绍
    1.HTTP/1.1:采用的协议
    2.302:状态码
    常见的状态:
    200 : 表示请求处理完成并完美返回
    302: 表示请求需要进一步细化。
    404: 表示客户访问的资源找不到。
    500: 表示服务器的资源发送错误。(服务器内部错误)
    3.Found:状态描述,常见ok和found
    2. servlet中的方法
    tomcat服务器把请求信息封装到HttpServletRequest对象,且把响应信息封装到HttpServletResponse
    response.setStatus(404);//设置状态码
    response.sendError(404);// 设置错误页面
    3. 演示如下

    response.setStatus(404);//错误代码,没有反应
    response.sendError(404);// 发送404的状态码+404的错误页面
    #输出结果:
    HTTP/1.1 404 Not Found
    Server: Apache-Coyote/1.1
    Content-Type: text/html;charset=ISO-8859-1
    Content-Language: en
    Content-Length: 949
    Date: Sat, 10 Oct 2015 13:09:53 GMT
    

    6

    响应头介绍:

    1. 基本介绍
    格式:Server: Apache-Coyote/1.1;Server响应头名,后面的是响应值;
    头里面主要包括:Server,服务器类型;Location:跳转网页地址 Conten*:实体内容
    2. servlet中的方法
    response.setHeader("server", "JBoss");修改对应头名的内容;
    3. 演示如下

    //修改服务器类型
    	response.setHeader("server", "JBoss");
    		/**
    		 * 修改实体内容
    		 */
    		//浏览器能直接看到的内容就是实体内容
    		response.getWriter().println("hello peace");//字符内容,常用
    		//response.getOutputStream().write("hello world".getBytes());//字节内容。不能两个同时使用
    #输出如下:
    HTTP/1.1 200 OK
    server: JBoss
    Content-Length: 12
    Date: Sat, 10 Oct 2015 13:11:04 GMTHTTP/1.1 200 OK
    server: JBoss
    Content-Length: 12
    Date: Sat, 10 Oct 2015 13:11:04 GMT
    

    7

    几个常要的方面介绍

    1. 测试重定向:与转发不同
    /**
    		 * 测试重定向:与转发不同
    		 * 使用请求重定向:发送一个302状态吗+location的响应
    		 * 
    		 */
    response.setStatus(302);//设置状态码
    response.setHeader("location", "/HttpSer/adv.html");//设置重定向页面
    		//简单写法
    	//	response.sendRedirect("/HttpSer/adv.html");
    #输出:
    HTTP/1.1 302 Found
    Server: Apache-Coyote/1.1
    location: /HttpSer/adv.html
    Content-Length: 12
    Date: Sat, 10 Oct 2015 13:15:26 GMT
    
    1. 定时刷新:
    /**
    		 * 定时刷新
    		 * 原理:浏览器解析refresh头,得到头之后重新请求当前资源
    		 *
    		 */
    		//response.setHeader("refresh", "1");//每隔1秒刷新一次
    		//隔5秒后转到另外的资源
    		//response.setHeader("refresh", "5;url=/HttpSer/adv.html");
    #输出:
     HTTP/1.1 200 OK
    Server: Apache-Coyote/1.1
    refresh: 1
    Content-Length: 12
    Date: Sat, 10 Oct 2015 13:18:39 GMT
    HTTP/1.1 200 OK
    Server: Apache-Coyote/1.1
    refresh: 5;url=/HttpSer/adv.html
    Content-Length: 12
    Date: Sat, 10 Oct 2015 13:21:29 GMT
    
    1. 设置编码:
    response.setCharacterEncoding("utf-8");
    		
    		/**
    		 * 1. 服务器发送给浏览器的数据类型和内容编码
    		 */
    		//response.setHeader("content-type", "text/html");//设置内容为html
    		//response.setContentType("text/html;charset=utf-8");//和上面代码等价。推荐使用此方法
    		//response.setContentType("text/xml");//设置内容为xml
    		//response.setContentType("image/png");//设置内容为图片
    
    1. 设置为下载方式打开文件:
    /**
    		 * 设置以下载方式打开文件
    		 */
    		//response.setHeader("Content-Disposition", "attachment; filename="+file.getName());
    
    1. 发送硬盘图片给浏览器:
    	File file = new File("/media/peace/本地磁盘/andriod/1.png");//WebContent
    		/**
    		 * 发送图片
    		 */
    		FileInputStream in = new FileInputStream(file);
    		byte[] buf = new byte[1024];
    		int len = 0;
    		
    		//把图片内容写出到浏览器
    		while( (len=in.read(buf))!=-1 ){
    			response.getOutputStream().write(buf, 0, len);
    		}
    

    来自一条小鲨鱼(rlovep.com)
    代码下载

  • 相关阅读:
    Webpack打包原理
    Vue——VNode
    Vue——响应式原理
    HTTP2.0——头部压缩
    HTTP2.0
    浏览器打开2个页面会有几个进程?
    计算机网络——TCP如何保证可靠性
    操作系统——进程之间的通信
    前端路由hash与history下
    前端路由hash与history上
  • 原文地址:https://www.cnblogs.com/onepeace/p/4952208.html
Copyright © 2011-2022 走看看