- Servlet 是驻留在服务器内存中运行的小程序;
- 一个 Servlet 就是一个 Java 类,且可以通过“请求 - 响应”模型来访问;
- 与 JSP 的模式相反,JSP 是在页面中嵌入 Java 代码,Servlet
是在类中嵌入 HTML 代码。
Tomcat 容器等级
Tomcat 容器分为四个等级,Servlet 的容器管理 Content 容器,一个 Context 对应一个 Web 工程。
Tomcat 容器等级
自己实现 Servlet
- 继承
HttpServlet
类; - 重写
doGet()
方法或doPost()
方法(不需要覆盖service()
方法,service()
会自行调用 doX); - 在 web.xml 中注册 Servlet。
index.jsp
GET 请求 HelloServlet
HelloServlet.java
public class HelloServlet extends HttpServlet {
public HelloServlet() { super();}
public void destroy() { super.destroy();}
public void init() throws ServletException {}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("Get...");
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("");
out.println("");
out.println(" A Servlet ");
out.println(" ");
out.println("Hello Servlet!
");
out.println(" ");
out.println("");
out.flush();
out.close();
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("Post...");
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("");
out.println("");
out.println(" A Servlet ");
out.println(" ");
out.println("Hello Servlet!
");
out.println(" ");
out.println("");
out.flush();
out.close();
}
}
web.xml
This is the description of my J2EE component
This is the display name of my J2EE component
HelloServlet
servlet.HelloServlet
HelloServlet
/servlet/hello
index.jsp
Servlet 执行流程与生命周期
- 用户在浏览器点击
- 匹配 web.xml 中的
/servlet/hello - 根据匹配 URL 获取对应的 Servlet 类
HelloServlet - 根据请求方式执行 Servlet 类的 doX 方法
Servlet 经历以下生命周期:
- 初始化、加载、实例化:判断 Servlet 实例是否存在,如不存在则装载 Servlet 类并创建实例(调用构造方法)、调用
init
(ServletConfig)方法; - 响应客户端请求:调用
service
(Servlet Request Servlet Response)方法,并决定调用 doX 方法; - 当服务器关闭时,调用
destroy
方法。
Tomcat 装载 Servlet
在下列时刻 Servlet 容器(如 Tomcat)装载 Servlet:
- 容器启动时自动装载:在 web.xml 文件中添加:
...
1
- 在 Servlet 容器启动后,客户首次向 Servlet 发送请求;
- Servlet 类文件被更新后,重新装载 Servlet。
Servlet 被装载后,Serlet 容器创建一个 Servlet 实例并且调用其 init()
方法进行初始化(整个生命周期中只调用一次)。
Servlet 与 JSP 的关系
Servlet 与九大内置对象
Servlet 获取表单数据
entity/User.java
// 用户实体类
public class Users {
private String username; //用户名
private String mypassword; //密码
private String email; //电子邮箱
private String gender; //性别
private Date birthday; //出生日期
private String[] favorites; //爱好
private String introduce; //自我介绍
private boolean flag; //是否接受协议
public Users() {}
// ...省略 getter 和 setter
}
servlet/RegServlet.java
import entity.Users;
public class RegServlet extends HttpServlet {
public RegServlet() {super();}
public void destroy() {super.destroy();}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
Users u = new Users();
String username, mypassword, gender, email, introduce, isAccept;
Date birthday;
String[] favorites;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
username = request.getParameter("username");
mypassword = request.getParameter("mypassword");
gender = request.getParameter("gender");
email = request.getParameter("email");
introduce = request.getParameter("introduce");
birthday = sdf.parse(request.getParameter("birthday"));
if (request.getParameterValues("isAccpet") != null)
isAccept = request.getParameter("isAccept");
else
isAccept = "false";
favorites = request.getParameterValues("favorite");
u.setUsername(username);
u.setMypassword(mypassword);
u.setGender(gender);
u.setEmail(email);
u.setFavorites(favorites);
u.setIntroduce(introduce);
if (isAccept.equals("true"))
u.setFlag(true);
else
u.setFlag(false);
u.setBirthday(birthday);
request.getSession().setAttribute("regUser", u); // 在 JavaBean 中 id 为 “regUser”
request.getRequestDispatcher("../userinfo.jsp").forward(request, response);
} catch (Exception ex) {
ex.printStackTrace();
}
}
public void init() throws ServletException {
// Put your code here
}
}
reg.jsp
用户注册
userinfo.jsp
<%@ page language="java" import="java.util.*,java.text.*" contentType="text/html; charset=utf-8"%>
用户信息
用户名:
密码:
性别:
E-mail:
出生日期:
<%
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
String date = sdf.format(regUser.getBirthday());
%>
<%=date%>
爱好:
<%
String[] favorites = regUser.getFavorites();
for (String f : favorites) {
%>
<%=f%>
<%
}
%>
自我介绍:
是否介绍协议:
路径跳转
相对路径访问 Servlet
访问HelloServlet!
绝对路径访问 Servlet
<%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";
%>
访问HelloServlet!
重定向
// 请求重定向方式跳转到 test.jsp ,当前路径是 ServletPathDirection/servlet/
response.sendRedirect("test.jsp");
// 使用 request.getContextPath 获得上下文对象
response.sendRedirect(request.getContextPath() + "/test.jsp");
服务器内跳转
// 服务器内部跳转,的斜线表示项目的根目录
request.getRequestDispatcher("/test.jsp").forward(request, response); // 绝对路径
request.getRequestDispatcher("../test.jsp").forward(request, response); // 相对路径