相信HTTP协议大家都不陌生,无论是网页浏览,还是REST或WebService等常见消息交互,都是基于HTTP的。
HTTP协议位于网络分层模型中的应用层,基于TCP/IP通信协议来传递数据,传递的数据由起始行、消息头、空行和消息体组成。其中,起始行在客户端请求时为请求行,在服务端响应时为状态行。
例如,服务端响应消息长这样:
我们可以看到,HTTP头由多个头域组成,每个头域由一个域名,冒号(:)和域值三部分组成,域名是大小写无关。
HTTP起始行和消息头中包含了访问URL、状态码、来源IP主机、报文大小等信息,这些信息对日常开发调试或运维排错有极大帮助,因此对HTTP消息中的部分常见信息做个介绍供大家了解和使用。
获取HTTP头信息
通过浏览器的开发者工具可以很方便的看到头信息。
若想通过Java编码来获取,可基于HttpServletRequest对象来做到,例如将头域的键值对存储在Map中:
import javax.servlet.http.HttpServletRequest;
private HttpServletRequest request;
//get request headers
private Map<String, String> getHeadersInfo() {
Map<String, String> map = new HashMap<String, String>();
Enumeration headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String key = (String) headerNames.nextElement();
String value = request.getHeader(key);
map.put(key, value);
}
return map;
}
常见头信息介绍
-
HTTP状态码
- 1xx:信息响应类,表示接收到请求并且继续处理
- 2xx:处理成功响应类,表示动作被成功接收、理解和接受,常见为200
- 3xx:重定向响应类,为了完成指定的动作,必须接受进一步处理
- 4xx:客户端错误,客户请求包含语法错误或者是不能正确执行;常见的404错误,就是找不到资源,赶紧检查URL是否正确吧
- 5xx:服务端错误,服务器不能正确执行一个正确的请求;若见到500的错误,则可以判断是服务端处理存在问题啦
Content-Type
表示后面的消息体属于什么MIME类型。Java Servlet默认为text/plain,但通常需要显式地指定为text/html;而对基于Json的REST交互,则需要配置为application/json。类型和内容不一致的话,则可能导致应用收到消息后不能正常解析。
详细取值范围参考:http://www.runoob.com/http/http-content-type.htmlContent-Length
表示消息体的长度。在服务联调过程中,可能会出现网络问题或连接断开导致消息传递不完整,这个时候通过该字段可以判断消息体长度和正常时是否一致来排查问题。Accept
浏览器/客户端告诉服务端自己接受的介质类型(即Content-Type),/表示任何类型,type/*表示该类型下的所有子类型。Accept-Charset
浏览器/客户端申明自己接受的字符集编码。Date
表示消息发送的时间,时间的描述格式由RFC822定义。例如,Date: Fri, 06 Apr 2018 15:02:56 GMT。Date描述的时间表示世界标准时(即0时区),换算成本地时间需要知道用户所在的时区。X-Forwarded-For
这是一个请求头中的扩展头部,HTTP/1.1(RFC 2616)协议并没有对它的定义,它最开始是由Squid这个缓存代理软件引入,用来表示HTTP请求端真实IP。如今它已经成为事实上的标准,被各大HTTP代理、负载均衡等转发服务广泛使用,并被写入RFC 7239(Forwarded HTTP Extension)标准之中。User-Agent
标识请求者的一些信息,如什么浏览器类型和版本、操作系统,使用语言等信息,例如:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36Cookie
HTTP请求发送时,会把保存在该请求域名下的所有cookie值一起发送给web服务器。
设置头信息
了解到以上内容之后,根据开发需要可设置HTTP头域的值,甚至可以设置一些自定义的头域信息。例如:
public String getRuleList(HttpServletRequest request,
HttpServletResponse response) {
response.setHeader("content-type", "text/html;charset=UTF-8");
response.addHeader("test", "test"); //自定义
return service.getRuleList();
}
// Content-Type: text/html;charset=UTF-8
// test: test
参考资料: