JavaWeb学习篇之----HTTP协议详解
简介:
- <img src="1.jpg"/>
- <img src="2.jpg"/>
- <img src="3.jpg"/>
这是使用了三个图片标签,我们再次访问:http://localhost:8080/aa/index.html
HTTP的请求内容
一个完整的HTTP请求包含:
1.一个请求行(GET /aa/index.html HTTP/1.0)
2.若干个请求头(告诉服务器客户端的一些信息)
3.实体内容(请求的时候需要向服务器传递的内容)。
注意:请求行,请求头,然后后空一行,请求信息(如表单提交数据为post方式)。
请求行:用于描述客户端的请求方式,请求的资源名称,以及使用的HTTP的协议版本号
GET /aa/index.html HTTP/1.0
请求头:
告诉服务器一些客户端的信息
Accept:用于告诉服务器,客户机支持的数据类型(值为:text/html(文本),image(图片),/*/(任何类型)
Accept-Charset:客户机采用的编码
Accept-Encoding:客户机支持的压缩格式
Accept-Language:客户机的语言环境,不同国家访问的内容也是不同的,就是通过这个头实现的,用于实现国际化
Host:告诉服务器,想访问的主机名
If-Modified-Since:客户机将这个头信息发送给服务端,服务端进行比对,告诉客户机是否去拿缓存,和服务器端返回的Last-Modified值是相等的
If-None-Match:客户机将这个头信息发送给服务端,服务端进行比对,告诉客户机是否去拿缓存,和服务器端返回的Etag值是相等的
Referer:客户机告诉服务器,他是从哪个资源来访问服务器的(防盗链),通过检查该头是否是从本网站点击过来的,如不是的,就让他跳到本网站的首页来
User-Agen::客户机告诉服务器,客户机的软件环境
Cookie:客户机通过这个头向服务器带点数据
Connection:客户机的连接状态(close:关闭连接 Keep-Alive:不会断开连接)
例子:
这个是我在访问http://localhost:8080/aa/index.html,可以看到请求信息。
以上的内容为多个消息头,用于描述客户端请求哪台主机,以及客户端的一些环境信息等
请求行中的GET称之为请求方式,请求方式:post,get,head,options,delete,trace,put,常用的有:get,post,用户没有设置,默认情况下浏览器向服务器发送的都是get请求,例如在浏览器直接输地址访问,点击链接访问都是get,用户如想把请求方式改为post,可通过更改表单form的提交方式实现.不管post或get,都用于向服务器请求某个web资源,这两种方式的区别主要表现在数据传递上:请求方式为get方式,则可以再请求的URL地址后以?的形式带上交给服务器的数据,多个数据之间以&进行分割,同时在URL地址后附带的参数是有限制的,其数据容量通常不能超过1k,若请求方式为post方式,则可以再请求的实体内容中向服务器发送数据,post方式的特点:传送的数据无限制.
- <a href="/2.html?name=jiangwei">2.html</a>
点击这个链接就是一个get方式,而且携带了name字段值
点击链接是Get方式,而且是在资源地址后面携带信息的。
同时再看一下Referer这个请求头,这个头代表的是从当前页面是从哪个页面跳转过来的:
我们点击上面的2.html超链接,跳转到了2.html页面这时候可以看到请求头中的Referer:http://localhost:8080/aa/index.html,表明2.html页面是从index.html页面跳转过来的,这个请求头的作用还是很大的,主要用于防盗链,比如用户点击了一个链接跳转到一个页面中,该页面的网站站长发现这个用户不是从指定的页面中跳转过来的,所以就会让页面跳转到该网站的首页,让用户从该网站的首页跳转到该页面。
下面在/aa/index.html文件中添加一个表单:
- <form action="/2.html" method="post">
- <input type="text" name="name"/>
- <input type="submit"/>
- </form>
在文本框中输入内容,点击提交按钮:
可以看到这种方式是post方式,而且在请求头之后空一行,是请求内容信息。
HTTP的响应内容
响应头:
用于描述服务器的基本信息,以及数据的描述,服务器通过这些数据的描述信息,可以通知客户端如何处理等一会它会送的数据
Location:这个头配合302状态码使用,用于告诉用户找谁
- response.setStatus(302);
- response.setHeader("Location","/aa/1.html");
请求重定向,判断浏览器的地址栏的地址是否发生变化,实例是用户登录
Server:服务器通过这个头,告诉浏览器的类型
Content-Encoding:服务器通过这个头,数据的压缩格式,收费是靠数据出口量算的, 所以为了省钱和效率高,要进行数据压缩,jdk中的GZIPOutputStream类,压缩类流,包装流和底层流,最好将包装流关了或者刷新,数据写入到底层流中去,
- response.setHeader("Content-Encoding","gzip");
- response.setHeader("Content-length",gzip.length+"");
Content-Length:服务器会送的数据的长度
Content-Type:服务器会送数据的类型,response.getOutputStream().write();服务器会送数据都是二进制,通过这个头,可以告诉浏览器这个二进制是什么类型,
- InputStream in = this.getServletContext().getResourceAsStream("/1.jpg");
- int len = 0;
- byte buffer[] =new byte[1024];
- OutputStream out =response.getOutputStream();
- while((len=in.read(buffer))>0){
- out.write(buffer,0,len)
- }
在服务器的目录下的web.xml中查看各个数据类型的respose.setHeader("content-type","")的写法.
Refresh:告诉浏览器隔多长时间刷新一次,response.setHeader("refresh","3;url=""")控制浏览器隔三秒跳到指定的网页上
Content-Disposition:告诉浏览器以下载的方式打开文件
- response.setHeader("content-disposition","attachment;filename=1.jpg);
Transfer-Encoding:告诉浏览器数据的传送格式
Last-Modified:服务端文件的最后修改时间,这个值返回给客户端,客户机第二次访问服务器时带来的If-Modified-Since的值和服务器的值一样,就拿缓存给客户,实时更新,
ETag:缓存相关的头,服务器根据数据的内容生产一个字符串,客户机第二次访问服务器时带来的If-None-Match的值和服务器的值一样,就拿缓存给客户,实时更新,
Expires:高速浏览器,把会送的资源缓存多少时间,-1或0,则是不缓存的
Pragma:no-cache
Cache-Control:no-cache
Date:控制浏览器不要缓存数据,当数据不发生改变时,就要缓存,当实时性要求很高的数据不能缓存.
响应行:
HTTP /1.1 200 OK :状态行,用于描述服务器对请求的处理结果
格式:HTTP版本号 状态码 原因叙述
状态码用于表示服务器对请求的处理结果,他是一个三位的十进制数,响应状态码分为5类,
100-199:表示接收请求,要求客户端继续提交下一次请求才能完成整个处理过程
200-299:表示成功接收请求并已完成整个处理过程,常用200
300-399:为完成请求,客户需进一步细化请求,例如,请求的资源已经移动一个新地址,常用302(你请求我,我叫你去找别人),307和304(拿缓存)
400-499:客户端的请求有错误,常用404,403(没有权限访问,之前我们在打开Tomcat Manager页面的时候遇到过)
500-599:服务器端出现错误,常用500
实体内容:
在响应头后面空一行是服务器返回的实体内容:
<HTML>
<BODY>
...........
- package com.http.demo;
- import java.io.ByteArrayOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.OutputStream;
- import java.util.zip.GZIPOutputStream;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- public class HttpServletDemo extends HttpServlet {
- private static final long serialVersionUID = -7234797658264000867L;
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {
- //测试
- try{
- //test1(resp);//location响应头
- //test2(resp);//Content-Encoding响应头
- //test3(resp);//Content-Type响应头
- test4(resp);//refresh响应头
- //test5(resp);//content-disposition
- }catch(Exception e){
- e.printStackTrace();
- }
- }
- @Override
- protected void doPost(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {
- doGet(req,resp);
- }
- //使用响应头location和302状态码实现请求重定向(地址栏中的地址发生改变)
- public void test1(HttpServletResponse response){
- response.setStatus(302);
- response.setHeader("Location", "/aa/3.html");
- }
- //使用响应头Content-Encoding实现数据的压缩输出
- public void test2(HttpServletResponse resp) throws Exception{
- //压缩数据很大的时候压缩效率才有体现,如果数据很小的话反而更大
- //压缩资源:提高网页的访问性能,电信按照出口流量收钱的。
- String data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";//压缩数据大点还有效果
- System.out.println("压缩前的数据大小:"+data.length());
- ByteArrayOutputStream bout = new ByteArrayOutputStream();//底层流
- GZIPOutputStream gout = new GZIPOutputStream(bout);//包装流一般有缓冲,没有把缓冲区写满,不会写到底层流
- gout.write(data.getBytes());
- gout.close();//等于刷新操作,将包装流中的信息刷新
- byte gzip[] = bout.toByteArray();//得到压缩后的数据
- System.out.println("压缩后的数据大小:"+gzip.length);
- //通知浏览器数据采用压缩格式
- resp.setHeader("Content-Encoding", "gzip");
- resp.setHeader("Content-Length", gzip.length+"");//表明长度
- resp.getOutputStream().write(gzip);//压缩数据写给浏览器
- }
- //使用响应头content-type设置服务器返回给client的数据类型
- public void test3(HttpServletResponse resp) throws Exception{
- //具体可以查看tomcat目录中的web.xml文件
- resp.setHeader("Content-Type","image/jpeg");
- InputStream ins = this.getServletContext().getResourceAsStream("/1.jpg");
- int len = 0;
- byte[] buffer = new byte[1024];
- OutputStream ops = resp.getOutputStream();
- while((len = ins.read(buffer))!=-1){
- ops.write(buffer, 0, len);
- }
- ops.close();
- }
- //使用响应头refresh实现页面的定时刷新
- public void test4(HttpServletResponse resp) throws Exception{
- //股票,聊天室
- //填充的值为:3;url="http://www.baidu.com"表示3s之后跳转到http://www.baidu.com页面
- //如果没有http://www.baidu.com的话,只是在该页面进行刷新
- resp.setHeader("refresh", "3;url=\"http://www.baidu.com\"");
- String data = "aaaaaaaaaaaaaa";
- resp.getOutputStream().write(data.getBytes());
- }
- //使用响应头content-disposition实现客户机用下载的方式打开数据资源
- public void test5(HttpServletResponse resp) throws Exception{
- resp.setHeader("content-disposition","attachment;filename=1.jpg");
- InputStream ins = this.getServletContext().getResourceAsStream("/1.jpg");
- int len = 0;
- byte[] buffer = new byte[1024];
- OutputStream ops = resp.getOutputStream();
- while((len = ins.read(buffer))!=-1){
- ops.write(buffer, 0, len);
- }
- }
- }
- resp.setHeader("refresh", "3");
每隔3s刷新该页面
- resp.setHeader("refresh", "3;url=\"http://www.baidu.com\"");
这个就是说3s之后跳转到baidu首页。
JavaWeb学习篇之----HTTP协议详解的更多相关文章
- JavaWeb学习篇之----容器Response详解
今天在来看一下Response容器的相关知识,其实这篇blog早就应该编写了,只是最近有点忙,所以被中断了.下面我们就来看一下Response容器的相关知识吧.Response和我们即将在后面说到的R ...
- JavaWeb学习篇之----容器Request详解
前篇说到了Response容器对象,这篇我们就来看一下Request容器对象,之前也说过了,这个两个容器对象是相对应的,每次用户请求服务器的时候web容器就会给创建这对容器对象,他们是共存亡的,当然R ...
- JavaWeb学习篇之----EL表达式详解
我们之前的几篇文章中都提到了一个EL表达式,那么这个EL表达式到底是什么东东呢?为什么用处那么大,下面我们就来看看EL表达式的相关内容 EL表达式简介: EL 全名为Expression Langua ...
- JavaWeb学习----JSP内置对象详解
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...
- [转载]JavaEE学习篇之——JQuery技术详解
原文链接:http://blog.csdn.net/jiangwei0910410003/article/details/32102187 1.简介2.工具3.jQuery对象 1.DOM对象转化成j ...
- J2EE学习篇之--JQuery技术详解
前面我们讲解了的J2EE的技术都是服务端的技术,下面我们来看一下前端的一些开发技术,这一篇我们来看一下jQuery技术 简介: jQuery由美国人John Resig创建,至今已吸引了来自世界各地的 ...
- J2EE学习篇之--Struts2技术详解
前面说到了Struts1的相关知识,下面来说一下Struts2的相关知识,我们知道现在Struts2使用的比Struts1多,Struts2已经替代Struts1成为主流的框架了... 摘要 Stru ...
- J2EE学习篇之--Spring技术详解
今天我们来看一下Spring的相关知识,我们知道Spring也是一个开源的框架,这个框架并不像是Struts一样,这个框架是可以用在Java的所有地方,所以,其实开发Android的时候我们也是可以使 ...
- TCP /IP协议详解【转】
转自:https://www.jianshu.com/p/0cf648510bce?utm_campaign=maleskine&utm_content=note&utm_medium ...
随机推荐
- 微信小程序登陆流程
#1:session_key和openId是什么?session_key 官方说明为:session_key是微信服务器生成的针对用户数据进行加密签名的密钥session_key的用途(1)对wx.g ...
- ecstore中kvstore之mongodb
mongodb安装 详细见 http://blog.csdn.net/motian06/article/details/17560067 mongodb扩展安装 详细见 http://blog.csd ...
- JAVA调用c/c++代码
JNI是Java Native Interface的缩写,中文为JAVA本地调用.使用JNI可以很方便的用我们的Java程序调用C/C++程序.很多时候,某些功能用Java无法实现,比如说涉及到底层驱 ...
- ibatis resultMap 的用法
先看个具体的例子: <resultMap id=”get-product-result” class=”com.ibatis.example.Product”> <result pr ...
- Mac搭建Hadoop源码阅读环境
1.本次Hadoop源码阅读环境使用的阅读工具是idea,Hadoop版本是2.7.3.需要安装的工具包括idea.jdk.maven.protobuf等 2.jdk,使用的版本是1.8版,在jdk官 ...
- LPC1768的USB使用-枚举过程
枚举过程如下 #ifndef __USBCORE_H__ #define __USBCORE_H__ /* USB端点0 发送数据结构体*/ typedef struct _USB_EP_DATA { ...
- 《玩转Bootstrap(JS插件篇)》笔记
导入JavaScript插件 不论是单独导入还一次性导入之前必须先导入jQuery库. 一次性导入 <script src="js/bootstrap.min.js"> ...
- jQuery简单实现图片预加载
我们在做网站的时候经常会遇到这样的问题:一个页面有大量的图片导致页面加载速度缓慢,经常会出现一个白页用户体验很不好.那么如何解决这个问题呢?下面我来介绍一种在实际应用中经常会使用到的js预加载的方法. ...
- 在IOS中使用DES算法对Sqlite数据库进行内容加密存储并读取解密
在IOS中使用DES算法对Sqlite 数据库进行内容加密存储并读取解密 涉及知识点: 1.DES加密算法: 2.OC对Sqlite数据库的读写: 3.IOS APP文件存储的两种方式及读取方式. 以 ...
- 复习php的一些函数
2014.07.04 查看ecshop的一些源码,学习了一些函数.