**1. HTTP协议的定义**
WWW是以Internet作为传输媒介的一个应用系统,WWW网上基本的传输单位是Web网页。WWW的工作是基于客户机/服务器计算模型,由Web浏览器和Web服务器构成,即B/S结构,两者之间采用超文本传输协议HTTP进行通信。
HTTP协议是基于TCP/IP协议之上的协议,是Web浏览器和Web服务器之间的应用层的协议,是通用的、无状态的面向对象的协议。
如果要实现网络互联我们要思考两个需要解决的技术问题:
第一:浏览器和服务器是通过什么来连接的。
第二:这种连接方式是怎么实现的。
通过Internet去发送到服务器当中,而Internet内部可以通过三种方式来实现发送信息和数据:
第一种:HTTP协议,也是在工作中最常用的,是建立在TCP/IP基础上实现的。
第二种:FTP协议
第三种:TCP/IP协议,它也是最底层的协议,其它的方式必须是要通过它,但是要想实现这种协议必须要实现socket编程,这种方法是用来上传一些比较大的文件,视频,进行断点续传的操作。
**2. HTTP协议实例剖析**
客户端连接服务器实现内部的原理如下:
![](https://box.kancloud.cn/0ac6075a44733bd9a6319164487d915e_614x246.jpg)
流程分析:
第一步:在浏览器客户端中得到用户输入的内容。
第二步:浏览器得到这个网址之后,内部会将这个域名发送到DNS上,进行域名解析。得到它的IP之后就会链接到指定的服务器上,假如服务器的地址是:221.104.13.32:80,从浏览器到服务器端口它使用到最底层的TCP/IP协议
第三步:实现TCP/IP协议用Socket来完成,使用了Socket的套接字。
第四步:服务器端的80端口监听客户端的链接,这样客户端到服务器就链接上了。
**HTTP请求体的内容介绍**
![](https://box.kancloud.cn/f8ade65ac4c8cfab92c7d21591699b8b_521x260.jpg)
~~~
1. <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
2. <%String path = request.getContextPath();%>
3. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
4. <html>
5. <head>
6. <title>测试HTTP协议体的内容</title>
7. <meta http-equiv="pragma" content="no-cache">
8. <meta http-equiv="cache-control" content="no-cache">
9. <meta http-equiv="expires" content="0">
10. <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
11. <meta http-equiv="description" content="This is my page">
12. <!-- <link rel="stylesheet" type="text/css" href="styles.css"> -->
13. </head>
14. <body>
15. <form name="form1" method="post" action="<%=path %>/LonginServlet">
16. 用户名:
17. <input type="text" name="username" value="admin" /><br />
18. 密 码:
19. <input type="password" name="password" value="123" /><br />
20. <input type="submit" name="submit" value="提交表单" />
21. </form>
22. </body>
23. </html>
~~~
~~~
1. <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
2. <%String path = request.getContextPath();%>
3. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
4. <html>
5. <head>
6. <title>测试HTTP协议体的内容</title>
7. <meta http-equiv="pragma" content="no-cache">
8. <meta http-equiv="cache-control" content="no-cache">
9. <meta http-equiv="expires" content="0">
10. <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
11. <meta http-equiv="description" content="This is my page">
12. <!-- <link rel="stylesheet" type="text/css" href="styles.css"> -->
13. </head>
14. <body>
15. <form name="form1" method="post" action="<%=path %>/LonginServlet">
16. 用户名:
17. <input type="text" name="username" value="admin" /><br />
18. 密 码:
19. <input type="password" name="password" value="123" /><br />
20. <input type="submit" name="submit" value="提交表单" />
21. </form>
22. </body>
23. </html>
~~~
`<form name="form1" method="post" action="<%=path %>/LonginServlet">` 表单中方法为 post, 所以提交后会跳转到 "<%=path %>/LonginServlet",转换一下是:http://192.168.1.105:8080/MyHTTP/LonginServlet; 并调用 LonginServlet.java 的 doPost()方法.
**HTTP响应的内容介绍**
![](https://box.kancloud.cn/c77367c45352fc6c8f12a5a6ef1365bf_516x262.jpg)
可以用 **HTTPWatch** 工具查一下,这个操作的过程, HTTPWatch 是IE 的一个插件,安装后,用IE浏览器打开,查看---> 浏览栏 就可以看到这个HTTPWatch .
![](https://box.kancloud.cn/e93d84cfa359f24b112389597accfebf_836x271.jpg)
在这里面可以测试到响应时间,结果,头部信息等信息.
在这里面有个 Cookies: JSESSIONIDSent
5444476F20784E44DECCC2900186336D
当用户登录时,点击登录按钮后,可能等的时间比较长,就多点了几次,这样就多次登录了. 服务器怎么判断是哪个用户呢? 所有在HTTP的协议体当中要把Cookies的JSESSIONID返回给客户端,客户端就知道是哪个用户登录了.
**HTTP返回请求数据的三种方式**
服务器接收到这些内容之后,并按照这些请求的路径找到对应的页面,进一步找到对应的网页内容,返回给客户端。
服务器返回客户端的内容有三种方式:
1、以HTML代码内容返回。
2、以XML字符串的形式返回,在以后的android开发中这种形式返回数据比较多。
3、以JSON对象形式返回,在网络流量上考虑JSON要比XML方式要好一些,便于解析
### POST和GET提交数据
**1. POST和GET方式的定义**
1. HTTP-GET和HTTP-POST是使用HTTP的标准协议动词,用于编码和传送变量名/变量值对参数,并且使用相关的请求语义。
2. 每个HTTP-GET和HTTP-POST都由一系列HTTP请求头组成,这些请求头定义了客户端从服务器请求了什么,而响应则是由一系列HTTP请求数据和响应数据组成,如果请求成功则返回响应的数据。
3. HTTP-GET以使用MIME类型application/x-www-form-urlencoded的urlencoded文本的格式传递参数。Urlencoding是一种字符编码,保证被传送的参数由遵循规范的文本组成,例如一个空格的编码是"%20"。附加参数还能被认为是一个查询字符串。
4. 与HTTP-GET类似,HTTP-POST参数也是被URL编码的。然而,变量名/变量值不作为URL的一部分被传送,而是放在实际的HTTP请求消息内部被传送。
**2. GET和POST之间的主要区别**
* 1、GET是从服务器上获取数据,POST是向服务器传送数据。
* 2、在客户端, GET方式在通过URL提交数据,数据在URL中可以看到;POST方式,数据放置在HTML HEADER内提交
* 3、对于GET方式,服务器端用Request.QueryString获取变量的值,对于POST方式,服务器端用Request.Form获取提交的数据。
* 4、GET方式提交的数据最多只能有1024字节,而POST则没有此限制
* 5、安全性问题。正如在(2)中提到,使用 GET 的时候,参数会显示在地址栏上,而 POST 不会。所以,如果这些数据是中文数据而且是非敏感数据,那么使用 GET ;如果用户输入的数据不是中文字符而且包含敏感数据,那么还是使用 POST为好
**3. URL的定义和组成**
Uniform Resource Locator 统一资源定位符
URL的组成部分:http://www.mbalib.com/china/index.htm
http://:代表超文本传输协议
www:代表一个万维网服务器
mbalib.com/:服务器的域名,或服务器名称
China/:子目录,类似于我们的文件夹
Index.htm:是文件夹中的一个文件
/china/index.htm统称为URL路径
**4. Java中HTTP编程接口**
Java中进行HTTP编程有如下的两种方式:
标准的Java接口
标准Apache接口
**示例1: HTTP协议,Get方式从服务器获得一张图片,采用标准的Java接口**
1. 建立Java Project.
2. 工程目录下新建目录/libs,把工具包拷贝到该目录下,选中包右键--->Build path--->Add to build path.
3. /src下新建一个包com.http.get,包下新建一个类文件 HttpUtils.java.
~~~
1. public class HttpUtils {
2. private static String URL_PATH = "http://192.168.1.105:8080/MyHTTP/pro1.png";
3. public HttpUtils() {
4. }
5. //从服务器得到流之后写到本地磁盘
6. public static void saveImageToDisk() {
7. InputStream inputStream = getInputStream(); //从服务器读到输入流
8. byte[] data = new byte[1024];
9. int len = 0;
10. FileOutputStream fileOutputStream = null;
11. try {
12. fileOutputStream = new FileOutputStream("C:\\test.png");
13. //从输入流中读取数据的下一个字节。
14. while ((len = inputStream.read(data)) != -1) {
15. fileOutputStream.write(data, 0, len);
16. }
17. } catch (IOException e) {
18. // TODO Auto-generated catch block
19. e.printStackTrace();
20. } finally {
21. if (inputStream != null) {
22. try {
23. inputStream.close();
24. } catch (IOException e) {
25. // TODO Auto-generated catch block
26. e.printStackTrace();
27. }
28. }
29. if (fileOutputStream != null) {
30. try {
31. fileOutputStream.close();
32. } catch (IOException e) {
33. // TODO Auto-generated catch block
34. e.printStackTrace();
35. }
36. }
37. }
38. }
39.
40. /**
41. * 获得服务器端的数据,以InputStream形式返回
42. * @return
43. */
44. public static InputStream getInputStream() {
45. InputStream inputStream = null;
46. HttpURLConnection httpURLConnection = null;
47. try {
48. URL url = new URL(URL_PATH);
49. if (url != null) {
50. //这个类就是客户端与服务器建立连接的一个类
51. httpURLConnection = (HttpURLConnection) url.openConnection();
52. // 设置连接网络的超时时间
53. httpURLConnection.setConnectTimeout(3000);
54. httpURLConnection.setDoInput(true); //从服务器取回数据
55. // 表示设置本次http请求使用GET方式请求
56. httpURLConnection.setRequestMethod("GET");
57. //从 HTTP 响应消息获取状态码
58. int responseCode = httpURLConnection.getResponseCode();
59. if (responseCode == 200) {
60. // 从服务器获得一个输入流
61. inputStream = httpURLConnection.getInputStream();
62. }
63. }
64. } catch (MalformedURLException e) {
65. // TODO Auto-generated catch block
66. e.printStackTrace();
67. } catch (IOException e) {
68. // TODO Auto-generated catch block
69. e.printStackTrace();
70. }
71. return inputStream;
72. }
73. public static void main(String[] args) {
74. // 从服务器获得图片保存到本地
75. saveImageToDisk();
76. }
77. }
~~~
~~~
1. public class HttpUtils {
2. private static String URL_PATH = "http://192.168.1.105:8080/MyHTTP/pro1.png";
3. public HttpUtils() {
4. }
5. //从服务器得到流之后写到本地磁盘
6. public static void saveImageToDisk() {
7. InputStream inputStream = getInputStream(); //从服务器读到输入流
8. byte[] data = new byte[1024];
9. int len = 0;
10. FileOutputStream fileOutputStream = null;
11. try {
12. fileOutputStream = new FileOutputStream("C:\\test.png");
13. //从输入流中读取数据的下一个字节。
14. while ((len = inputStream.read(data)) != -1) {
15. fileOutputStream.write(data, 0, len);
16. }
17. } catch (IOException e) {
18. // TODO Auto-generated catch block
19. e.printStackTrace();
20. } finally {
21. if (inputStream != null) {
22. try {
23. inputStream.close();
24. } catch (IOException e) {
25. // TODO Auto-generated catch block
26. e.printStackTrace();
27. }
28. }
29. if (fileOutputStream != null) {
30. try {
31. fileOutputStream.close();
32. } catch (IOException e) {
33. // TODO Auto-generated catch block
34. e.printStackTrace();
35. }
36. }
37. }
38. }
39.
40. /**
41. * 获得服务器端的数据,以InputStream形式返回
42. * @return
43. */
44. public static InputStream getInputStream() {
45. InputStream inputStream = null;
46. HttpURLConnection httpURLConnection = null;
47. try {
48. URL url = new URL(URL_PATH);
49. if (url != null) {
50. //这个类就是客户端与服务器建立连接的一个类
51. httpURLConnection = (HttpURLConnection) url.openConnection();
52. // 设置连接网络的超时时间
53. httpURLConnection.setConnectTimeout(3000);
54. httpURLConnection.setDoInput(true); //从服务器取回数据
55. // 表示设置本次http请求使用GET方式请求
56. httpURLConnection.setRequestMethod("GET");
57. //从 HTTP 响应消息获取状态码
58. int responseCode = httpURLConnection.getResponseCode();
59. if (responseCode == 200) {
60. // 从服务器获得一个输入流
61. inputStream = httpURLConnection.getInputStream();
62. }
63. }
64. } catch (MalformedURLException e) {
65. // TODO Auto-generated catch block
66. e.printStackTrace();
67. } catch (IOException e) {
68. // TODO Auto-generated catch block
69. e.printStackTrace();
70. }
71. return inputStream;
72. }
73. public static void main(String[] args) {
74. // 从服务器获得图片保存到本地
75. saveImageToDisk();
76. }
77. }
~~~
4. 把pro1.png图片放在MyHTTP web工程目录下,启动服务器.
5. 运行这个Java工程,rus as--->Java Project.
然后就可这个 pro1.png 图片下载到D:\test.png.
**期间,遇到一个错误,工程目录上有个大大的红色惊叹号**。
后来找到原因是导入了多余的包,解决方法有两种:
(1) library里导入了多余的包,删除后就可以了
(2) 把java build path里面的libraries全部remove掉,再重新add进去就行了
你现在打开MyEclipse 右键单击你的web工程,找到 Build Path > Configure Build Paht... > 然后上面有几个选项卡找到 Libraries。 这里看到的就是你工程里面引用的 所有的 jar , 看看是不是在某个jar图标上有个很小的黄色的感叹号? 如果有的话就没错了, 先选中这个jar, 点击右边的 Remove > 点击OK 等待几秒,现在web工程上面的红色XX是不是没有了。