1.Servlet概述
JSP的前身就是Servlet。Servlet就是在服务器端运行的一段小程序。一个Servlet就是一个Java类,并且可以通过“请求-响应”编程模型来访问的这个驻留在服务器内存的Servlet程序。
2.Tomcat容器等级
Tomcat的容器分为4个等级,Servlet的容器管理Context容器,一个Context对应一个Web工程。
3.手工编写第一个Servlet
编写一个Servlet程序大体上需要3个步骤:继承HttpServlet-->重写doGet()或者doPost()方法-->在web.xml中注册Servlet。
HttpServlet的继承关系如图:
重写doGet还是doPost方法需要根据请求方式而定。
一、编写一个类继承自HttpRequest并重写doGet(或者doPost方法)在项目的src目录下新建一个servlet.MyServlet.java
1 package servlet; 2 3 import java.io.IOException; 4 import java.io.PrintWriter; 5 6 import javax.servlet.ServletException; 7 import javax.servlet.http.HttpServlet; 8 import javax.servlet.http.HttpServletRequest; 9 import javax.servlet.http.HttpServletResponse; 10 11 /** 继承自HttpServlet */ 12 public class HelloServlet extends HttpServlet { 13 14 /** 重写doGet方法 */ 15 @Override 16 protected void doGet(HttpServletRequest request, HttpServletResponse response) 17 throws ServletException, IOException { 18 System.out.println("处理get请求。。。"); 19 PrintWriter out = response.getWriter(); 20 out.println("<b>HelloServlet</b>"); 21 } 22 23 /** 重写doPost方法 */ 24 @Override 25 protected void doPost(HttpServletRequest request, HttpServletResponse response) 26 throws ServletException, IOException { 27 System.out.println("处理post请求。。。"); 28 PrintWriter out = response.getWriter(); 29 out.println("<b>HelloServlet</b>"); 30 } 31 32 }
二、在WEB-INF/web.xml中注册刚刚新建的Servlet:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app version="2.5" 3 xmlns="http://java.sun.com/xml/ns/javaee" 4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 5 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 6 http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> 7 <display-name></display-name> 8 <welcome-file-list> 9 <welcome-file>index.jsp</welcome-file> 10 </welcome-file-list> 11 12 <!-- 注册Servlet开始 --> 13 <servlet> 14 <servlet-name>HelloServlet</servlet-name> 15 <servlet-class>servlet.HelloServlet</servlet-class> 16 </servlet> 17 <servlet-mapping> 18 <servlet-name>HelloServlet</servlet-name> 19 <url-pattern>/servlet/HelloServlet</url-pattern> 20 </servlet-mapping> 21 <!-- 注册Servlet结束 --> 22 23 </web-app>
其中servlet-name表示Servlet的名字,servlet-class要写完成的类的定义(包名.类名),url-pattern表示Servlet的路径。
在index.jsp中使用自定义的Servlet处理get和post请求。
1 <%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%> 2 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 3 <html> 4 <head> 5 <title>手工编写的第一个Servlet</title> 6 </head> 7 8 <body> 9 <h1>第一个Servlet小例子</h1><hr> 10 <a href="servlet/HelloServlet">get方式请求HelloServlet</a><br /><br /> 11 <form action="servlet/HelloServlet" method="post"> 12 <input type="submit" value="post方式请求HelloServlet" /> 13 </form> 14 </body> 15 </html>
发布项目,运行结果:
一个Servlet可以在web.xml中配置多个映射,这样就可以在URL中使用不同的名字访问相同的Servlet。如下所示:就可以使用给人以假象——好像使用的是asp或者php或者更多的语言。
1 <!-- 注册Servlet开始 --> 2 <servlet> 3 <servlet-name>HelloServlet</servlet-name> 4 <servlet-class>servlet.HelloServlet</servlet-class> 5 </servlet> 6 <!-- 一个Servlet可以配置多个映射,向下面这样配置就可以有多种方式访问Servlet了 --> 7 <servlet-mapping> 8 <servlet-name>HelloServlet</servlet-name> 9 <url-pattern>/servlet/HelloServlet</url-pattern> 10 </servlet-mapping> 11 <servlet-mapping> 12 <servlet-name>HelloServlet</servlet-name> 13 <url-pattern>/servlet/HelloServlet.asp</url-pattern> 14 </servlet-mapping> 15 <servlet-mapping> 16 <servlet-name>HelloServlet</servlet-name> 17 <url-pattern>/servlet/HelloServlet.php</url-pattern> 18 </servlet-mapping> 19 <servlet-mapping> 20 <servlet-name>HelloServlet</servlet-name> 21 <!-- *表示任意名称均可 --> 22 <url-pattern>/servlet/hello/*</url-pattern> 23 </servlet-mapping> 24 <!-- 注册Servlet结束 -->
4.使用MyEclipse编写Servlet
1.src-->new Servlet。
2.重写doGet()或者doPost()方法。
3.部署运行。
通过MyEclipse创建Servlet的时候它默认继承自HttpServlet。默认勾选覆写init()、destory()、doGet()和doPost()方法,并且自动向web.xml中注册该Servlet。
可以发现使用MyEclipse创建的Servlet它已经自动为我们生成了输出的html模板,我们只需要做很少的改动即可。
5.Servlet的执行流程和生命周期
用户点击超链接向Servlet发送请求-->服务器在web.xml中的servlet-mapping寻找与该Servlet相对应的URL地址-->找到对应的Servlet名字-->根据Servlet的名字找到和该Servlet相关的处理类-->根据请求的方式不同确定是调用doGet还是doPost方法。
一个Servlet的生命周期大致分为3个阶段:
1.客户端发送请求给服务器。
2.服务器开始接受,先判断该请求的servlet实例是否存在,如果不存在先装载一个servlet类并创建实例。
如果存在则直接调用该servlet的service方法,之后进行判断是调用 doGet方法还是doPost方法。
3.servlet创建实例后,调用init方法进行初始化。之后调用servce方法,判断是调用doGet方法还是doPost方法。
4.最后判断服务器是否关闭,如果关闭则调用destroy方法。
下面这个例子展示了Servlet的生命周期:
首先是一个Servlet:TestServlet1
1 package servlet; 2 3 import java.io.IOException; 4 import java.io.PrintWriter; 5 6 import javax.servlet.ServletException; 7 import javax.servlet.http.HttpServlet; 8 import javax.servlet.http.HttpServletRequest; 9 import javax.servlet.http.HttpServletResponse; 10 11 public class TestServlet1 extends HttpServlet { 12 13 public TestServlet1() { 14 System.out.println("TestServlet1构造方法被执行!"); 15 } 16 17 public void destroy() { 18 System.out.println("TestServlet1销毁方法被执行!"); 19 } 20 21 public void doGet(HttpServletRequest request, HttpServletResponse response) 22 throws ServletException, IOException { 23 24 System.out.println("TestServlet1的doGet方法被执行!"); 25 response.setContentType("text/html;charset=utf-8"); 26 PrintWriter out = response.getWriter(); 27 out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">"); 28 out.println("<HTML>"); 29 out.println(" <HEAD><TITLE>A Servlet</TITLE></HEAD>"); 30 out.println(" <BODY>"); 31 out.println("<h1>你好我是TestServlet1</h1>"); 32 out.println(" </BODY>"); 33 out.println("</HTML>"); 34 out.flush(); 35 out.close(); 36 } 37 38 public void doPost(HttpServletRequest request, HttpServletResponse response) 39 throws ServletException, IOException { 40 System.out.println("TestServlet1的doPost方法被执行!"); 41 doGet(request, response);// 让doPost与doGet执行相同的操作 42 } 43 44 public void init() throws ServletException { 45 System.out.println("TestServlet1的初始化方法被执行!"); 46 } 47 48 }
主页index.jsp
1 <%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%> 2 <% 3 String path = request.getContextPath(); 4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 5 %> 6 7 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 8 <html> 9 <head> 10 <base href="<%=basePath%>"> 11 <title>Servlet的生命周期</title> 12 </head> 13 14 <body> 15 <h1>Servlet的生命周期</h1><hr /> 16 <a href = "servlet/TestServlet1">以get方式请求TestServlet1</a> 17 </body> 18 </html>
当服务器启动之后我们第一次访问index.jsp的时候,构造方法,初始化方法和doGet()方法执行
当我们再次请求该页面的时候,只有doGet()方法被执行:
服务器关闭的时候销毁方法执行。
6.Tomcat装载Servlet的3种情况
在下列时刻Servlet容器会加载Servlet:
1.Servlet容器启动时自动装载某些Servlet,实现它只需要在web.xml文件中的<servlet></servlet>之间添加以下代码:
<load-on-startup>1</load-on-startup>
其中,数字越小表示优先级越高。
例如:我们在web.xml中设置TestServlet2的优先级为1,而TestServlet1的优先级为2,启动和关闭Tomcat:
优先级高的先启动也先关闭。
2.客户端首次向某个Servlet发送请求。【例子详见Servlet生命周期的那个例子】
3.Servlet类被修改后,Tomcat容器会重新装载Servlet。
Servlet被装载后,Servlet容器会创建一个Servlet实例,并且调用Servlet的init()方法进行初始化,在Servlet的真个生命周期内init()方法只被调用一次。
7.Servlet与JSP内置对象的对应关系
8.Servlet获取表单数据
用户在reg.jsp中填写注册表单,使用post方式将数据发送到一个名称为servlet.RegServlet的Servlet处理【Servlet的doPost()方法】,Servlet将用户信息封装成一个Users对象存储在session中,讲请求转发到userinfo.jsp。在userinfo.jsp中通过<jsp:useBean>指令从session中取出保存的用户对象,通过<jsp:getPerproty>指令显示用户对象的各个字段。
1 package entity; 2 3 import java.util.Date; 4 5 /** 用户实体类 */ 6 public class Users { 7 private String username; 8 private String password; 9 private String email; 10 private String sex; 11 private Date birthday; 12 private String[] favorites; 13 private String introduce; // 自我介绍 14 private boolean flag; // 是否接受协议 15 16 public Users() { 17 } 18 19 public String getUsername() { 20 return username; 21 } 22 23 public void setUsername(String username) { 24 this.username = username; 25 } 26 27 public String getPassword() { 28 return password; 29 } 30 31 public void setPassword(String password) { 32 this.password = password; 33 } 34 35 public String getEmail() { 36 return email; 37 } 38 39 public void setEmail(String email) { 40 this.email = email; 41 } 42 43 public String getSex() { 44 return sex; 45 } 46 47 public void setSex(String sex) { 48 this.sex = sex; 49 } 50 51 public Date getBirthday() { 52 return birthday; 53 } 54 55 public void setBirthday(Date birthday) { 56 this.birthday = birthday; 57 } 58 59 public String[] getFavorites() { 60 return favorites; 61 } 62 63 public void setFavorites(String[] favorites) { 64 this.favorites = favorites; 65 } 66 67 public String getIntroduce() { 68 return introduce; 69 } 70 71 public void setIntroduce(String introduce) { 72 this.introduce = introduce; 73 } 74 75 public boolean isFlag() { 76 return flag; 77 } 78 79 public void setFlag(boolean flag) { 80 this.flag = flag; 81 } 82 83 }