https://blog.csdn.net/a360316515/article/details/77272128
https://www.cnblogs.com/Garnett-Boy/p/8251561.html
客户端发送一个HTTP请求到服务器的请求消息包括以下格式:请求行、请求头部、空行和请求数据四个部分组成。
服务器接收并处理客户端发过来的请求后会返回一个HTTP的响应消息。HTTP响应也由四个部分组成,分别是:状态行、消息报头、空行和响应正文。
主要特点
1、简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
2、灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
3.无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
4.无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
5、支持B/S及C/S模式。
URL,全称是UniformResourceLocator, 中文叫统一资源定位符,是互联网上用来标识某一处资源的地址。URL一般由三部组成:①协议(或称为服务方式)②存有该资源的主机IP地址(有时也包括端口号)③主机资源的具体地址。如目录和文件名等。
以下面这个URL为例,介绍下普通URL的各部分组成:
http://www.aspxfans.com:8080/news/index.asp?boardID=5&ID=24618&page=1#name
从上面的URL可以看出,一个完整的URL包括以下几部分:
1.协议部分:该URL的协议部分为“http:”,这代表网页使用的是HTTP协议。在Internet中可以使用多种协议,如HTTP,FTP等等本例中使用的是HTTP协议。在"HTTP"后面的“//”为分隔符
2.域名部分:该URL的域名部分为“www.aspxfans.com”。一个URL中,也可以使用IP地址作为域名使用
3.端口部分:跟在域名后面的是端口,域名和端口之间使用“:”作为分隔符。端口不是一个URL必须的部分,如果省略端口部分,将采用默认端口
4.虚拟目录部分:从域名后的第一个“/”开始到最后一个“/”为止,是虚拟目录部分。虚拟目录也不是一个URL必须的部分。本例中的虚拟目录是“/news/”
5.文件名部分:从域名后的最后一个“/”开始到“?”为止,是文件名部分,如果没有“?”,则是从域名后的最后一个“/”开始到“#”为止,是文件部分,如果没有“?”和“#”,那么从域名后的最后一个“/”开始到结束,都是文件名部分。本例中的文件名是“index.asp”。文件名部分也不是一个URL必须的部分,如果省略该部分,则使用默认的文件名
6.锚部分:从“#”开始到最后,都是锚部分。本例中的锚部分是“name”。锚部分也不是一个URL必须的部分
7.参数部分:从“?”开始到“#”为止之间的部分为参数部分,又称搜索部分、查询部分。本例中的参数部分为“boardID=5&ID=24618&page=1”。参数可以允许有多个参数,参数与参数之间用“&”作为分隔符。
HTTP协议中定义了浏览器和服务器进行交互的不同方法,基本方法有4种,分别是GET,POST,PUT,DELETE。这四种方法可以理解为,对服务器资源的查,改,增,删。
GET:从服务器上获取数据,也就是所谓的查,仅仅是获取服务器资源,不进行修改。
POST:向服务器提交数据,这就涉及到了数据的更新,也就是更改服务器的数据。
PUT:PUT的英文含义是放置,也就是向服务器新添加数据,就是所谓的增。
DELETE:从字面意思也能看出,这种方式就是删除服务器数据的过程。
POST和GET方式的安全性是相对的,另外也要看是从哪个角度来看的。从数据传输过程方面来看,POST方式是更加安全的,但是从对服务器数据的操作来看,POST方式的安全性又是比较低的。
GET和POST请求方式的区别:
1、GET请求的数据会暴露在地址栏中,而POST请求则不会
GET请求,请求的数据会附加在URL之后,以?分割URL和传输数据,多个参数用&连接。URL的编码格式采用的是ASCII编码,而不是uniclde,即是说所有的非ASCII字符都要编码之后再传输。
POST请求:POST请求会把请求的数据放置在HTTP请求包的包体中。上面的item=bandsaw就是实际的传输数据。
2、传输数据的大小
在HTTP规范中,没有对URL的长度和传输的数据大小进行限制。但是在实际开发过程中,对于GET,特定的浏览器和服务器对URL的长度有限制。因此,在使用GET请求时,传输数据会受到URL长度的限制。
对于POST,由于不是URL传值,理论上是不会受限制的,但是实际上各个服务器会规定对POST提交数据大小进行限制,Apache、IIS都有各自的配置。
3、安全性
POST的安全性比GET的高。这里的安全是指真正的安全,而不同于上面GET提到的安全方法中的安全,上面提到的安全仅仅是不修改服务器的数据。比如,在进行登录操作,通过GET请求,用户名和密码都会暴露再URL上,因为登录页面有可能被浏览器缓存以及其他人查看浏览器的历史记录的原因,此时的用户名和密码就很容易被他人拿到了。除此之外,GET请求提交的数据还可能会造成Cross-site request frogery攻击
4、HTTP中的GET,POST,SOAP协议都是在HTTP上运行的
GET方式:
1、GET方式是以实体的方式得到由请求URL所指定资源的信息,如果请求URL只是一个数据产生过程,那么最终要在响应实体中返回的是处理过程的结果所指向的资源,而不是处理过程的描述。也就是说,GET得到的信息是资源,而不是资源的处理过程。
2、请求的数据会附加在URL之后,以?分隔URL和传输数据,多个参数用&连接。URL编码格式采用的是ASCII编码,而不是Unicode,即所有的非ASCII字符都要编码之后再传输。
3、因为URL的长度限制,GET方式传输的数据大小有所限制,传送的数据量不超过2KB。
4、GET方式服务器端用Request.QueryString获取变量的值。
5、GET方式传输的参数安全性低,因为传输的数据会显示在请求的URL中。
POST方式:
1、用来向目的服务器发出请求,要求它接收被附在请求后的实体,并把它当做请求队列中请求URL所指定资源的附加新子项。
2、POST方式将表单内各个字段和内容放置在HTML HEADER中一起传送到Action属性所指定的URL地址,用户是看不到这个过程的。
3、POST方式传送的数据量比较大,一般被默认为没有限制,但是根据IIS的配置,传输量也是不同的。
4、POST方式在服务器端用Request.Form获取提交的数据。
5、POST方式传输的数据安全性较高,因为数据传输不是明显显示的。
HTTPS(全称:Hypertext Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道,简单讲是HTTP的安全版。URL表明它使用了HTTP,但HTTPS存在不同于HTTP的默认端口及一个加密/身份验证层(在HTTP与TCP之间)。,HTTPS在HTTP的基础上加入了SSL协议,SSL依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信加密。HTTPS协议的主要作用可以分为两种:(1)确认通讯双方的身份,(2)建立安全通道,保证数据传输安全。
HTTPS和HTTP的区别主要如下:
1、https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。
2、http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
3、http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
4、http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。
SSL 协议既用到了公钥加密技术(非对称加密),又用到了对称加密技术。
Step 1:用公开密钥加密技术(通常为RSA)验证彼此身份(有时服务器不需要验证客户端身份),并协商Step2中通讯时所用的对称加密密钥;
Step 2:用对称密钥加密技术(如DES,或者RC4)加密服务器端和客户端通讯时的数据。
这样做的好处是:公开密钥加密相对复杂,速度慢,可用来完成安全性要求较高的身份认证、密钥协商等事务;对称密钥加密技术相对简单,速度快,可用来加密数据量大的传输内容。
HttpUrlConnection 与httpClient
在java中连接http,介绍两种方法,一种是java的HttpUrlConnection,另一种是apacha公司的httpClient,后者是第三方的类库需要从外部,导入,同时这也是第一次使用外部的类库,以后还会有很多需要导入外部类库的需求。
http协议是基于tcp的一种协议。
tcp是一种保证可靠连接的传输协议,通过三次握手,和丢失重传的机制保证数据的传输。
首先来看HttpUrlConnection
这个类是java自带的,直接import就行。
使用tcp连接的过程几乎都一样,http协议中有两种方式,一种是get方式,另一种是post提交,有些网页需要提交数据,所以要使用。
先看GET
首先需要一个url,这个url使用String建立
String path ="";//
URL url = new URL(path);
之后通过url对象打开连接
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
这里需要注意打开连接之后,这个函数返回的是不是httpUrlconnection类型而是 URLConnection类型,可以直接强转。
之后开始通过对conn对象进行设置连接的参数
conn.setRequestMethod("GET"); //设置本次请求的方式 , 默认是GET方式, 参数要求都是大写字母
conn.setConnectTimeout(5000);//设置连接超时
conn.setDoInput(true);//是否打开输入流 , 此方法默认为true
conn.setDoOutput(true);//是否打开输出流, 此方法默认为false
conn.connect();//表示连接
之后就开始判断是否连接成功,服务器会返回一个响应码,最常见的大概就是我们的404,不过除此之外还有很多,而成功连接返回的是200,也有一个静态的名称来代替HTTP_OK。
可以使用一个if判断:
int code = conn.getResponseCode(); // 获取服务器的响应代码。
String getResponseMessage(); // 获取服务器的响应消息。
String getResponseMethod(); // 获取发送请求的方法。
当我们确定连接成功之后,我们就需要打开服务器的输出流,然后从这个流里读取数据
InputStream is = conn.getInputStream();
String name = path.substring(path.lastIndexOf("/")+1);
System.out.println("name = " + name);
fos = new FileOutputStream("C:\\pro\\"+name);
byte[] buffer = new byte[1024];
int len = 0;
while ((len = is.read(buffer))!=-1) {
fos.write(buffer, 0, len);
这里通过getinputStream得到流,然后通过FileOutputStream流将文件写入到c盘。至此下载文件结束。
下面是post
与get相比,就是在设置请求方式的时候设置为POST,然后提交要提交的数据
OutputStream os = conn.getOutputStream();
os.write("platform=2&appVersion=1.7.0&osType=2".getBytes());
os.flush();
得到了服务器的输出流,然后写入数据,以&分隔。 除此之外,完全一样。
- HttpURLConnection对象不能直接构造,需要通过URL类中的openConnection()方法来获得。
- HttpURLConnection的connect()函数,实际上只是建立了一个与服务器的TCP连接,并没有实际发送HTTP请求。HTTP请求实际上直到我们获取服务器响应数据(如调用getInputStream()、getResponseCode()等方法)时才正式发送出去。
- 对HttpURLConnection对象的配置都需要在connect()方法执行之前完成。
- HttpURLConnection是基于HTTP协议的,其底层通过socket通信实现。如果不设置超时(timeout),在网络异常的情况下,可能会导致程序僵死而不继续往下执行。
- HTTP正文的内容是通过OutputStream流写入的, 向流中写入的数据不会立即发送到网络,而是存在于内存缓冲区中,待流关闭时,根据写入的内容生成HTTP正文。
- 调用getInputStream()方法时,返回一个输入流,用于从中读取服务器对于HTTP请求的返回信息。
- 我们可以使用HttpURLConnection.connect()方法手动的发送一个HTTP请求,但是如果要获取HTTP响应的时候,请求就会自动的发起,比如我们使用HttpURLConnection.getInputStream()方法的时候,所以完全没有必要调用connect()方法。
HttpClient
HttpClient就是一个增强版的HttpURLConnection- 创建HttpClient对象。
- 如果需要发送GET请求,创建HttpGet对象;如果需要发送POST请求,创建HttpPost对象。
- 如果需要发送请求参数,可调用HttpGet、HttpPost共同的setParams(HttpParams params)方法来添加请求参数;对于HttpPost对象而言,也可调用setEntity(HttpEntity entity)方法来设置请求参数。
- 调用HttpClient对象的execute(HttpUriRequest request)发送请求,执行该方法返回一个HttpResponse。
- 调用HttpResponse的getAllHeaders()、getHeaders(String name)等方法可获取服务器的响应头;调用HttpResponse的getEntity()方法可获取HttpEntity对象,该对象包装了服务器的响应内容。程序可通过该对象获取服务器的响应内容。
首先我们需要导入第三方的类库
第一部肯定是需要下载HttpClient的jar包。
得到像这样的3个jar包,然后再项目中新建一个libs的文件夹,将这三个jar包复制进去
选中这三个包,然后右键,点击Bulid Path就可以了
导入了包之后,就可以使用HttpClient类了
首先还是需要一个url
String path = "";
然后创建一个HttpClient对象
HttpClient client = new DefaultHttpClient();
之后创建一个GET请求对象
HttpGet httpGet = new HttpGet(path);
之后通过Client的execute函数来连接
HttpResponse response = client.execute(httpGet);
参数是get请求对象,返回的是一个httpresponse对象,这个对象,就是我们得到得结果,然后我们对这个response操作
同样,先判断一下响应码
response.getStatusLine().getStatusCode() == 200;
这里首先得到状态行,然后再得到里面的状态码。
我们通过这个Response可以得到一个实体HttpEntity。
HttpEntity entity = response.getEntity();
从这个实体中我们可以像上面一样得到一个流使用getContent(),不过,这个类为我们提供了更加简单的方法,在EntityUtils类中有toByteArray(entity),和toString(entity)方法,返回的分别是byte[],和string,对于byte数组,我们可以使用FileOutputStream来写入文件流中。
Post方式
和上面一样,只是多出了一些操作部分
HttpPost httpPost = new HttpPost(path);
//创建一个提交数据的容器
List<BasicNameValuePair> parames = new ArrayList<>();
parames.add(new BasicNameValuePair("platform", "2"));
parames.add(new BasicNameValuePair("appVersion", "1.7.0"));
parames.add(new BasicNameValuePair("osType", "2"));
//封装容器到请求参数中
HttpEntity entity = new UrlEncodedFormEntity(parames);
//设置请求参数到post请求中
httpPost.setEntity(entity);
//执行post请求
HttpResponse response = client.execute(httpPost);
这里的的类型变成了HttpPost,然后将post的参数加到容器里,然后将容器传给一个实体,将这个请求给post,之后执行。