什么是Servlet
Servlet是Server Applet(服务器小程序),运行在服务器上,可以接受客户端的请求,对后台数据库进行增删改查操作,为用户提供数据服务。
实现Servlet
Servlet相关API
- Servlet接口
- GenericServlet类(实现Servlet接口)
- HttpServlet类(继承GenericServlet类)
实现Servlet有三种方式
- 继承HttpServlet类
主要方法:
- doGet 处理Get请求
- doPost 处理POST请求
- doPut …
- doDelete
- doTrace
- doHead
- doOptions
- service 服务,通过请求参数,调用doXXX方法
doXXX方法都有默认实现,可以根据需要实现
- 继承GenericServlet类
主要方法:
- init 进行初始化
- service 抽象方法,必须实现,为用户提供服务
- destroy 销毁
- 实现Servlet接口
主要方法:
- init 初始化
- service 服务
- destory 销毁
- getServletConfig 获取配置信息
- getServletInfo 获得Servlet信息
实现上面所有方法
Servlet的配置
Servlet定义后,需要在服务器配置,用户才能访问到。
在web.xml配置
<!-- 注册MyServlet -->
<servlet>
<!-- Servlet的名字 -->
<servlet-name>MyServlet</servlet-name>
<!-- Servlet的包名+类名 -->
<servlet-class>com.java29.MyServlet</servlet-class>
</servlet>
<!-- 配置MyServlet的访问地址 -->
<servlet-mapping>
<!-- Servlet的名字 -->
<servlet-name>MyServlet</servlet-name>
<!-- 网络地址 -->
<url-pattern>/MyServlet.do</url-pattern>
</servlet-mapping>
调用过程:
web.xml其它的配置:
<!-- 设置欢迎页面文件 -->
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<!-- 配置错误页面 -->
<error-page>
<!-- 错误代码 -->
<error-code>404</error-code>
<!-- 页面地址 -->
<location>/404.html</location>
</error-page>
Servlet3.0支持,使用WebServlet注解配置
在类前面加:
@WebServlet("/Servlet的URL")
对比两种注册方法:
- 使用注解比较简单,缺点是使用硬编码方式进行注册,后面如果需要修改就需要修改源代码。
- 使用XML比较繁琐,优点是XML可以在网站部署后进行修改。
Servlet的生命周期
Servlet的生命周期是由服务器来进行管理的,主要的生命周期有:
- 实例化
用户第一次访问该Servlet类时,就会创建一个Servlet的实例,该实例保存在Tomcat中。(注意一个Servlet类只有一个实例)
默认情况下,Servlet第一次被访问时被创建
在标签下配置执行Servlet的创建时机
- 第一次被访问时创建
<load-on-startup>负数</load-on-startup>
- 在服务器启动时创建
<load-on-startup>0或正整数</load-on-startup>
- 初始化
init方法,用户第一次访问时,先实例化,然后初始化 - 服务
调用service方法,给用户提供服务,用户每访问一次,就调用一次 - 销毁
调用destroy方法,释放各种资源,在Tomcat关闭时调用
案例代码:
/**
* 测试Servlet的生命周期
*/
@WebServlet("/lifecircle.do")
public class LifecircleServlet extends HttpServlet{
public LifecircleServlet(){
System.out.println("实例化LifecircleServlet");
}
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
super.service(req, res);
System.out.println("LifecircleServlet进行服务");
}
@Override
public void destroy() {
super.destroy();
System.out.println("LifecircleServlet进行销毁");
}
@Override
public void init() throws ServletException {
super.init();
System.out.println("LifecircleServlet进行初始化");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("LifecircleServlet调用doGet");
}
}
Servlet的请求和响应参数
service方法用于处理用户请求,参数:
- HttpServletRequest 请求参数,包含请求URL、方法、参数等信息
主要方法:- String getParameter(“参数名”) 获得请求中的参数
- setCharacterEncoding(“编码类型”) 设置请求的编码
- getMethod() 获得请求方法类型,Get、POST…
- getRequestURL() 获得请求的URL
- HttpServletResponse 响应参数,给浏览器提供响应的交互
主要方法:- PrintWriter getWriter() 获得输出流,向浏览器发送信息
- sendRedirect(“页面地址”) 实现页面的跳转
- setCharacterEncoding(“编码类型”) 设置响应的编码
案例:Servlet接受浏览器发送的请求参数
@WebServlet("/register.do")
public class RegisterServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doGet");
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求的编码
req.setCharacterEncoding("UTF-8");
//设置响应的编码
resp.setContentType("text/html;charset=UTF-8");
//获得请求参数
String username = req.getParameter("username");
//解决get提交参数的中文乱码
//username = new String(username.getBytes("ISO-8859-1"),"UTF-8");
String password = req.getParameter("password");
String pid = req.getParameter("pid");
String phone = req.getParameter("phone");
//输出参数
System.out.println(username+","+password+","+pid+","+phone);
//获得响应对象的输出流
PrintWriter pw = resp.getWriter();
pw.println(username+"你好啊");
pw.close();
}
}
客户端表单:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>用户的注册</title>
</head>
<body>
<form action="register.do" method="post">
<table width="50%">
<tr>
<td>账号</td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td>密码</td>
<td><input type="password" name="password"></td>
</tr>
<tr>
<td>身份证号</td>
<td><input type="text" name="pid"></td>
</tr>
<tr>
<td>手机号</td>
<td><input type="text" name="phone"></td>
</tr>
<tr>
<td cospan="2">
<input type="submit" value="注册">
</td>
</tr>
</table>
</form>
</body>
</html>
中文乱码问题
页面或表单中包含中文,可能出现乱码。
对于不同的乱码情况,有不同的解决方法:
- html页面中
<meta charset="utf-8">
- doGet方法的请求参数
String name = req.getParameter("name");
name = new String(name.getBytes("ISO-8859-1"),"UTF-8");
- doPost方法的请求参数
req.setCharacterEncoding("UTF-8");
- 响应对象的输出流
resp.setContentType("text/html;charset=UTF-8");
- JSP中
在page指令中设置pageEncoding="UTF-8"
Servlet的线程安全问题
Servlet是单实例多线程的,Tomcat中每一个Servlet类只会创建一个实例,不同用户访问该实例时,为了不会相互影响,Tomcat会开启子线程为每个用户进行服务。
注意:Servlet的成员变量,可能出现线程同步问题,一般情况下最好不定义成员变量,使用局部变量。