HTTP
概念:
Hyper Text Transfer Protocol 超文本传输协议
传输对象:客户端,服务器端
传输协议:客户端与服务器端通讯时,发送数据的格式
特点:
1.基于TCP/IP的高级协议
2.默认端口号为:80
3.基于请求/响应模型:一次请求对应一次响应
4.无状态:每次请求之间相互独立,不能交互数据
请求消息数据格式
-
请求行
请求方式 请求url 请求协议/版本
GET /login.html HTTP/1.1 -
请求方式:
HTTP协议中有七种请求方式
GET:
1. 请求参数在请求行中,在url后
2. 请求的url长度有限制
3. 不太安全
POST:
1. 请求参数在请求体中
2. 请求的url长度没有限制
3. 相对安全 -
请求头:客户端浏览器告诉服务器一些信息
(键值对格式)
请求头名称:请求头值
常见请求头:
1. User-Agent:浏览器告知服务器,该浏览器的版本信息,在服务器端获取头信息,解决浏览器兼容性问题
2. Referer:http://localhost/login.html
告诉服务器,我从哪里来
作用:
1. 防盗链
2. 统计工作 -
请求空行
空行,就是用于分割POST请求的请求头 -
请求体(正文)
封装POST请求消息的请求参数
请求字符串格式
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 请求体
响应消息数据格式
Request:
-Request对象与Response对象
1.由服务器创建,交由程序员使用
2.request对象,是获取请求消息,response设置响应消息
requestfacade类(具体实现类) extends HttpServletRequest extends ServelRequest
http://localhost:8080/examples/composite.jsp过程:
1.在端口8080启动Server,并通知Service完成启动,Service通知connector完成初始化和启动的过程
2.Connector首先收到这个请求,会调用ProtocolHandler完成http协议的解析,交给SocketProcessor处理,解析请求头,交给CoyoteAdapter解析请求行和请求体,并把解析信息封装到Request和Response对象中
3.把请求交给Container容器
4.Container容器交给其子容器--Engine容器,并等待Engine容器的处理结果
5.Engine容器匹配所有虚拟主机,匹配到host
6.请求移交给hosthome的Host容器,host匹配其所有子容器Context,contexPath对应的/examples的Context容器,匹配不到时,将请求路径名设为" ",并交由Context去处理
7.请求再次被提交移交给Context容器,Context继续匹配其子容器Wrapper,Wrapper容器加载composite.jsp对应的servlet,这里编译的servlet对应于_jsp.class文件
8.Context容器根据后缀匹配原则*.jsp,找到composite.jsp编译java类的class文件
9.Connector构建一个org.apache.catalina.connector.Request以及org.apache.catalina.connecotor.Response对象,使用反射调用serclet的service方法
10.Context容器将封装了响应消息的Response对象返回Host容器
11.Host容器把Response返回Engine容器
12.Engine容器将Response返回Connector
13.Connector容器将Response返回浏览器
14.浏览器解析,显示响应报文
- Request功能
- 获取请求消息数据
获取请求行数据
GET /day14/demo1?name=zhangsan HTTP/1.1
方法:
1. 获取请求方式:GET
String getMethod()
2. 获取虚拟目录
String getContextPath()
3. 获取Servlet路径
String getServletPath()
4. 获取get方式请求参数:name=zhangsan
String getQuaryString()
5. 获取请求URI
String getRequestURI()
StringBuffer getRequestURL()
URL:统一资源定位符
URI:统一资源标识符
6. 获取协议及版本
String getProtocol()
7. 获取客户机IP地址
String getRemoteAddr() - 获取请求头数据
方法:
String getHeader(String name):通过请求头的名称获取请求头的值
Enumeration getHeaderNames():获取所有的请求头名称
获取请求体数据
只有POST方法,才有请求体
步骤:
1. 获取流对象
BufferedReader getReader():获取字符输入流,只能操作字符数据
ServletInputStream getInputStream():获取字节输入流,可以操作所有类型数据
2. 再从流对象拿取数据
- 获取请求消息数据
<!-- 表单数据-->
<form action="/DemoRequest/Demo01" method="post">
<input name="username" placeholder="请输入用户名">
<input name="password" placeholder="请输入密码">
<input type="submit" value="提交">
</form>
@WebServlet("/Demo01")
public class Demo01 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
BufferedReader bufferedReader=request.getReader();
String line=null;
while((line=bufferedReader.readLine())!=null){
System.out.println(line);//username=xiaomi&password=aaa
}
}
2.其他功能
1.获取请求参数通用方式(get,post)中都适用
String getParameter(String name)根据参数名称获取参数值 username=xiaomi&&password=aaa
String[] getParameterValues(String name):根据参数名称获取参数值的数组 hobby=xx&&hobby=game;同一个键对应多个
Enumeration<String> getParameterNames():获取所有请求的参数名称
Map<String,String[]> getParameterMap():获取所有参数的map集合
-- 乱码问题
request.setCharacterEncoding("utf-8");//解决中文乱码问题,获取参数前,修改输入流编码格式
2.请求转发
一种在服务器内部资源跳转方式
方法:
步骤:
1.通过Request对象获取请求转发器对象:RequestDispatcher(String path)
2.适用RequestDispatcher对象转发:forward(ServletRequest request,ServletResponse response)
特点:
1.浏览器地址路径不发生变化
2.只能转发到当前服务器内部资源中
3.转发是一次请求
System.out.println("Demo03被访问了");
//Demo04为转发的目的地
request.getRequestDispatcher("/Demo04").forward(request,response);
3.共享数据
域对象:一个有作用范围的对象,可以在范围内共享数据
request域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据
方法:
1.void setAttribute(String name,Object obj):存储数据
2.Object getAttribute(String name):通过键获取值
3.void removeAttribute(String name):通过键移除键值对
4.获取ServletContext
@WebServlet("/Demo02")
public class Demo02 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// String string=request.getParameter("username");
/*
String[] lessons=request.getParameterValues("lesson");
for (String lesson : lessons) {
System.out.println(lesson);
}
Enumeration<String> parameterNames=request.getParameterNames();
while(parameterNames.hasMoreElements()){
String name=parameterNames.nextElement();
System.out.println(name);
String title=request.getParameter(name);
System.out.println(title);
System.out.println("---------");
}
*/
request.setCharacterEncoding("utf-8");//解决乱码问题
Map<String,String[]> map=request.getParameterMap();
Set<String> set=map.keySet();
for (String string : set) {
String[] strings=map.get(string);
System.out.println(string);
for (String s : strings) {
System.out.println(s);
}
System.out.println("-----------");
}
}
<form action="/DemoRequest/Demo02" method="post">
<input name="username" placeholder="请输入用户名">
<br>
<input name="password" placeholder="请输入密码">
<br>
<input name="lesson" type="checkbox" value="英语">英语
<input name="lesson" type="checkbox" value="Math">数学
<br>
<input type="submit" value="提交">
</form>
登录案例
使用html访问服务器,并且与数据库交互,若符合数据库中数据,则登陆成功,若不匹配,则访问失败
实现部分:
1. html:提交表单;
2. Servlet:通过Request对象,获取表单信息,并且与数据库进行交互(可能是多个Servlet实现此功能)
3. Dao:操作数据库得类,实际与数据库进行交互的类(将交互信息,封装为User对象,包含用户名以及密码)
此类中需要创建一个连接池类,根据配置文件实例化连接池对象(使用Druid进行配置)
简化封装类:BeanUtils
BeanUtils工具类,简化数据封装
用于封装JavaBean(比如User)
JavaBean:标准的Java类
要求:
1. 类必须被public修饰
2. 必须提供空参构造器
3. 成员变量必须使用private修饰
4. 提供公共的setter和getter方法
功能:
封装数据
JavaBean的概念:
1.含有成员变量
2.属性:(属性即setter和getter方法截取后的产物)属性一般与成员变量名相同,但是也可以不一致,属性是用于操纵成员变量的;
方法:
setProperty();//操纵属性,为成员变量赋值
getProperty();//根据属性,得到成员变量的值
populate(Object obj,Map map);//将map集合的键值对信息,封装到对应的JavaBean对象中