- 定义:(Hyper Test Transfer Protocol) 超文本传输协议
- 传输协议:定义了客户端和服务器端通信时发送数据的格式。
- 历史版本:
- 版本1.0:每次请求响应都会建立新的连接。
- 版本1.1:复用连接。
- 特点:
- 基于TCP/IP的高级协议;
- 默认端口号:80;
- 基于请求/响应模型,即一次请求对应一次响应;
- 无状态的:每次请求之间相互独立,不能交互数据。
- HTTP请求消息数据格式:
- 请求行:请求方式 url 协议/版本,例:GET /login.html HTTP/1.1
- 请求方式:
- GET:
- 请求参数在请求行中,在url后面。
- 请求的url长度有限
- 不太安全
- POST:
- 请求参数在请求体中
- 请求的url长度没有限制
- 相对安全
- GET:
- 请求方式:
- 请求头:请求头名称:请求头值(键值对格式)
- Host:请求的主机
- User-Agent:浏览器的版本信息,服务器端获取该信息后可以解决浏览器兼容问题。
- Referer:告诉服务器当前请求从哪里来,作用1,防止盗取链接。作用2,统计工作。
- 请求空行:空行,用来分隔请求头与请求体
- 请求体(正文):封装POST请求消息的请求参数(POST请求有,GET请求没有)
Request:客户端发送给服务器的消息
- request对象和response对象原理
- request和response对象是由服务器创建。
- request对象是来获取请求消息,response对象是来设置响应消息。
- request对象继承体系结构:
- ServletRequest---接口
- HttpServletRequest---接口(继承ServletRequest接口)
- org.apache.catalina.connector.TequestFacde---实现类
- request功能:获取请求消息
- 获取请求消息数据
- 获取请求行数据(例:GET /king/test?nema=zhangsan HTTP/1.1)
- 获取请求方法:String getMethod(),GET
- 获取虚拟目录:String getContextPath(),/king
- 获取Servlet路径:String getServletPath(),/test
- 获取get方法请求参数:String getQueryString(),nema=zhangsan
- 获取请求URI(统一资源标识符):String getRequestURI(),/king/test
- 获取请求URL(统一资源定位符):String getRequestURL(),http://localhost/king/test
- 获取协议及版本:String getProtocol(),HTTP/1.1
- 获取客户机的IP地址:String getRemoteAddr()
- 获取请求头数据
- String getHeader(String name):根据请求头的名称获取请求头的值。
- Enumeration<String> getHeaderNames():获取所有请求头名称。
- 获取请求体数据(POST方法才有)
- 获取流对象
- BufferReader getReader():获取字符输入流,只能操作字符数据。
- ServletInputStream getInputStream():获取字节输入流,可以操作所有类型数据。
- 从流对象中取数据
- 获取流对象
- 获取请求行数据(例:GET /king/test?nema=zhangsan HTTP/1.1)
- 其他功能:
- 获取请求参数通用方式
- String getParameter(String name):根据参数名称获取参数值
- Sting[] getParameterValues(String name):根据参数名称获取参数值的数组(多用于复选框情况)
- Enumeration<String> getParameterNames():获取所有请求的参数名称
- Map<String,String[]> getParameterMap():获取所有参数的map集合
- 注意中文乱码问题:
- get方式:tomcat8已将get方式乱码问题解决
- post方式:需要在获取参数前,设置request编码方式request.setCharacterEncoding("utf-8");
- 请求转发:一种在服务器内部资源跳转的方式。
- 转发步骤:
- 通过request对象获取请求转发器对象RequestDispatcher getRequestDispatcher(string path)
- 使用RequestDispatcher对象进行转发forward(ServletRequest request, ServletResponse response)
- 特点:
- 浏览器地址栏路径不发生变化。
- 只能转发到当前服务器内部资源中。
- 转发是一次请求。
- 转发步骤:
- 共享数据
- 域对象:一个有作用范围的对象,可以在范围内共享数据。
- request域代表一次请求的范围,一般用于请求转发的多个资源中共享数据。
- 方法:
- void setAttribute(String name, Object obj) 存储数据
- Object getAttribute(String name) 通过键获取值
- void removeAttribute(String name) 通过键删除键值对
- 获取ServletContext
- 获取请求参数通用方式
- 获取请求消息数据
Response:服务器端发送给客户端的消息
数据格式:
1.响应行:HTTP/1.1 200 OK
1.组成:协议/版本 响应状态码 状态码描述
2.响应的状态码:服务器告诉客户端浏览器这次请求响应的一个状态。
1.状态码都是三位数字;
2.分类:
1.1XX:服务器接收客户端的消息,但是还没有接收完成,等待一段时候后,服务器向浏览器发送一个1XX的状态码。
2.2XX:成功
3.3XX:重定向,
典型代表:
302:重定向
304:访问缓存
4.4XX:客户端错误。
典型代表:
404:表示请求路径没有对应的资源
405:表示请求方式没有对应的方法
5.5XX:服务器端错误。
典型代表:
500:服务器内部出现异常;502 Bad Gateway是指错误网关,无效网关
2.响应头
格式:键值对(名称:值)
常见的响应头:
1.Content-Type:服务器告诉客户端本次响应体数据格式以及编码格式。
2.Content-disposition:服务器告诉客户端以什么格式打开响应体数据。
in-line:默认值,在当前页面内打开。
attachment:以附件形式打开,如文件下载。
3.响应空行
4.响应体:传输的数据。
Response对象:
功能:设置响应消息。
1.设置响应行;
1.格式:HTTP/1.1 200 OK
2.设置状态码;setStatus(int sc)
2.设置响应头:setHeader(String name, String value)
3.设置响应体:
使用步骤:
1.获取输出流;
*字符输出流:PrintWriter getWriter()
*字节输出流:ServletOutPutStream getOutPutStream()
2.使用输出流,将数据输出到客户端浏览器中。
案例:
1.重定向:资源跳转的方式
实现:response.sendRedirect("目标url")
重定向的特点:redirect
1.地址栏路径发生改变
2.重定向可以访问其他服务器的资源
3.重定向是两次请求。不能使用request对象来共享数据了
转发的特点:forward
1.转发地址栏路径不变
2.转发只能访问当前服务器下的资源
3.转发是一次请求
注:面试中常问到redirect和forward的区别
路径的写法:
路径分类:
1.相对路径:通过相对路径不可以确定唯一资源
* 如:./index.xml
* 不以/开头的,以.开头的路径
* 规则:判断当前资源和目标资源的相对位置关系。
./:代表当前路径
../:代表后退一级目录
2.绝对路径:通过绝对路径可以确定唯一资源。
* 如:http://localhost/servlet/demo1 /servlet/demo1
* 以/开头的为绝对路径
* 规则:判断定义的路径是给谁用的?判断请求将来从哪发出
1.给客户端浏览器使用:需要加虚拟目录(项目的访问路径)
重定向
建议虚拟目录动态获取,动态获取虚拟目录: String contextPath = request.getContextPath();
2.给服务器使用:不需要加虚拟目录
转发
2.服务器输出字符数据到浏览器
步骤:
1.获取字符输出流:
PrintWriter pw = response.getWriter();
2.输出数据
pw.write("hello");
注:可能存在中文乱码问题,如果出现乱码,那么一定是编解码使用的字符集不一致导致
解决方法:在获取流对象之前设置流编码,默认为ISO-8899-1
-1.设置流编码
response.setCharacterEncoding("GBK");//想要的编码格式,这里仅作举例。
0.告诉浏览器使用特定的编码格式
response.setHeader("content-type","text/html;charset=utf-8");
-1和0可以简写为:response.setContentType("text/html;charset=utf-8");
3.服务器输出字节数据到浏览器
步骤:
1.获取字节输出流
ServletOutPutStream sos = response.getOutPutStream();
2.输出数据
sos.write("hello".getBytes());
注:同样会出现中文乱码问题,解决方法同上。
4.验证码
1.本质:图片
2.目的:防止恶意表单注册