Http协议请求 响应介绍

Posted by BY Blog on December 11, 2018

HTTP协议相关

什么是HTTP

http协议是hyper text transfer protocol(超文本传输协议)的简写,基于TCP/IP通信协议传递数据。http协议是应用层的面向对象的协议,工作在客户端-服务器架构上。浏览器作为http客户端通过url向http服务端即web服务器发送所有请求,web服务器收到请求后,向客户端发送响应信息。

https://upload-images.jianshu.io/upload_images/2964446-5a35e17f298a48e1.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/551/format/webp

HTTP报文结构
http request报文

报文由三部分组成:分别是请求行、请求头和请求体。

http请求报文结构

以一个实际的例子来说明

http request示例

  • 请求行中包含:请求方法、请求资源(uri)和http版本号。请求方法包含get、post、put、delete等
  • 请求头包含若干个属性,格式为 属性名:属性值
    • Accept:通过这个字段告诉服务器客户端接收什么类型的响应,通常有text/plain、application/json等格式
    • Cookie:服务器通过Cookie值知道客户端的多个请求属于一个Session
    • Referer:表示这个请求从哪个URL而来
    • Cache-Control:对缓存进行控制,如一个请求希望响应返回的内容在客户端要被缓存一年,或不希望被缓存就可以通过这个报文头达到目的。
    • 其他参见:https://en.wikipedia.org/wiki/List_of_HTTP_header_fields
  • 请求体:请求中需要传递的参数

如何访问请求头中的信息

访问请求头中的信息可以通过类HttpServletRequest去获取,而在springMVC中,HttpServletRequest要通过RequestContextHolder来获取。具体使用方式参见:

		RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        HttpServletRequest httpServletRequest = ((ServletRequestAttributes)requestAttributes).getRequest();
        // 获取所有头部名字并追加到sb中
        Enumeration<String> headerNames = httpServletRequest.getHeaderNames();
        StringBuilder sb = new StringBuilder();
        while (headerNames.hasMoreElements()) {
            String ele = headerNames.nextElement();
            sb.append(ele + " ; ");
        }

        // 获取特定头部 值并追加到sb
        Enumeration<String> headers = httpServletRequest.getHeaders("content-type");
        sb.append("\n");

        while (headers.hasMoreElements()) {
            sb.append(headers.nextElement() + " ; ");
        }

        // 获取Cookie
        Cookie[] cookies = httpServletRequest.getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("content-type")) {
                sb.append("\n" + cookie.getValue());
                break;
            }
        }
		// 获取sessionId
		HttpSession session = httpServletRequest.getSession();
        sb.append("\nsessionId:" + session.getId());
http response报文

response报文也主要由响应行、响应头、响应体组成:

http response结构

以一个实际的例子来说明

http response示例

  • 响应行:包括报文协议及版本、状态码及状态描述
    • 状态码主要分为5段,分别是
      • 1xx:告诉客户端,请求已收到,正在处理
      • 2xx:处理成功,一般表示请求已受理、已经处理完成等信息
      • 3xx:重定向到其他地方,要客户端再发起一个请求以完成整个处理
      • 4xx:处理发生错误,责任在客户端,如客户端请求一个不存在的资源,客户端未被授权、禁止访问等
      • 5xx:处理发生错误,责任在服务器,如服务端抛出异常、路由出错、http版本不支持等等
  • 响应头:由多个属性组成
    • cache-control:响应输出到客户端后,服务端通过该报文头告诉客户端如何控制响应内容的缓存
    • ETag:一个代表响应服务端资源(如页面)版本的报文头属性,如果某个服务端资源发生变化了,这个ETag就会相应发生变化。它是Cache-Control的有益补充,可以让客户端“更智能”地处理什么时候要从服务端取资源,什么时候可以直接从缓存中返回响应。
    • Location:我们在JSP中让页面Redirect到一个某个A页面中,其实是让客户端再发一个请求到A页面,这个需要Redirect到的A页面的URL,其实就是通过响应报文头的Location属性告知客户端的
    • Set-cookie:设置客户端的Cookie
    • 其他报文头详见:http://en.wikipedia.org/wiki/List_of_HTTP_header_fields 
  • 响应体

如何访问http response中的信息

在服务端,可以通过HttpServletResponse去读取、设置请求头中的信息。HttpServletResponse中主要包含如下API。

// 添加cookie到response头中,该函数可被多次调用,加入不同name的cookie
public void addCookie(Cookie cookie);
// 检查response header中是否包含名为name的头部
public boolean containsHeader(String name);

// encode url和redirect url,返回编码后的url
public String encodeURL(String url);
public String encodeRedirectURL(String url);

// 响应头相关
public void setHeader(String name, String value);
public void addHeader(String name, String value);
public void setIntHeader(String name, int value);
public void addIntHeader(String name, int value);
public void setDateHeader(String name, long date);
public void addDateHeader(String name, long date);
public String getHeader(String name);
public Collection<String> getHeaders(String name);
public Collection<String> getHeaderNames();

// 响应状态相关
public void setStatus(int sc);
public int getStatus();

//不但会设置Location的响应报文头,还会生成303的状态码呢,两者天仙配呢  
public void sendRedirect(String location) throws IOException;
参考文章

Http请求、响应结构体介绍:https://blog.csdn.net/u010256388/article/details/68491509

Http协议介绍:https://www.jianshu.com/p/80e25cb1d81a

RequestContextHolder分析:https://juejin.im/entry/584bac6eb123db0066127bae