什么是Servlet
Servlet就是工作在服务器端的类,该类可以处理用户传过来的请求,也可以通过响应向用户输送数据。
如何使用Servlet
Servlet就是处理用户的HTTP请求,然后回送HTTP响应,若是没有Servlet技术出现的话,我们还要手动的使用一些基本、底层的类去解析HTTP。现在有了Servlet的底层封装,我们可以基于Servlet快速的开发。我们可以让我们编写的类继承HttpServlet,HttpServlet也是继承了GenericServlet,里面定义了与HTTP相关的各种方法,如GET、POST、HEAD等,我们只需要在自己编写的类上重写对应的请求方法就可以处理用户通过给HTTP方法传送过来的请求了。
例如在doGet方法里面,有两个参数,一个是HttpServletRequest,另外一个是HttpServletResponse,前面一个对应的就是用户的HTTP请求,后面一个就是你响应给用户的HTTP响应。在HttpServletRequest里面,你可以获取HTTP请求的各种信息,如用户的IP,用户通过哪个端口发送,请求参数,请求头,各种路径,编码格式等。在HttpServletResponse里面,你可以设置你的响应内容,响应头,响应编码等。
Servlet的生命周期
(1)加载实例化。当用户请求一个Servlet的时候,如果Servlet容器中没有这个Servlet的实例的话,容器就会加载实例化一个该Servlet。
(2)初始化。在进行处理请求前,会调用Servlet的init方法进行初始化,在init方法里面你可以写你要初始化的代码。
(3)处理请求。Servlet会调用父类的service方法,该方法处理过程主要是这样的,首先在HttpServletRequest参数中通过getMethod方法拿到这个Http请求的是什么方法,然后判断这个方法是什么类型的,如果是GET方法,就对应到doGet方法中处理,前面你的Servlet类中必须要重写这个方法,不是的话报405的错误,就是说你请求的这个方法不被访问。
(4)销毁。当Servlet容器决定要删除这个Servlet实例的时候,就会调用这个Servlet的destroy方法。例如当你运行着Tomcat,然后你修改了改Servlet的时候,Servlet容器就是删除你以前的Servlet实例,然后加载实例化新的这个。
Servlet是单例的
为什么设计Servlet为单例呢?我们可以先想想如果Servlet不是单例的话,很多客户通过访问一个Servlet的话,每次都new出一个实例的话,内存很快就爆了,所以设计出单例是合理的。
怎么看Servlet是单例的?我们只需要在doXXX方法中打印this,就可以判断是不是用同一个实例。
单实例多线程的Servlet模型
Servlet规范定义中,在默认的情况下,Servlet容器对声明的每一个Servlet,只创建一个实例,如果有多个客户同时访问这个Servlet,Servlet容器如何处理这多个请求呢?答案就是多线程,Servlet维护了一个线程池来服务请求,线程池实际上是等待执行代码的一组线程,这些线程叫做工作者线程,当容器收到一个访问Servlet的请求,调度者线程从线程池中选取一个线程来执行Servlet里面的service方法。
Servlet简单例子
/** * Servlet的工作流程 * @author xujianguo <[email protected]> * @date 2014-6-21 * @CopyRight 2014 Topview Inc. * @version V1.0 */ @WebServlet(name="servlet_work", urlPatterns="/servlet_work") public class ServletWork extends HttpServlet { private static final long serialVersionUID = 1L; @Override public void init() throws ServletException { System.out.println("------ ServletWork Init ------"); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("------ ServletWork DoGet ------"); resp.getWriter().write("ServletWork"); } @Override public void destroy() { System.out.println("------ ServletWork Destroy ------"); } }