Java Servlet是运行在服务器或应用服务器上的程序,它是作为来自Web浏览器的请求或其他HTTP客户端的请求与HTTP应用服务器的数据库或应用程序的中间层。使用Servlet,可以收集来自网页表单的用户输入,呈现来自数据库或其他源的记录,还可以动态创建网页。
Servlet架构
下图展示了Servlet在Web应用程序中的位置:
Servlet任务
- 读取客户端(浏览器)发送的显式数据。包括表单数据等等。
- 读取客户端(浏览器)发送的隐式的HTTP请求数据。包括cookies等等。
- 处理数据并生成结果。需要访问数据库。
- 发送显式的数据(即文档)到客户端(浏览器)。该文档格式可以是多种多样的,包括文本文件(HTML文件、XML文件等)、二进制文件(图像)等。
- 发送隐式的HTTP响应到HTTP客户端(浏览器)。这包括告诉浏览器或其他客户端被返回的文档类型(例如HTML)、设置cookies和缓存参数,以及其他类似的参数。
使用Servlet
1、创建Servlet的三种方式
(1)实现javax.servlet.Servlet接口。
(2)继承javax.servlet.GenericServlet类
(3)继承javax.servlet.http.HttpServlet类
我们在日常开发中一般会使用第三种方法来进行Servlet的创建,前两种方法理解即可.。
注意:创建Servlet文件后,需要在web.xml文件中完成Servlet配置,才可以使用。
2、配置Servlet的两种方式
(1)使用web.xml文件配置Servlet。例如,我有一个名为ServletDemo的Servlet,主要将它配置到服务器进行运行,可以按照下面的代码进行配置web.xml文件:
ServletDemo
cn.tender.servlet.ServletDemo
ServletDemo
/ServletDemo
(2)使用注解进行Servlet配置(高版本后默认使用此方法):
当我们去创建一个Servlet时会默认继承HttpServlet类,会使用注解方式进行配置Servlet:
// 这种方式配置的效果与第一种一致
@WebServlet("/HelloServlet")
注意:两种配置方式不能同时使用,即配置了web.xml就不能使用注解,使用了注解也就不能使用web.xml配置了。
Servlet相关知识
1、Servlet容器装载Servlet的时刻:
(1)Servlet容器启动后会自动装载某些Servlet;
(2)在Servlet容器启动后,客户端首次向Servlet容器发送请求;
(3)Servlet文件被更新后,重新装载Servlet。
在默认情况下,当Web客户第一次请求访问某个Servlet时,Web容器会创建这个Servlet的实例。
当设置了web.xml中
的子元素
后,Servlet容器在启动Web应用时,将按照指定顺序创建并初始化这个Servlet。设置的数值大于0即可。例如:
HelloServlet
com.langsin.servlet.HelloServlet
2
2、Servlet的生命周期:
先看与Servlet生命周期有关的三个方法:init(), service(), destroy(). Servlet生命周期可被定义为从创建直到毁灭的整个过程。以下是三个方法分别对应的Servlet过程:
- init():Servlet进行初始化;
- service():Servlet处理客户端的请求;
- destroy():Servlet结束,释放资源;
在调用destroy()方法后,Servlet由JVM的垃圾回首器进行垃圾回收。
现在我们来详细讨论Servlet生命周期的方法:
init()
方法:
init()
方法被设计成只调用一次。它在第一次创建Servlet时被调用,在后续处理每个人Http请求的时候,不会再调用,因此,它只用于Servlet的一次性初始化。
Servlet被装载后,Servlet容器创建一个Servlet实例并且调用Servlet的init()
方法进行初始化在Servlet生命周期中init()
方法只被调用一次。
当用户调用一个Servlet时,Servlet容器就会创建一个Servlet实例,每一个用户请求都会产生一个新的线程,适当的时候移交给doGet()
和doPost()
方法。init()
方法简单的创建或加载一些数据,这些数据将会被用在Servlet的整个生命周期。
init()
方法的定义如下:
public void init() throws ServletException {
// 初始化代码...
}
service()
方法:
service()
方法是执行实际任务的主要方法。Servlet 容器(即 Web 服务器)调用 service()
方法来处理来自客户端(浏览器)的请求,并把格式化的响应写回给客户端。
每次服务器接收到一个 Servlet 请求时,服务器会产生一个新的线程并调用服务。service()
方法检查 HTTP 请求类型(GET、POST、PUT、DELETE 等),并在适当的时候调用doGet()
、doPost()
、doPut()
,doDelete()
等方法。
service()
的定义如下:
public void service(ServletRequest request, ServletResponse response)
throws ServletException, IOException{
// service()代码...
}
service()
方法由容器调用,service()
方法在适当的时候调用doGet()
、doPost()
、doPut()
,doDelete()
等方法,所以,我们不需要对service()
方法做任何动作,只需要根据客户端的请求类型重写doGet()
、doPost()
方法即可。
destroy()
方法:
destroy()
方法只会被调用一次,在Servlet生命周期结束时被调用。destroy()
方法可以让Servlet关闭数据库连接、停止后台、把cookie列表或点击计数器写入到磁盘,并执行其他类似的清理活动。
在调用destroy()
方法之后,Servlet对象被标记为垃圾回收。
destroy()
方法的定义如下所示:
public void destroy() {
// 终止化代码...
}
在首次访问某个Servlet时,init()
方法会被执行,而且也会执行service()
方法。再次访问时,只会执行service()
方法,不再执行init()
方法。在关闭Web容器时会调用destroy()
方法。
继承HttpServlet类创建Servlet
1、HttpServlet
概述
继承HttpServlet创建Servlet的方法是我们开发中最常用的一种方式。它与HTTP协议有关,HTTP协议中有两种常用的请求方式,get
和post
。而我们使用的HttpServlet
时会获得这两种请求方式产生的请求和响应对象,通过这两个对象完成处理与响应。
HttpServlet
类中提供了service(HttpServletRequest request, HttpServletResponse response)
方法,这个方法是HttpServlet
自己的方法,不是从Servlet
类中继承来的。在HttpServlet
的service(ServletRequest, ServletResponse)
方法中会把ServletRequest
和ServletResponse
强转成HttpServletResponse
和HttpServletResponse
,然后调用service(HttpServletRequest, HttpServletResponse)
方法,这说明子类可以去覆盖service(HttpServletRequest,HttpServletResponse)
方法即可,这就不用自己去强转请求和响应对象了。
在HttpServlet
的service(HttpServletRequest, HttpServletResponse)
方法会去判断当前请求是GET还是POST,如果是GET请求,那么会去调用本类的doGet()
方法,如果是POST请求会去调用doPost()
方法,这说明我们在子类中去覆盖doGet()
或doPost()
方法即可。
以下是doGet()
和doPost()
方法的原型:
protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
//测试代码
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
注意:在doPost()
方法中调用了doGet()
方法,因此在实现两个方法时,如果代码逻辑一致,只写一遍代码即可。
2、创建HttpServlet实例
(1)创建ServletDemo
类,实现HttpServlet
接口:
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 用于测试Servlet的Demo类
* @author mTender
*/
public class ServletDemo extends HttpServlet {
private static final long serialVersionUID = 1L;
public ServletDemo() {
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 使用HttpServletResponse对象设置文档的content-type类型
resp.setContentType("text/html;charset=utf-8");
// 使用HttpServletResponse对象向jsp文件中写入字符
resp.getWriter().append("welcome");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
(2)使用注解或者配置web.xml,这里采用的是配置web.xml文件的形式:
ServletDemo
com.demo.ServletDemo
ServletDemo
/Servlet.do
(3)开启服务器,访问ServletDemo,网页中会出现下图所示效果:
3、简单JSP&Servlet实例
假设我们现在向Servlet提交一个表单,表单包括我们的用户名和密码,我们需要从JSP页面获取数据,并将用户名和密码在Eclipse的控制台打印出来。
(1)创建JSP页面:
(2)创建ServletDemo
:
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 用于测试Servlet的Demo类
* @author mTender
*/
public class ServletDemo extends HttpServlet {
private static final long serialVersionUID = 1L;
public ServletDemo() {
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 使用HttpServletResponse对象设置文档的content-type类型
resp.setContentType("text/html;charset=utf-8");
req.setCharacterEncoding("utf-8");
// 获取前端页面提交过来的数据
String username = req.getParameter("UserName");
String password = req.getParameter("password");
System.out.println("Username:" + username + " password:" + password);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
(3)配置ServletDemo
类,配置方式和2、Servlet实例中配置方式相同,这里不再赘述;
(4)我在JSP表单的输入框内填入的用户名是:mTender;密码是:123456,点击提交,在Eclipse的控制台上可以看到以下输出:
我们在获取用户信息完成之后,就可以对用户信息进行校验或者加工,例如:我们可以校验用户数据是否符合我们要求用户遵守的信息标准,也可以在这个时候给用户的密码进行加密(目前比较常用的用户密码加密方法是MD5码加密)等一系列的操作。
刚刚开始学习Java Web,还基本上是个小白,文章中的错误欢迎大家指正!