Servlet概述
什么是Servlet?
Servlet是在服务器上运行的小程序。一个Servlet就是一个Java类,并且可以通过“请求—响应”编程模型来访问的这个驻留在服务器内存里的Servlet程序。
Tomcat容器等级
Tomcat的容器分为四个等级,Servlet的容器管理Context容器,一个Context对应一个Web工程。
使用eclipse手工编写第一个Servlet
1.继承HttpServlet
2.重写doGet()或者doPost()方法
3.在Web.xml中注册Servlet
首先在新创建的WebProject里面,添加一个包servlet,创建一个HelloServlet的类,继承与HttpServlet。
然后重写doGet和doPost方法
代码示例:
HelloServlet.java类
package servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//继承于HttpServlet
public class HelloServlet extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
System.out.println("处理Get()请求...");
PrintWriter out =response.getWriter();
//指定文件的输出类型
response.setContentType("text/html;charset=utf-8");
out.println("<strong>Hello Servlet!</strong><br>");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
System.out.println("处理Post()请求...");
PrintWriter out =response.getWriter();
//指定文件的输出类型
response.setContentType("text/html;charset=utf-8");
out.println("<strong>Hello Servlet!</strong><br>");
}
}
web.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>MyFirstServletDemo</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<!-- 和上面的<servlet-name>是一一对应的关系 -->
<servlet-name>HelloServlet</servlet-name>
<!-- 表示名字叫做HelloServlet这个servlet的访问路径,要和界面上写的超链接一一对应 -->
<url-pattern>/servlet/HelloServlet</url-pattern>
</servlet-mapping>
</web-app>
index.jsp文件
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>第一个Servlet小例子</h1>
<hr>
<a href="servlet/HelloServlet">Get方式请求HelloServlet</a><br>
<form action="servlet/HelloServlet" method="post">
<input type="submit" value="Post方式请求HelloServlet" />
</form>
</body>
</html>
练习
假设在helloapp应用中有一个HelloServlet类,它在 web.xml文件中的配置如下:
<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>org.javathinker.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
那么在浏览器端访问HelloServlet的URL是什么?
答案是:http:localhost:8080:helloapp/hello
解析:
localhost是服务器主机名,也可以是IP地址127.0.0.1;8080是tomcat服务器的端口号;helloapp是web工程的上下文地址ContexRoot(一般情况下与web工程名一致);最后是<url-pattern/>
标签中的内容。
Servlet执行流程和生命周期
生命周期:
1、初始化阶段,调用init()方法
2.响应客户请求阶段,调用service()方法。由service()方法根据提交方式选择执行doGet()或者doPost()方法。
3.终止阶段,调用destroy方法。
问答:
编写Servlet的doPost方法时,需要抛出异常为?
编写Servlet的doPost方法时,需要抛出ServletExcpetion和IOException异常。
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
在myeclipse中新建一个Servlet,可以看到自动生成的代码中会抛出ServletException和IOException
doGet和doPost抛出的异常类型是一样的
* @throws ServletException if an error occurred
* @throws IOException if an error occurred
Tomcat装载Servlet的三种情况
Servlet生命周期:
在下列时刻Servlet容器装载Servlet:
1.Servlet容器启动时,自动装载某些Servlet,实现它只需要在web.xml文件中的<Servlet></Servlet>
之间添加如下代码:<loadon-startup>1</loadon-startup>
数字越小表示优先级越高。
2.在Servlet容器启动后,客户首次向Servlet发送请求。
3.Servlet类文件被更新后,重新装载Servlet。
Servlet被装载后,Servlet容器创建一个Servlet实例并且调用Servlet的init()方法进行初始化。在Servlet的整个生命周期内,init()方法只被调用一次。
代码示例:
新建ServletLifeCycleDemo工程
TestServlet1.java文件
package servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class TestServlet1
*/
@WebServlet("/TestServlet1")
public class TestServlet1 extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public TestServlet1() {
System.out.println("TestServlet1构造方法被执行...");
}
public void destroy() {
System.out.println("TestServlet1销毁方法被执行...");
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("TestServlet1的doGet()方法被执行");
// 指定文件的输出类型
response.setContentType("text/html;charset=utf-8");
PrintWriter out =response.getWriter();
out.println("<h1>您好,我是TestServlet1</h1><br>");
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
System.out.println("TestServlet1的doPost()方法被执行");
doGet(request, response);// 让doPost()执行与doGet()相同的操作
}
public void init() throws ServletException{
System.out.println("TestServlet1的初始化方法被执行");
}
}
TestServlet2.java文件代码内容与TestServlet1,只是修改一下输出内容把1变为2
web.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>ServletLifeCycleDemo</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>TestServlet1</servlet-name>
<servlet-class>servlet.TestServlet1</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet>
<servlet-name>TestServlet2</servlet-name>
<servlet-class>servlet.TestServlet2</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>TestServlet1</servlet-name>
<url-pattern>/servlet/TestServlet1</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>TestServlet2</servlet-name>
<url-pattern>/servlet/TestServlet2</url-pattern>
</servlet-mapping>
</web-app>
index.jsp文件
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>Servlet生命周期</h1>
<hr>
<a href="servlet/TestServlet1">以Get方式请求TestServlet1</a>
</body>
</html>
Servlet与JSP内置对象的对应关系
Servlet获取表单数据
代码示例:
Users.java类
package entity;
//用户实体类
public class Users {
private String username;// 用户名
private String mypassword;// 密码
private String email;// 邮箱
private String gender;// 性别
private String[] favorites;// 爱好
private boolean flag;// 是否接受协议
public Users() {
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getMypassword() {
return mypassword;
}
public void setMypassword(String mypassword) {
this.mypassword = mypassword;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String[] getFavorites() {
return favorites;
}
public void setFavorites(String[] favorites) {
this.favorites = favorites;
}
public boolean isFlag() {
return flag;
}
public void setFlag(boolean flag) {
this.flag = flag;
}
}
RegServlet.java类
package servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import entity.Users;
/**
* Servlet implementation class RegServlet
*/
@WebServlet("/RegServlet")
public class RegServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
// private String introduce;
/**
* @see HttpServlet#HttpServlet()
*/
public RegServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
Users u = new Users();
String username, mypassword, gender, email, isAccept;
String[] favorites;
try {
username = request.getParameter("username");
mypassword = request.getParameter("mypassword");
gender = request.getParameter("gender");
email = request.getParameter("email");
isAccept = request.getParameter("flag");
System.out.println(isAccept);
// 用来获取多个复选按钮的值
favorites = request.getParameterValues("favorites");
u.setUsername(username);
u.setMypassword(mypassword);
u.setGender(gender);
u.setEmail(email);
u.setFavorites(favorites);
if ("true".equals(isAccept)) {
u.setFlag(true);
} else {
u.setFlag(false);
}
// 把注册成功的用户对象保存在session中
request.getSession().setAttribute("regUser", u);
// 跳转到注册成功页面
request.getRequestDispatcher("../reginfo.jsp").forward(request, response);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
reg.jsp文件
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<style type="text/css">
.label {
width: 20%
}
.controler {
width: 80%
}
</style>
<script type="text/javascript" src="js/Calendar3.js"></script>
</head>
<body>
<h1>用户注册</h1>
<hr>
<form name="regForm" action="servlet/RegServlet" method="post">
<table border="0" width="800" cellspacing="0" cellpadding="0">
<tr>
<td class="lalel">用户名:</td>
<td class="controler"><input type="text" name="username" /></td>
</tr>
<tr>
<td class="label">密码:</td>
<td class="controler"><input type="password" name="mypassword"></td>
</tr>
<tr>
<td class="label">确认密码:</td>
<td class="controler"><input type="password" name="confirmpass"></td>
</tr>
<tr>
<td class="label">电子邮箱:</td>
<td class="controler"><input type="text" name="email"></td>
</tr>
<tr>
<td class="label">性别:</td>
<td class="controler"><input type="radio" name="gender"
checked="checked" value="Male">男<input type="radio"
name="gender" value="Female">女</td>
</tr>
<tr>
<td class="label">爱好:</td>
<td class="controler"><input type="checkbox" name="favorite"
value="nba"> NBA <input type="checkbox"
name="favorite" value="music"> 音乐 <input
type="checkbox" name="favorite" value="movie"> 电影 <input
type="checkbox" name="favorite" value="internet"> 上网
</td>
</tr>
<tr>
<td class="label">接受协议:</td>
<td class="controler"><input type="checkbox" name="flag"
value="true">是否接受霸王条款</td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit" value="注册" />
<input type="reset" value="取消" /> </td>
</tr>
</table>
</form>
</body>
</html>
reginfo.jsp文件
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.util.*" %>
<%@ page import="java.text.*" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<style type="text/css">
.title {
width: 30%;
background-color: #CCC;
font-weight: bold;
}
.content {
width: 70%;
background-color: #CBCFE5;
}
</style>
</head>
<body>
<h1>用户信息</h1>
<hr>
<center>
<jsp:useBean id="regUser" class="entity.Users" scope="session" />
<table width="600" cellpadding="0" cellspacing="0" border="1">
<tr>
<td class="title">用户名:</td>
<td class="content"> <jsp:getProperty name="regUser"
property="username" /></td>
</tr>
<tr>
<td class="title">密码:</td>
<td class="content"> <jsp:getProperty name="regUser"
property="mypassword" /></td>
</tr>
<tr>
<td class="title">性别:</td>
<td class="content"> <jsp:getProperty name="regUser"
property="gender" /></td>
</tr>
<tr>
<td class="title">E-mail:</td>
<td class="content"> <jsp:getProperty name="regUser"
property="email" /></td>
</tr>
<tr>
<td class="title">是否介绍协议:</td>
<td class="content"> <jsp:getProperty name="regUser"
property="flag" /></td>
</tr>
</table>
</center>
</body>
</html>
Servlet路径跳转
绝对路径:放之四海而皆准的路径
相对路径:相对于当前资源的路径
代码示例:
HelloServlet.java
package servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class HelloServlet
*/
@WebServlet("/HelloServlet")
public class HelloServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public HelloServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(request, response);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
// 指定文件的输出类型
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
out.println("<h1>您好,我是HelloServlet</h1><br>");
}
}
TestServlet.java
package servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class TestServlet
*/
@WebServlet("/TestServlet")
public class TestServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public TestServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(request, response);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
// 请求重定向方式跳转到test.jsp,当前路径是ServletPathDirection/servlet/test.jsp显然是错误的
//使用request.getContextPath获得上下文对象
//response.sendRedirect(request.getContextPath() + "/test.jsp");
//服务器内部跳转,第一种这里的斜线表示项目的根目录
//request.getRequestDispatcher("/test.jsp").forward(request, response);
//第二种
request.getRequestDispatcher("../test.jsp").forward(request, response);
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>ServletLifeCycleDemo</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>servlet.HelloServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>TestServlet</servlet-name>
<servlet-class>servlet.TestServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/servlet/HelloServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>TestServlet</servlet-name>
<url-pattern>/servlet/TestServlet</url-pattern>
</servlet-mapping>
</web-app>
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String path=request.getContextPath();
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>Servlet路径跳转</h1>
<hr>
<!-- 使用相对路径访问HelloServlet -->
<!-- /HelloServlet 第一个/表示服务器的根目录 -->
<a href="servlet/HelloServlet">访问HelloServlet</a><br>
<!-- 使用绝对路径访问HelloServlet,可以使用path变量:path变量表示项目的根目录 -->
<a href="<%=path%>/servlet/HelloServlet">访问HelloServlet</a><br>
<!-- 表单中action的URL地址写法,与超链接方式完全相同 -->
<a href="servlet/TestServlet">访问TestServlet,跳转到test.jsp</a>
</body>
</html>
test.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String path=request.getContextPath();
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>Test.jsp</h1>
<hr>
</body>
</html>