超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议。所有的WWW文件都必须遵守这个标准。
HTTP协议(HyperText Transfer Protocol,超文本传输协议)是用于从WWW服务器传输超文本到本地浏览器的传输协议。它可以使浏览器更加高效,使网络传输减少。它不仅保证计算机正确快速地传输超文本文档,还确定传输文档中的哪一部分,以及哪部分内容首先显示(如文本先于图形)等。
HTTP是客户端浏览器或其他程序与Web服务器之间的应用层通信协议。在Internet上的Web服务器上存放的都是超文本信息,客户机需要通过HTTP协议传输所要访问的超文本信息。HTTP包含命令和传输信息,不仅可用于Web访问,也可以用于其他因特网/内联网应用系统之间的通信,从而实现各类应用资源超媒体访问的集成。
解释1
所谓长连接指建立SOCKET连接后不管是否使用都保持连接,但安全性较差,
所谓短连接指建立SOCKET连接后发送后接收完数据后马上断开连接,一般银行都使用短连接
解释2
长连接就是指在基于tcp的通讯中,一直保持连接,不管当前是否发送或者接收数据。
而短连接就是只有在有数据传输的时候才进行连接,客户-服务器通信/传输数据完毕就关闭连接。
解释3
长连接和短连接这个概念好像只有移动的CMPP协议中提到了,其他的地方没有看到过。
通信方式
各网元之间共有两种连接方式:长连接和短连接。所谓长连接,指在一个TCP连接上可以连续发送多个数据包,在TCP连接保持期间,如果没有数据包发送,需要双方发检测包以维持此连接。短连接是指通信双方有数据交互时,就建立一个TCP连接,数据发送完成后,则断开此TCP连接,即每次TCP连接只完成一对 CMPP消息的发送。
现阶段,要求ISMG之间必须采用长连接的通信方式,建议SP与ISMG之间采用长连接的通信方式。
解释4
短连接:比如http的,只是连接、请求、关闭,过程时间较短,服务器若是一段时间内没有收到请求即可关闭连接。
长连接:有些服务需要长时间连接到服务器,比如CMPP,一般需要自己做在线维持。
参考文章:http://blog.csdn.net/shine0181/article/details/7799754
GET /q547550831?viewmode=contents HTTP/1.1 [请求行]
Host: blog.csdn.net [消息头] 消息名:内容
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36
Referer: http://blog.csdn.net/q547550831?viewmode=contents
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8
PS:这是我博客主页的请求头,但是这并不代表每个网页的请求头都是这一样的。
请求方式有:
POST,GET,HEAD,OPTIONS,DELETE,TRACE,PUT,CONNECT等
参考文档:http://tools.jb51.net/table/http_request_method
常用的有:POST和GET
Host: blog.csdn.net [主机名]
Connection: keep-alive [连接状态:保持连接]
Cache-Control: max-age=0 [指定请求和响应遵循的缓存机制:查看是否有修改并选择更新否]
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 [可接受的格式]
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36 [浏览器内核]
Referer: http://blog.csdn.net/q547550831?viewmode=contents [从哪个网页跳转到这个网页来的,可以用来防盗链]
Accept-Encoding: gzip, deflate, sdch [可接收的压缩格式]
Accept-Language: zh-CN,zh;q=0.8 [浏览器支持的语言]
PS:请求是指浏览器发出向服务器发出,所以这些信息都是浏览器的信息。请求头远远不止这几种,可以参考该文档:http://tools.jb51.net/table/http_header
案例:防止盗链
package com.pc; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class Servlet6 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); response.setCharacterEncoding("utf-8"); PrintWriter out = response.getWriter(); out.println("<a href='http://127.0.0.1:8080/servlet1/Servlet5'>连接到Servlet5</a>"); out.flush(); out.close(); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); } }
package com.pc; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class Servlet5 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); response.setCharacterEncoding("utf-8"); PrintWriter out = response.getWriter(); // 通过request对象来获取http请求信息 // 取出Host String host = request.getHeader("Host"); out.println("host=" + host); // 限制用户 // 获取用户浏览器的Referer // referer可以防止盗链,通过判断链接来至哪里 String referer = request.getHeader("Referer"); if(referer == null || !referer.startsWith("http://127.0.0.1:8080/servlet1")){ out.println("非法盗链"); } else { out.println("referer=" + referer); } out.flush(); out.close(); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 一般开发人员习惯把doGet()和doPost()合二为一 this.doGet(request, response); } public void init() throws ServletException { // Put your code here } }
PS:该案例中只能允许http://127.0.0.1:8080/servlet1开头的网址进行访问Servlet5
HTTP/1.1 200 OK [状态行]
Server: openresty [消息名] 消息名:内容
Date: Fri, 01 Jan 2016 08:11:04 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
Cache-Control: private
Set-Cookie: uuid=5cad65d6-7a99-4b15-a6e6-5c50e584ca77; expires=Sat, 02-Jan-2016 08:13:49 GMT; path=/
Set-Cookie: ViewMode=contents; path=/
Content-Encoding: gzip
--------------这是一个空行
消息体
响应状态码分别为1,2,3,4,5开头的三位数字
1** |
信息,服务器收到请求,需要请求者继续执行操作 |
2** |
成功,操作被成功接收并处理 |
3** |
重定向,需要进一步的操作以完成请求 |
4** |
客户端错误,请求包含语法错误或无法完成请求 |
5** |
服务器错误,服务器在处理请求的过程中发生了错误 |
PS:常见的有200(成功),303(重定向),400(Not Found),500(服务器内部错误)
可以参考该文档:http://tools.jb51.net/table/http_status_code
Server: openresty [服务器名称]
Date: Fri, 01 Jan 2016 08:11:04 GMT [原始服务器消息发出的时间]
Content-Type: text/html; charset=utf-8 [返回内容的MIME类型]
Transfer-Encoding: chunked [文件传输编码]
Connection: keep-alive [连接状态:保持连接]
Vary: Accept-Encoding [告诉下游代理是使用缓存响应还是从原始服务器请求]
Cache-Control: private [告诉所有的缓存机制是否可以缓存及哪种类型]
Set-Cookie: uuid=********; expires=Sat, 02-Jan-2016 08:13:49 GMT; path=/ [设置Http Cookie]
Set-Cookie: ViewMode=contents; path=/ [设置Http Cookie]
Content-Encoding: gzip [web服务器支持的返回内容压缩编码类型]
PS:可以参考该文档http://tools.jb51.net/table/http_header
浏览器默认情况下,会缓存所访问的页面,这样会出现一个问题:如果用户习惯把光标停留在地址栏,然后回车来取页面,就会默认调用cache中取数据。
案例1、有些网站要求及时性很高,因此要求不缓存页面。
//指定该页面不缓存 Ie
response.setDateHeader("Expires", -1);【针对IE浏览器设置不缓存】
//为了保证兼容性.
response.setHeader("Cache-Control", "no-cache");【针对火狐浏览器等】
response.setHeader("Pragma", "no-cache");【其他浏览器】
案例2、有些网站要求网页缓存一定时间,比如缓存一个小时
response.setDateHeader("Expires", System.currentTimeMillis()+3600*1000); //后面一个参数表示设置的缓存保持时间,-1表示永远不缓存
Content-Type,内容类型,一般是指网页中存在的Content-Type,用于定义网络文件的类型和网页的编码,决定浏览器将以什么形式、什么编码读取这个文件
PS:其作用就是告诉浏览器,该服务器返回的网页中消息体是什么格式的,该以什么编码格式来读取这个网页。
因为该类型很多,故给出参考文档,以备后用:http://tools.jb51.net/table/http_content_type
案例1:定时刷新Refresh的使用
response.setHeader("Refresh", "5;url=/servletPro/Servlet2"); // 5秒后刷新并跳转到url后的链接。通过这个可以实现页面定时刷新。
案例2:文件下载
package com.pc; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class Servlet7 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); response.setCharacterEncoding("utf-8"); // 演示下载文件 response.setHeader("Content-Disposition", "attachment; filename=EVO_120G.jpg"); // 打开文件 // 1.获取到要下载文件的全路径 String path = this.getServletContext().getRealPath("/EVO_120G.jpg"); // 测试 System.out.println("path=" + path); // 2.创建文件输入流 FileInputStream fis = new FileInputStream(new File(path)); // 做一个缓冲字符数组 byte buff[] = new byte[1024]; int length = 0; // 3.指向response的输出流 OutputStream os = response.getOutputStream(); // 4.循环读出 // length表示每次实际读入的字节数 while((length = fis.read(buff)) != -1){ os.write(buff, 0, length); } // 关闭 os.close(); fis.close(); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); } }
----------参考《韩顺平.细说Servlet》