Servlet初识
...大约 5 分钟
1. Servlet入门
1.1 概念
Servlet(server applet)是运行在服务器端的小程序。
- Servlet就是一个接口,定义了Java类被浏览器访问到(tomcat识别)的规则;
- 使用时需要自定义一个类来实现Servlet接口,复写Servlet接口的方法。
动态资源:不同的人访问的资源可能不一样。
1.2 快速入门
- 创建一个JavaWEB项目
- 定义一个类,实现Servlet接口,代码为
public class ServletDemo1 implements Servlet
- 覆写接口中的抽象方法
- 配置Servlet,在web.xml中配置Servlet,并映射虚拟路径。
- 启动Tomcat服务器,并访问相应虚拟路径;
1.3 执行原理
- 当服务器接收到客户端浏览器的请求后,会解析请求URL路径,获取访问的Servlet的资源路径;
- 查找web.xml文件,是否有对应的
<url-pattern>
标签体内容; - 如果有,则再找到对应的
<servlet-class>
全类名; - tomcat会将字节码文件加载进内存,并且创建其对象;
- 调用其方法。
1.4. Servlet的生命周期
Servlet中的生命周期主要有Servlet被创建时执行一次的init方法,提供服务的service方法和正常关闭服务器时执行一次的destroy方法。
1.4.1 init方法
被创建时执行init方法,只执行一次,Servlet默认情况下,第一次被访问时,Servlet被创建。
- 可以在web.xml中的
<servlet>
标签下配置执行Servlet的创建时机。- 第一次被访问时,创建;
<load-on-startup>
的值为负数 - 在服务器启动时,创建。
<load-on-startup>
的值为0或正整数
- 第一次被访问时,创建;
<servlet>
<servlet-name>demo1</servlet-name>
<servlet-class>hek.web.servlet.ServletDemo1</servlet-class>
<load-on-startup>-1</load-on-startup>
</servlet>
Servlet的init方法,只执行一次,说明一个Servlet在内存中只存在一个对象,Servlet是单例的。
- 多个用户同时访问时,可能存在线程安全问题。
- 解决方法:尽量不要在Servlet中定义成员变量。即使定义了成员变量,也不要对修改值
1.4.2 service方法
提供服务时执行service方法,可执行多次。
- 每次访问Servlet时,Service方法都会被调用一次。
1.4.3 destroy方法
被销毁时执行destroy方法,只执行一次。
- 服务器关闭时,Servlet被销毁。
- 只有服务器正常关闭时,才会执行destroy方法。
- destroy方法在Servlet被销毁之前执行,一般用于释放资源。
1.5 Servlet的注解配置
Servlet3.0以上支持注解配置。可以不需要web.xml了。
1.5.1 使用步骤
- 创建JavaEE项目,选择Servlet的版本3.0以上,不创建web.xml;
- 定义一个类,实现Servlet接口
- 复写Servlet的方法
- 在类上使用@WebServlet注解,进行配置,代码
@WebServlet("/资源路径")
。
资源路径必须加上反斜线,不然会报错。
1.5.2 实现原理
WebServlet的注解中对XML的配置给了默认值,可根据自己的需求进行传入参数,默认传入的为资源路径。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface WebServlet {
String name() default "";//相当于<Servlet-name>
String[] value() default {};//代表urlPatterns()属性配置
String[] urlPatterns() default {};//相当于<url-pattern>,这也是默认传入值
int loadOnStartup() default -1;//相当于<load-on-startup>
WebInitParam[] initParams() default {};
boolean asyncSupported() default false;
String smallIcon() default "";
String largeIcon() default "";
String description() default "";
String displayName() default "";
}
默认传入的是虚拟目录路径。
2. Servlet进阶
在入门阶段学习了Serlet的概念、使用步骤、执行原理、生命周期、注解配置。现在学习更多的Servlet的知识。
2.1 Servlet的体系结构
Servlet -- 接口
|
GenericServlet -- 抽象类
|
HttpServlet -- 抽象类
2.1.1 GenericServlet
将Servlet接口中其他的方法做了默认空实现,只将service()方法作为抽象方法,将来定义Servlet类时,可以继承GenericServlet,实现service()方法即可。
了解即可,真正开发时不用这种方式。
2.1.2 HttpServlet
对http协议的一种封装,简化操作。
2.1.2.1 使用步骤
- 定义类继承HttpServlet
- 复写doGet/doPost方法
//为保持简介已去掉导包代码
@WebServlet("/demo")
public class ServletDemo extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doPost...");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doGet...");
}
}
- 使用doGet方法,默认情况下直接访问该路径就是get请求,触发该方法。
- 使用doPost方法,最简单的方式为建立一个表单页面(login.html),然后访问表单的路径(/login.html),使用post方法将信息提交到/demo路径下。
<!-- web目录下的login.html 表单-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>login</title>
</head>
<body>
<form action="/demo" method="post">
<input type="text">
<button type="submit">提交</button>
</form>
</body>
</html>
2.2 Servlet访问路径
一个Servlet可以定义多个访问路径 ,如@WebServlet({"/d4","/dd4","/ddd4"})
,然后可以通过其中的任意一个路径进行访问到该资源。
2.2.1 路径定义规则
/xxx
:路径匹配/xxx/xxx
:多层路径,目录结构*.do
:扩展名匹配