一 HTTP简介
Hyper Text Transfer Protocol 超文本传输协议
定义了客户端和服务器通信时 发送数据的格式
二 HTTP特点
1. 基于TCP/IP的高级协议
2. 默认端口号80
3. 基于请求/响应模型 一次请求对应一次响应
4. 无状态的 每次请求之间相互独立 不能交互数据
三 请求消息数据格式
原始数据
POST /login.html HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Referer: http://localhost/login.html
Connection: keep-alive
Upgrade-Insecure-Requests: 1
username=zhangsan
1. 请求行
GET /login.html HTTP/1.1 -> 请求方式 请求url 请求协议/版本
HTTP协议有7种请求方式 常用的有2种
GET
a. 请求参数在请求行中 拼接在url后面
b. 请求的url长度有限制
c. 不太安全
POST
a. 请求参数在请求体中
b. 请求的url长度没有限制
c. 相对安全
2. 请求头
客户端告诉服务器一些信息 固定格式(请求头名称: 请求头值)
常见的请求头
a. User-Agent 当前使用的版本信息
b. Referer 当前请求从哪里来
3. 请求空行
空行 用于分割POST请求的请求头和请求体
4. 请求体(正文)
封装POST请求的请求参数
四 Request|Response执行原理
1. 服务器会根据请求url中的资源路径 创建对应的servlet对象
2. 服务器会创建request对象和response对象 request对象中封装请求消息数据
3. 服务器将request对象和response对象 传递给service() 并且调用service()
4. 程序员可以通过request对象获取请求消息数据 通过response对象设置响应消息数据
5. 服务器在给客户端做出响应之前 会从response对象中拿程序员设置的响应消息数据
五 Request功能
1. 获取请求消息数据
a. 获取请求行数据
请求行原始数据
GET /xxx/demo1?name=zhangsan HTTP/1.1
获取请求方式 String getMethod() -> GET
获取虚拟目录 String getContextPath() -> /xxx
获取servlet路径 String getServletPath() -> /demo1
获取get方式请求参数 String getQueryString() -> name=zhangsan
获取请求uri String getRequestURI() -> /xxx/demo1
获取请求url StringBuffer getRequestURL() -> http://localhost/xxx/demo1
获取协议及版本 String getProtocol() -> HTTP/1.1
获取客户端IP地址 String getRemoteAddr() -> 0:0:0:0:0:0:0:1
b. 获取请求头数据
获取所有请求头名称 Enumeration<String> getHeaderNames()
通过请求头名称获取请求头值 String getHeader(String name)
c. 获取请求体数据
请求体只有post方式请求才有 封装了请求参数
1> 获取流对象
BufferedReader getReader() -> 获取字符输入流 只能操作字符类型数据
ServletInputStream getInputStream() -> 获取字节输入流 可以操作所有类型数据
2> 从流对象中拿数据
2. 其他功能
a. 获取请求参数通用方式
get和post都可以使用下列方法来获取请求参数
通过参数名称获取参数值 String getParameter(String name)
通过参数名称获取参数值的数组 String[] getParameterValues(String name)
获取所有参数名称 Enumeration<String> getParameterNames()
获取所有参数名称和参数值的数组 Map<String, String[]> getParameterMap()
b. 请求转发
一种在服务器内部的资源跳转方式
特点
1> 浏览器地址栏路径不发生变化
2> 只能转发到当前服务器内部资源中
3> 转发是一次请求
步骤
ServletRequest#getRequestDispatcher(String path).forward(ServletRequest request, ServletResponse response)
c. 共享数据
域对象: 一个有作用范围的对象 可以在范围内共享数据
Request域: 代表一次请求的范围 一般用于请求转发的多个资源中共享数据
存储数据 void setAttribute(String name, Object obj)
通过键获取值 Object getAttribute(String name)
通过键移除值 void removeAttribute(String name)
d. 获取ServletContext
ServletContext getServletContext()
六 ServletContext
代表整个web应用 可以和程序的容器(服务器)来通信
1. 获取
a. 通过ServletRequest获取 ServletRequest#getServletContext()
b. 通过GenericServlet获取 GenericServlet#getServletContext()
2. 功能
a. 获取MIME类型
MIME类型: 在互联网通信过程中定义的一种文件数据类型 固定格式(大类型/小类型) 比如text/html image/jpeg
获取: String getMimeType(String file)
b. 共享数据
域对象: 一个有作用范围的对象 可以在范围内共享数据
ServletContext域: 代表整个web应用
存储数据 void setAttribute(String name, Object obj)
通过键获取值 Object getAttribute(String name)
通过键移除值 void removeAttribute(String name)
c. 获取文件在服务器上的真实路径
ServletContext#getRealPath("/b.txt") -> web目录下资源访问
ServletContext#getRealPath("/WEB-INF/c.txt") -> WEB-INF目录下资源访问
ServletContext#getRealPath("/WEB-INF/classes/a.txt") -> src目录下资源访问
七 响应消息数据格式
原始数据
HTTP/1.1 200 OK Content-Type: text/html;charset=UTF-8 Content-Length: 101 Date: Wed, 06 Jun 2018 07:08:42 GMT <html> <head> <title>$Title$</title> </head> <body> hello response </body> </html>
1. 响应行
HTTP/1.1 200 OK -> 响应协议/版本 响应状态码 响应状态码描述
响应状态码: 服务器告诉客户端本次请求和响应的一个状态 状态码都是3位数字
1xx 服务器接收客户端消息 但没有接收完成 等待一段时间后 发送1xx状态码
2xx 成功 比如200
3xx 重定向 比如重定向302 访问缓存304
4xx 客户端错误 比如请求路径没有对应的资源404 请求方式没有对应的doXxx方法405
5xx 服务器端错误 比如服务器内部出现异常500
2. 响应头
服务器告诉客户端一些信息 固定格式(响应头名称: 响应头值)
常见的响应头
a. Content-Type 服务器告诉客户端本次响应体数据格式以及编码格式
b. Content-Disposition 服务器告诉客户端以什么格式打开响应体数据
in-line 默认值 在当前页面内打开
attachment;filename=xxx 以附件形式打开响应体(文件下载)
3. 响应空行
空行 用于分割响应头和响应体
4. 响应体
传输的数据
八 Response功能
1. 设置响应消息数据
a. 设置响应行数据
设置状态码 void setStatus(int code)
b. 设置响应头数据
设置响应头 void setHeader(String name, String value)
c. 设置响应体数据
1> 获取流对象
PrintWriter getWriter() -> 获取字符输出流 只能操作字符类型数据
ServletOutputStream getOutputStream() -> 获取字节输出流 可以操作所有类型数据
2> 使用输出流 将数据输出到客户端
2. 其他功能
a. 重定向
资源跳转方式
特点
1> 浏览器地址栏路径发生变化
2> 可以访问其他服务器资源
3> 重定向是两次请求
步骤
HttpServletResponse#sendRedirect(String path)
九 中文乱码
1. 请求参数
get -> tomcat8已经将乱码问题解决了
post -> 需要在获取参数之前 设置request的编码 ServletRequest#setCharacterEncoding("utf-8")
2. 响应数据
需要在获取流之前 设置response的编码 ServletResponse#setContentType("text/html;charset=utf-8")