Http协议&Servlet
Http协议
- 什么是协议
双方在交互、通讯的时候,遵守的一种规范、规则。
- http协议
针对网络上的客户端和服务器端在执行http请求的时候,遵守的一种规范。其实就是规定了客户端在访问服务器端的时候,需要带上哪些东西,服务器端返回数据的时候,也要带上哪些东西。
- 版本
1.0协议:请求数据,服务器返回后,将会断开连接
1.1协议:请求数据,服务器返回后,连接还会保持。除非服务器 | 客户端关闭。有一定的时间限制,如果都空着这个连接,后面会自动断开。
演示客户端和服务器端通讯
在地址栏中键入网络地址,回车之后,浏览器都能显示出来一些东西,浏览器和服务器究竟如何通讯呢?
- 安装抓包工具HttpWatch(IE插件)
- 打开Tomcat,输入http://localhost:8080
- 在Tomcat首页上找到Example,选择servlet例子,然后找到请求参数(request parameters),点击execute超链接
- 执行Tomcat的例子,然后查看浏览器和Tomcat的对接细节
Http请求数据解释
请求的数据里面包含三个部分内容:请求行、请求头、请求体
- 请求行:
POST /examples/servlets/servlet/RequestParamExample HTTP/1.1
请求方式 | 请求的地址路径(即需要访问的地方) |
---|---|
POST | http://localhost:8080/examples/servlets/servlet/RequestParamExample |
GET | http://localhost:8080/examples/servlets/servlet/RequestParamExample |
- 请求头
-
Host: localhost:8080
-
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:33.0) Gecko/20100101 Firefox/33.0
-
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
-
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
-
Accept-Encoding: gzip, deflate
-
Referer: http://localhost:8080/examples/servlets/servlet/RequestParamExample
-
Content-Length: 99
-
Content-Type: text/plain; charset=UTF-8
-
Connection: keep-alive
-
Pragma: no-cache
-
Cache-Control: no-cache
-
Accept:客户端向服务器端表示,我能支持什么类型的数据
-
Referer:真正请求的地址路径,全路径
-
Accept-Language:支持的语言类型
-
User-Agent:向服务器表明当前来访的客户端信息
-
Content-Type:提交的数据类型,经过url编码的form表单的数据
-
Accept-Encoding:压缩算法
-
Host:主机地址
-
Content-Length:数据长度
-
Connection:keep-alive 保持连接
-
Cache-Control:对缓存的操作
- 请求体
firstname=zhang&lastname=123
浏览器真正发送给服务器的数据,发送的数据呈现的是key-value的格式,如果存在多个数据,那么使用&连接
Http响应数据解析
响应行 : http/1.1 200 ok
- 200: 成功,正常处理,得到数据
- 403:for bidden 拒绝
- 404: Not Found
- 500: 服务器异常
响应头: Server: Apache-Coyote/1.1
表明服务器的类型 Tomcat
Content-Type: “text/html;charset=ISO-8859-1”
编码方式
Content-Length:“670” 返回的数据长度
Date: “Thu, 28 Feb 2019 03:10:19 GMT” 通讯的日期,响应的时间
POST和GET请求的不同
- 请求路径不同,POST请求在URL后面不跟上任何数据,GET请求在地址后面跟上’?'和数据。
- 带上的数据方式不同,POST采用流的方式写数据,而GET则是在地址栏上跟上数据。
- 由于POST采用流的方式写数据,所以一定需要Content-Length的头来说明数据的长度为多长。
POST和GET请求的安全性
- POST
- 数据是以流的方式写过去,不会再地址栏上显示,现在一般提交数据到服务器使用的是POST方式。
- 带的数据没有大小限制。
- GET
- 会在地址栏后面拼接数据,所以有安全隐患。
- 能够带的数据有限。大概1kb以下
WEB资源
在Http协议当中,规定了请求和响应双方,客户端和服务端。与web相关的资源
两种分类
-
静态资源: html、js、css文件
-
动态资源:jsp、servlet
Servlet
- servlet是什么?
其实就是一个java程序,运行在我们的web服务器上,用于接收和响应客户端的http请求
更多配合动态资源使用,访问服务器,无论是静态资源还是动态资源,都需要servlet来实现
Tomcat其实就是Servlet的一个容器
Hello Servlet初次使用
-
写一个web项目,得需要一个服务器
-
测试运行Web工程
1.新建一个类,实现Servlet接口
2.配置servlet,告诉服务器我们的应用有这么些个servlet
3.在Web-Content/WEB-INF的下面配置web.xml文件
4.配置细节如下:
<!-- 向服务器报告,我这个应用里面有这个servlet,名字叫HelloServlet
路径是com.liuhuan.servlet.HelloServlet -->
<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>com.liuhuan.servlet.HelloServlet</servlet-class>
</servlet>
<!-- 注册servlet的映射,servlet-name是指上面具体的servlet
<url-pattern>是指浏览器地址栏上的URL-->
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/HelloServlet</url-pattern>
</servlet-mapping>
Servelt执行过程
- 找到Tomcat应用
- 找到项目
- 找到web.xml,然后在里面找到,有没有哪一个pattern的内容是/HelloServlet
- 找到中的那个servlet-name【HelloServlet】
- 找到上面定义的servlet元素中的servlet-name中的【HelloServlet】
- 找到下面的,然后开始创建该类的实例
- 然后执行servlet中的service方法
Servlet的通用写法
Servlet(接口)
|
|
GenericServlet
|
|
HttpServlet(用于处理Http的请求)
一般使用doGet()和doPost()方法
Servlet的生命周期
- 生命周期
从创建到销毁的一段时间
- 生命周期方法
从创建到销毁的哪些方法
- init方法
/**
* 1.初次访问servlet,创建servlet实例。
* 2.而且一个servlet只会初始化一次
* 即init方法只会执行一次
*/
@Override
public void init(ServletConfig config) throws ServletException {
System.out.println("HelloServlet02初始化...");
}
- service方法
/**
* 任何呼叫都会让service方法去处理,
* 即来一次请求,调用一次service方法
*
*/
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
System.out.println("Service处理请求..");
}
- destory()方法
/**
* 1.servlet销毁的时候就会执行该方法
* 2.项目从Tomcat里面移除
* 3.关闭Tomcat
*/
@Override
public void destroy() {
System.out.println("servlet被销毁了..");
}
让Servlet创建实例的时机提前
1.初次访问可能在init方法中浪费多余的时间,所以,需要把创建实例的时机提前。
2. 在配置的时候,使用,跟下面代码一样,中间的数字越小,创建实例的时机越早,一般使用正整数。
<load-on-startup>2</load-on-startup>
ServletConfig
Servlet的配置对象,通过这个对象,来对Servlet进行配置
// 1.得到ServletConfig配置对象
ServletConfig config = getServletConfig();
// 2.获取web.xml里面的<servlet-name>配置的名称
String servletName = config.getServletName();
System.out.println("servletName == " + servletName);
// 3.可以获取某一个初始化参数
String address = config.getInitParameter("address");
System.out.println("address == " + address);
System.out.println("--------------------------");
// 遍历所有参数的名字和参数值
Enumeration<String> names = config.getInitParameterNames();
while (names.hasMoreElements()) {
String key = (String) names.nextElement();
String value = config.getInitParameter(key);
System.out.println("key == " + key + " &&value == " +value);
}
ServletConfig的作用
1.假如未来我们自己开发的一些应用,使用到了一些新技术,或者一些代码,我们不会,但是有人写出来了,它的代码放在自己的servlet类里面
2.刚好这个servlet里面需要一个数字或者叫做变量值,但是这个值不能是固定的。所以要求使用到这个servlet的公司,在注册servlet的时候,必须在web.xml里面声明init-params
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletConfig config = getServletConfig();
String number = config.getInitParameter("number");
if(number == null) {
throw new IllegalArgumentException("servlet在配置的时候一定要写number这个参数");
}else {
System.out.println("number == " + number);
}
}
如果在用的项目中没有配置number这个参数,就会报在源代码中的异常:servlet在配置的时候一定要写number这个参数