Servlet简介
一、Servlet是什么?
Servlet是在JSP之前推出的,它是一种应用于服务器端的Java程序,可以生成动态的Web页面。由Web服务器负责加载,是独立于平台和协议的Java应用程序。
JSP改变了Servlet提供HTTP服务时的编程方式。但是在内部机制上,每一个JSP都被处理成一个Servlet。HTTP协议处理过程是建立连接、发送请求、提供服务、发送响应和关闭连接。Servlet使用最多的是HTTP协议,但是并不限制所使用的协议。
Servlet具有跨平台、可移植性强的特点。没有被广泛使用,主要是因为Servlet编写需要全面掌握Java程序设计技巧,而且它将页面的显示和处理功能混杂在一起,不利于系统开发过程的分工和后期维护。
二、Servlet的生命周期
Servlet运行在Servlet容器中,由容器管理其生命周期,Servlet生命周期主要包含以下4个过程:
1、加载和实例化:
加载和实例化Servlet由Servlet容器来完成,加载Servlet之后,容器会通过Java的反射机制来创建Servlet实例。
2、初始化:
在Servlet实例创建后,容器会调用Servlet的init()方法来初始化该Servlet对象。目的是让Servlet对象在处理客户端请求前先完成一些初始化工作,只会调用一次init()方法。
3、执行:
当客户请求到来时,Servlet容器首先针对该请求创建ServletRequest和ServletResponse两个对象,然后Servlet容器会自动调用Servlet的servlet()方法来响应客户端请求,同时把ServletRequest和ServletResponse两个对象传递给service()方法。通过ServletRequest对象,Servlet可以获得客户端的请求信息,处理完成后,则将响应信息放置在ServletResponse对象中。最后销毁这两个对象。
4、清理:
当Servlet实例需要从服务中移除时,容器会调用destroy()方法,让该实例释放掉所使用的资源,并将实例中的数据存放在持久的存储设备中。之后,Servlet实例便会被Java的垃圾回收器回收。
在整个生命周期中,其初始化和销毁都只发生一次,service()方法执行的次数取决于Servlet被客户端访问的次数。
三、Servlet的生命周期的3个重要方法
1、init()方法:
创建Servlet实例时会调用init()方法,在该方法中完成类似于构造方法的初始化功能,其参数为ServletConfig的实例。该方法结束后,Servlet就可以接收客户端的请求。
整个生命周期,只执行一次。
2、service()方法:
该方法用于响应客户端发出的请求,service()方法使用ServletRequest接口和ServletResponse接口的对象作为参数,ServletRequest对象用于处理请求,ServletResponse对象用于发送响应。
service()方法执行时会检查HTTP请求的类型,并相应的调用doGet()、doPost()等方法,因此,通常的做法是不使用service(),而直接使用doGet()、doPost()等方法来处理请求。
3、destroy()方法:
当不再需要Servlet实例或重新装入时,destroy()方法被调用。使用destroy()方法可以释放掉所有在init()方法中申请的资源。一个Servlet实例一旦终止,就不再允许被再次调用,只能等待被卸载。
destroy()方法通常用来执行一些清理任务,在destroy()方法中一般安排释放资源的代码。
四、Servlet常用类和接口
Servlet API包含在两个包中,分别是javax.servlet和javax.servlet.http。在Servlet架构中,Servlet接口是所有类型的Servlet类必须实现的接口,最典型的的Servlet类是HttpServlet类。
1、Servlet接口:
Servlet接口是所有Servlet都必须直接或间接实现的接口。
主要方法:init()、service()、destroy()等。
2、GenericServlet抽象类:
有两个Servlet类:GenericServlet和HttpServlet类,提供了2种基本Servlet,分别为Servlet方法提供了一种默认的实现模式。我们编写的Servlet一般总是从这两种Servlet中继承。GenericServlet实现了Servlet接口,派生类必须实现service()方法。
3、HttpServlet抽象类:
HttpServlet是所有基于Web的Servlet类的根类。HttpServlet类重写了service方法,并针对客户端的几种不同请求类型提供了几个不同的方法,如doGet()、doPost();
4、ServletRequest和ServletResponse接口
当客户请求到来时,Servlet容器会创建一个ServletRequest对象用来封装请求数据,同时创建一个ServletResponse对象,用来封装响应数据。随后这两个对象将作为service()方法的参数被传递到Servlet。
5、HttpServletRequest接口:
ServletRequest接口表示Servlet的请求,HttpServletRequest是它的子接口。HttpServletRequest接口代表了客户端的HTTP请求。
6、HttpServletResponse接口:
ServletResponse接口表示Servlet响应,而HttpServletResponse接口是它的子接口。HttpServletResponse接口表示对客户端的HTTP响应。
7、HttpSession接口:
HttpSession对象有Servelt容器负责创建的,在HttpSession对象中可以存放客户状态信息。Servlet会为每一个HttpSession分配一个唯一标示符,即Session ID。SessionID作为Cookie保存在客户浏览器中,每当客户发出HTTP请求时,Servlet容器就可以从HttpSession对象中读取SessionID,再根据Session ID找到相应的HttpSession对象,进而获取客户的状态信息。
五、Servlet小例子
1、网页输出案例。
在myeclipse某个工程里创建一个servlet,名为HelloServlet:
package servlet;
import java.io.IOException;
import java.io.PrintWriter;
importjavax.servlet.ServletException;
importjavax.servlet.http.HttpServlet;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
publicclassHelloServletextends HttpServlet {
private static finallongserialVersionUID = 1L;
public HelloServlet(){ //构造方法
super();
}
//重写HttpServlet的doGet方法
protected void doGet(HttpServletRequest req,HttpServletResponse resp)throwsServletException ,IOException{
PrintWriter out=resp.getWriter(); //获得输出流 out
out.println("hellohadoop"); //网页上输出
out.close(); //关闭输出流
}
}
想通过网页访问到HelloServlet,则必须进行部署,web.xml文件如下:
<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/servlet/HelloServlet</url-pattern> <!—指定servlet访问路径 -->
</servlet-mapping>
注意:在web.xml里面可不能写入 <!—指定servlet访问路径 --> 这个注释,否则会出错。
如果写成这样,浏览器这样写:
<url-pattern>/HelloServlet</url-pattern>
2、通过doPost方法处理POST方法提交的表单
userform.jsp:
<%@page contentType="text/html;charset=GB2312" %>
<html>
<head>
<title>登陆页面</title>
</head>
<body>
<!-- login是在web.xml里面配置的servlet路径 -->
<form action="login"method="post">
<input type="text"name="username">
<input type="submit"value="提交"/>
</form>
</body>
</html>
UserServlet.java:
package servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
public class UserServlet extendsHttpServlet {
private static finallong serialVersionUID = 1L;
public UserServlet() {
super();
}
//重写HttpServlet的doPost方法
protected void doPost(HttpServletRequestreq, HttpServletResponse resp)
throwsServletException, IOException {
resp.setContentType("text/html;charset=GB2312"); //设置输出内容的格式和编码格式
PrintWriter out =resp.getWriter(); //获取输出流out
req.setCharacterEncoding("GB2312"); //设置接收参数的编码格式
Stringusername=req.getParameter("username"); //获取参数
out.println("<html>");
out.println("<body>");
out.println("用户名:"+username);
out.println("</body>");
out.println("</html>");
out.close();
}
}
web.xml配置如下:
<servlet>
<servlet-name>UserServlet</servlet-name>
<servlet-class>servlet.UserServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>UserServlet</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>