什么是Servlet ?
''Java servlet is a Java program that extends the capabilities of a server.''
Java servlet是一个扩展了服务器功能的java程序。
Servlet 的主要功能在于交互式地浏览和修改数据,生成动态 Web 内容。这个过程为:
- 客户端发送请求至服务器端;
- 服务器将请求信息发送至 Servlet;
- Servlet 生成响应内容并将其传给服务器。响应内容动态生成,通常取决于客户端的请求;
- 服务器将响应返回给客户端。
Servlet 生命周期
- 客户端请求该servlet
- 加载servlet类到内存
- 实例化并调用init()方法,初始化该servlet
- service()(根据请求方法不同调用doGet() 或者 doPost(),此外还有doHead()、doPut()、doTrace()、doDelete()、doOptions()、destroy())
- 加载和实例化 Servlet。这项操作一般是动态执行的。然而,Server 通常会提供一个管理的选项,用于在 Server 启动时强制装载和初始化特定的 Servlet
Servlet创建一个servlet实例
- 一个客户端的请求到达Server
- Server 调用 Servlet 的 init() 方法。(可配置为 Server 创建 Servlet 实例时调用,在 web.xml 中 <servlet> 标签下配置 <load-on-startup> 标签,配置的值为整型,值越小 Servlet 的启动优先级越高)
- 一个客户端的请求到达 Server
- Server 创建一个请求对象,处理客户端请求
- Server 激活 Servlet 的 service()方法,传递请求和响应对象作为参数
- service() 方法获得关于请求对象的信息,处理请求,访问其他资源,获得需要的信息
- service() 方法使用响应对象的方法,将响应传回Server,最终到达客户端。service()方法可能激活其它方法以处理请求,如 doGet() 或 doPost() 或程序员自己开发的新的方法。
一般 Servlet 只初始化一次(只有一个对象),当 Server 不再需要 Servlet 时(一般当 Server 关闭时),Server 调用 Servlet 的 destroy() 方法
- 典型的Servlet声明周期是:
- 第一个到达服务器的 HTTP 请求被委派到 Servlet 容器
- Servlet 容器在调用 service() 方法之前加载 Servlet
- 然后 Servlet 容器处理由多个线程产生的多个请求,每个线程执行一个单一的 Servlet 实例的 service() 方法
工作模式
- 客户端发送请求至服务器
- 服务器启动并调用 Servlet
- Servlet根据客户端请求生成响应内容并将其传给服务器
- 服务器将响应返回客户端
开发Servlet
Servlet 本身不能独立运行,需要在一个web应用中运行的
而一个web应用是部署在tomcat中的.
开发步骤:
- 创建web应用项目
- 编写Servlet代码
- 部署到tomcat中
coding...
Servlet coding is done so现在我们整理一遍工作流程
- login.html
打开一个静态的html页面,在这个页面中可以通过form,以post的形式提交数据 - /login路径
- 在上一步的login.html中,用form,把账号和密码,提交到/login这个路径(这里使用的方法是form表达的action = "login"),并且附带method="post"
- 找到对应的Servlet
tomcat接受到一个新的请求
http://127.0.0.1/login
其路径是/login,接着就到配置文件web.xml进行匹配,发现/login,对应的Servlet类是 LoginServlet。
接下来的逻辑,就会基于这个LoginServlet进行
-
调用doGet或者doPost
Tomcat从上一步拿到了LoginServlet的实例之后,根据页面login.html提交信息的时候带的method="post",去调用对应的doPost方法 -
request获取参数
接着流程进入了doPost方法中,在这个方法中,通过参数request,把页面上传递来的账号和密码信息取出来
String name = request.getParameter("name");
String password = request.getParameter("password");
- response设置响应
骤 8 : response设置响应 顶 折
接着,根据账号和密码是否正确(判断是否是admin和123), 创建不同的html字符串。
然后把html字符串通过如下方式,设置在了response对象上
String html = null;
if (name.equals("admin") && password.equals("123456")) {
html = "<h2 style='color:green'>login success hello i am fungi8~!</h2>";
} else {
html = "<h2 style='color:red'>sorry login fail. Dr.fungi8 do not want to see you !</h2>";
}
PrintWriter writer = resp.getWriter();
writer.println(html);
这里Servlet的工作就做完了
- tomcat把html传递给浏览器
在Servlet完成工作之后,tomcat拿到被Servlet修改过的response,根据这个response生成html字符串,然后再通过HTTP协议,这个html字符串,回发给浏览器,浏览器再根据HTTP协议获取这个html字符串,并渲染在界面上。
这样在效果上,浏览器就可以看到Servlet中生成的字符串了。
Service()
Servlet 需要提供对应的doGet() 与 doPost()方法
-
doGet()
当浏览器使用get方式提交数据的时候,servlet需要提供doGet()方法
doGet()请求:- form默认的提交方式
- 如果通过一个超链访问某个地址
- 如果在地址栏直接输入某个地址
- ajax指定使用get方式的时候
-
doPost()
当浏览器使用post方式提交数据的时候,servlet需要提供doPost()方法
doPost()请求:- 在form上显示设置 method="post"的时候
- ajax指定post方式的时候
-
service()
LoginServlet继承了HttpServlet,同时也继承了一个方法
service(HttpServletRequest , HttpServletResponse )
实际上,在执行doGet()或者doPost()之前,都会先执行service(),由service()方法进行判断,到底该调用doGet()还是doPost().可以发现,service(), doGet(), doPost() 三种方式的参数列表都是一样的.所以,有时候也会直接重写service()方法,在其中提供相应的服务,就不用区分到底是get还是post了.
中文编码问题
- 获取中文的参数
为了成功获取中文参数,需要做如下操作
- login.html中加上
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
这句话的目的是告诉浏览器,等下发消息给服务器的时候,使用UTF-8编码
- login.html的form的method修改为post
- 在servlet进行解码和编码
byte[] bytes= name.getBytes("ISO-8859-1");
name = new String(bytes,"UTF-8");
先根据ISO-8859-1解码,然后用UTF-8编码这样就可以得到正确的中文参数了
如果觉得麻烦可以使用:
request.setCharacterEncoding("UTF-8");
并且把这句话放在request.getParameter()之前
生命周期
- 实例化 -> 初始化 -> 提供服务 -> 销毁 -> 回收资源
-
实例化
当用户通过浏览器输入一个路径,这个路径对应的servlet被调用的时候,该Servlet就会被实例化。无论访问了多少次LoginServlet
LoginSerlvet构造方法 只会执行一次,所以Serlvet是单例 的 -
初始化
LoginServlet 继承了HttpServlet,同时也继承了init(ServletConfig) 方法。init 方法是一个实例方法,所以会在构造方法执行后执行。
无论访问了多少次LoginSerlvet --> init初始化 只会执行一次 -
提供服务
接下来就是执行service()方法,然后通过浏览器传递过来的信息进行判断,是调用doGet()还是doPost()方法
在service()中就会编写我们的业务代码,在本例中就是判断用户输入的账号和密码是否正确 -
销毁
在如下几种情况下,会调用destroy():
- 该Servlet所在的web应用重新启动.在serverl.xml中配置该web应用的时候用到了
<Context path="/" docBase="e:\project\j2ee\web" debug="0" reloadable="false" />
如果把 reloadable="false" 改为reloadable="true"就表示有任何类发生的更新,web应用会自动重启,当web应用自动重启的时候,destroy()方法就会被调用
- 关闭tomcat的时候destroy()方法会被调用,但是这个一般都发生的很快,不易被发现
- 被回收
当Servlet被销毁之后,发生GC会自动回收内存。
引用:
http://how2j.cn/k/servlet/servlet-jump/
https://en.wikipedia.org/wiki/Java_servlet
https://baike.baidu.com/item/servlet
网友评论