本节内容
1.Servlet简介
2.Servlet运行原理
3.创建Servlet
4.Servlet的生命周期
5.Servlet线程安全问题
6.Servlet初始化参数
7.Servlet中的一些对象
一、Servlet简介
Servlet是sun公司提供的一门用于开发动态web资源的技术。
Sun公司在其API中提供了一个servlet接口,用户若想用发一个动态web资源(即开发一个Java程序向浏览器输出数据),需要完成以下2个步骤:
1、编写一个Java类,实现servlet接口。
2、把开发好的Java类部署到web服务器中。
按照一种约定俗成的称呼习惯,通常我们也把实现了servlet接口的java程序,称之为Servlet
二、Servlet运行原理
Servlet程序是由WEB服务器调用,web服务器收到客户端的Servlet访问请求后:
①Web服务器首先检查是否已经装载并创建了该Servlet的实例对象。如果是,则直接执行第④步,否则,执行第②步。
②装载并创建该Servlet的一个实例对象。
③调用Servlet实例对象的init()方法。
④创建一个用于封装HTTP请求消息的HttpServletRequest对象和一个代表HTTP响应消息的HttpServletResponse对象,然后调用Servlet的service()方法并将请求和响应对象作为参数传递进去。
⑤WEB应用程序被停止或重新启动之前,Servlet引擎将卸载Servlet,并在卸载之前调用Servlet的destroy()方法。
三、创建Servlet
Servlet接口SUN公司定义了两个默认实现类,分别为:GenericServlet、HttpServlet。
HttpServlet指能够处理HTTP请求的servlet,它在原有Servlet接口上添加了一些与HTTP协议处理方法,它比Servlet接口的功能更为强大。因此开发人员在编写Servlet时,通常应继承这个类,而避免直接去实现Servlet接口。
HttpServlet在实现Servlet接口时,覆写了service方法,该方法体内的代码会自动判断用户的请求方式,如为GET请求,则调用HttpServlet的doGet方法,如为Post请求,则调用doPost方法。因此,开发人员在编写Servlet时,通常只需要覆写doGet或doPost方法,而不要去覆写service方法。
创建Servlet就是使用一个类去继承HttpServlet这个类。重写其中的处理请求的方法:一般是doPost、doGet。
现在这个Servlet还不能被访问:我们需要给Servlet配置映射的访问路径。
在web.xml中配置
然后将项目部署到Tomcat中就可以在浏览器通过路径来访问 了。
同一个Servlet可以映射多个访问路径:
你可以用这些不同的路径来访问这个Servlet。
四、Servlet生命周期
Servlet的设计模式:单例多线程模式。
Servlet是一个供其他Java程序(Servlet引擎)调用的Java类,它不能独立运行,它的运行完全由Servlet引擎来控制和调度。
针对客户端的多次Servlet请求,通常情况下,服务器只会创建一个Servlet实例对象,也就是说Servlet实例对象一旦创建,它就会驻留在内存中,为后续的其它请求服务,直至web容器退出,servlet实例对象才会销毁
生命周期: 创建------->初始化--------->运行----------->销毁
1.创建:第一次访问这个Servlet时创建,并且只创建一次。(除非重启服务器,否则不会在创建)
2.初始化:在servlet创建后会调用init方法来初始化,init只执行一次。
3.运行: 每次请求都会调用service方法来进行处理请求(每一次请求都会创建新的请求对象与响应对象)。
4.销毁: 服务器关闭,或者服务器异常关闭,就会进行销毁。
五、Servlet线程安全
当多个客户端并发访问同一个Servlet时,web服务器会为每一个客户端的访问请求创建一个线程,并在这个线程上调用Servlet的service方法,因此service方法内如果访问了同一个资源的话,就有可能引发线程安全问题。
1.尽量不要声明全局变量,全局变量很容易造成线程不安全。
2.给共享的资源使用同步synchronized这种做法是给Servlet对象加了一把锁,保证任何时候都只有一个线程在访问该Servlet对象里面的资源,这样就不存在线程安全问题了。这种做法虽然解决了线程安全问题,但是编写Servlet却万万不能用这种方式处理线程安全问题。如果人数过多,那么这些人必须排队,效率非常低。
六、Servlet初始化参数
配置初始化参数:
在Servlet的配置文件web.xml中,可以使用一个或多个<init-param>标签为servlet配置一些初始化参数
当servlet配置了初始化参数后,web容器在创建servlet实例对象时,会自动将这些初始化参数封装到ServletConfig对象中,并在调用servlet的init方法时,将ServletConfig对象传递给servlet。进而,我们通过ServletConfig对象就可以得到当前servlet的初始化参数信息。

package com.xk; import java.io.IOException; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet implementation class LoginServlet */ public class LoginServlet extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public LoginServlet() { super(); // TODO Auto-generated constructor stub } @Override public void init(ServletConfig config) throws ServletException { //接收初始化参数 String charset= config.getInitParameter("charset"); int count= Integer.parseInt(config.getInitParameter("count")); } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }
七、Servlet中的对象:
ServletContext对象
WEB容器在启动时,它会为每个WEB应用程序都创建一个对应的ServletContext对象,它代表当前web应用。
ServletConfig对象中维护了ServletContext对象的引用,开发人员在编写servlet时,可以通过ServletConfig.getServletContext方法获得ServletContext对象。
由于一个WEB应用中的所有Servlet共享同一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象来实现通讯。ServletContext对象通常也被称之为context域对象。使用ServletContext可以实现多个Servlet之间的数据共享。
使用ServletContext可以获取web应用的初始化参数
获取初始化参数:

package com.xk; import java.io.IOException; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet implementation class LoginServlet */ public class LoginServlet extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public LoginServlet() { super(); // TODO Auto-generated constructor stub } @Override public void init(ServletConfig config) throws ServletException { //使用ServletContext对象接收web应用的初始化参数 String url=config.getServletContext().getInitParameter("url"); } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }
实现转发请求:

package com.xk; import java.io.IOException; import javax.servlet.RequestDispatcher; import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet implementation class LoginServlet */ public class LoginServlet extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public LoginServlet() { super(); // TODO Auto-generated constructor stub } @Override public void init(ServletConfig config) throws ServletException { //使用ServletContext对象接收web应用的初始化参数 String url=config.getServletContext().getInitParameter("url"); } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取ServletContext对象 ServletContext servletContext=this.getServletContext(); //获取请求转发对象 RequestDispatcher dispatcher = servletContext.getRequestDispatcher("/seervlet/registerServlet"); //进行转发 dispatcher.forward(request, response); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }
本来访问的是loginServlet但是出现的是registerServlet的内容。
这就实现了转发。