Servlet
概念
server applet:运行在服务器端的小程序

- Servlet 是JavaEE 规范之一。Servlet就是一个接口,定义了Java类被浏览器访问到(tomcat识别)的规则。
- Servlet 是运行在服务器上的一个java 小程序,它可以接收客户端发送过来的请求,并响应数据给客户端。
- Servlet 就JavaWeb 三大组件之一。三大组件分别是:Servlet 程序、Filter 过滤器、Listener 监听器。
入门
创建JavaEE项目
定义一个类,实现Servlet接口
public class HelloServlet implements Servlet { /** * service 方法是专门用来处理请求和响应的 * @param servletRequest * @param servletResponse * @throws ServletException * @throws IOException */ @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { System.out.println("Hello Servlet 被访问了"); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14配置Servlet
在web.xml中配置:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!-- servlet 标签给Tomcat 配置Servlet 程序--> <servlet> <!--servlet-name 标签Servlet 程序起一个别名(一般是类名) --> <servlet-name>HelloServlet</servlet-name> <!--servlet-class 是Servlet 程序的全类名--> <servlet-class>cn.edu.buaa.servlet.HttpServletDemo</servlet-class> </servlet> <!--servlet-mapping 标签给servlet 程序配置访问地址--> <servlet-mapping> <!--servlet-name 标签的作用是告诉服务器,我当前配置的地址给哪个Servlet 程序使用--> <servlet-name>HelloServlet</servlet-name> <!--url-pattern 标签配置访问地址<br/> / 斜杠在服务器解析的时候,表示地址为:http://ip:port/工程路径<br/> /hello 表示地址为:http://ip:port/工程路径/hello <br/> --> <url-pattern>/hello</url-pattern> </servlet-mapping> </web-app>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
执行原理:
- 当服务器接受到客户端浏览器的请求后,会解析请求URL路径,获取访问的Servlet的资源路径
- 查找web.xml文件,是否有对应的
<url-pattern>
标签体内容。 - 如果有,则在找到对应的
<servlet-class>
全类名 - tomcat会将字节码文件加载进内存,并且创建其对象
- 调用其方法
生命周期方法
被创建
加载Servlet类
类加载器负责加载servlet类。 当Web容器接收到servlet的第一个请求时,将加载servlet类。
创建Servlet实例
Web容器在加载servlet类之后创建一个servlet的实例。servlet实例在servlet生命周期中只创建一次。
执行init方法,只执行一次
Web容器在创建servlet实例后调用init
方法一次。 init
方法用于初始化servlet。 它是javax.servlet.Servle
t接口的生命周期方法。init方法的语法如下:
public void init(ServletConfig config) throws ServletException
Servlet什么时候被创建?
默认情况下,第一次被访问时,Servlet被创建
可以配置执行Servlet的创建时机。
在
<servlet>
标签下配置第一次被访问时,创建
<load-on-startup>
的值为负数
在服务器启动时,创建
<load-on-startup>
的值为0或正整数
Servlet的init方法,只执行一次,说明一个Servlet在内存中只存在一个对象,Servlet是单例的
多个用户同时访问时,可能存在线程安全问题。
- 解决:尽量不要在Servlet中定义成员变量。即使定义了成员变量,也不要对其修改值
提供服务
执行service方法,执行多次。每当接收到servlet的请求时,Web容器都会调用service
方法。如果servlet未初始化,则遵循上述前三个步骤,然后调用service
方法。 如果servlet被初始化,它调用service
方法。 请注意,servlet仅初始化一次。 Servlet接口的service
方法的语法如下:
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException
- 每次访问Servlet时,Service方法都会被调用一次。
销毁
执行destroy方法,只执行一次
- Servlet被销毁时执行。服务器关闭时,Servlet被销毁
- 只有服务器正常关闭时,才会执行destroy方法。
- destroy方法在Servlet被销毁之前执行,一般用于释放资源
从服务中删除servlet实例之前,Web容器调用destroy
方法。它使servlet有机会清理所有资源,例如内存,线程等。Servlet接口的destroy
方法的语法如下:
public void destroy()
在如下几种情况下,会调用destroy()
- 该Servlet所在的web应用重新启动 在server.xml中配置该web应用的时候用到了
<Context path="/" docBase="e:\\project\\j2ee\\web" debug="0" reloadable="false" />
如果把 reloadable="false" 改为reloadable="true" 就表示有任何类发生的更新,web应用会自动重启当web应用自动重启的时候,destroy()方法就会被调用
- 关闭tomcat的时候 destroy()方法会被调用,但是这个一般都发生的很快,不易被发现。
被回收 当该Servlet被销毁后,就满足垃圾回收的条件了。 当下一次垃圾回收GC来临的时候,就有可能被回收。
Servlet3.0:
好处:
- 支持注解配置。可以不需要web.xml了。
步骤:
- 创建JavaEE项目,选择Servlet的版本3.0以上,可以不创建web.xml
- 定义一个类,实现Servlet接口
- 复写方法
- 在类上使用@WebServlet注解,进行配置
- @WebServlet("资源路径")
@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
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Servlet的体系结构
Servlet -- 接口 | GenericServlet -- 抽象类 | HttpServlet -- 抽象类
GenericServlet:将Servlet接口中其他的方法做了默认空实现,只将service()方法作为抽象
- 将来定义Servlet类时,可以继承GenericServlet,实现service()方法即可
HttpServlet:对http协议的一种封装,简化操作
定义类继承HttpServlet,复写doGet/doPost方法
public class HttpServletDemo extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("doGet...."); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("doPost...."); } }
1
2
3
4
5
6
7
8
9
10
11
12
ServletConfig
ServletConfig
对象是由每个servlet的Web容器创建的。这个对象可用于从web.xml
文件获取配置信息。
如果从web.xml
文件修改配置信息,就不需要更改servlet中的代码。因此,对于有特定配置内容需要不定时修改,这样会更容易管理Web应用程序。
ServletConfig的优点
ServletConfig
的核心优点是,如果可以修改web.xml文件中的信息,则不需要编辑servlet代码文件。
1、可以获取Servlet 程序的别名servlet-name 的值
2、获取初始化参数init-param
3、获取ServletContext 对象
ServletConfig接口的方法
编号 | 方法 | 描述 |
---|---|---|
1 | public String getInitParameter(String name) | 返回指定参数名称的参数值。 |
2 | public Enumeration getInitParameterNames() | 返回所有初始化参数名称的枚举。 |
3 | public String getServletName() | 返回servlet的名称。 |
4 | public ServletContext getServletContext() | 返回ServletContext的对象。 |
- 可通过调用Servlet接口的
getServletConfig()
方法来返回ServletConfig
对象。
public ServletConfig getServletConfig();
为servlet提供初始化参数的语法
servlet的init-param
子元素用于指定servlet的初始化参数。
<web-app>
<servlet>
......
<init-param>
<param-name>parameter_name</param-name>
<param-value>parameter_value</param-value>
</init-param>
......
</servlet>
</web-app>
2
3
4
5
6
7
8
9
10
获取初始化参数的ServletConfig示例
ConfigServlet.java
public class ConfigServlet extends HttpServlet {
private static final long serialVersionUID =1L;
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
// 设置服务器内容类型
response.setContentType("text/html");
// 获取服务器输出对象
PrintWriter out = response.getWriter();
// 获取ServletConfig
ServletConfig config = getServletConfig();
String driver = config.getInitParameter("mysql_driver");
out.println("driver details is <b>"+driver+"</b>");
out.close();
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
dbConfig.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ServletConfig</title>
</head>
<body>
<div style="text-align: center">
请<a href="dbConfig">点击这里</a>查看所有配置信息
</div>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
12
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>ServletRequest</display-name>
<welcome-file-list>
<welcome-file>dbConfig.html</welcome-file>
<welcome-file>redirect.html</welcome-file>
<welcome-file>forward.html</welcome-file>
<welcome-file>head.html</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>ConfigServlet</servlet-name>
<servlet-class>ConfigServlet</servlet-class>
<init-param>
<param-name>mysql_driver</param-name>
<param-value>com.mysql.jdbc.Driver</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>ConfigServlet</servlet-name>
<url-pattern>/dbConfig</url-pattern>
</servlet-mapping>
</web-app>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
ServletContext
ServletContext
的对象由Web容器在部署项目时创建。代表整个web应用,可以和程序的容器(服务器)来通信。 该对象可用于从web.xml
文件获取配置信息。 每个Web应用程序只有一个ServletContext
对象。如果有信息要共享给多个servlet使用,最好在web.xml
文件中使用<context-param>
元素提供它。
优点
如果有任何信息要共享给所有的servlet使用,并且要让它容易维护,最好的办法就是在web.xml
文件中提供这些信息,所以如果信息要更改直接在web.xml
中修改,而不需要修改servlet代码。
1、获取web.xml 中配置的上下文参数context-param
2、获取当前的工程路径,格式: /工程路径
3、获取工程部署后在服务器硬盘上的绝对路径
4、像Map 一样存取数据
ServletContext
接口的使用
有很多ServletContext对象可以使用。 其中一些如下:
- ServletContext对象提供容器和servlet之间的接口。
- 使用ServletContext对象在
web.xml
文件获取配置信息。 - ServletContext对象可用于设置,获取或删除
web.xml
文件中属性。 - ServletContext对象可用于提供应用程序间通信。
常用的ServletContext
接口方法
序号 | 方法 | 描述 |
---|---|---|
1 | public String getInitParameter(String name) | 返回指定参数名称的参数值。 |
2 | public Enumeration getInitParameterNames() | 返回上下文的初始化参数的名称。 |
3 | public void setAttribute(String name,Object object) | 在应用程序范围内设置给定的对象。 |
4 | public Object getAttribute(String name) | 返回指定名称的属性。 |
5 | public Enumeration getInitParameterNames() | 返回上下文的初始化参数的名称,作为String对象的枚举。 |
6 | public void removeAttribute(String name) | 从servlet上下文中删除给定名称的属性。 |
- 通过
ServletConfig
接口的getServletContext()
方法返回ServletContext
对象。 - 通过
GenericServlet
类的getServletContext()
方法返回ServletContext
对象。
获取MIME类型:
MIME类型:在互联网通信过程中定义的一种文件数据类型
- 格式: 大类型/小类型 text/html image/jpeg
获取:
String getMimeType(String file)
域对象:共享数据
- setAttribute(String name,Object value)
- getAttribute(String name)
- removeAttribute(String name)
- ServletContext对象范围:所有用户所有请求的数据
获取文件的真实(服务器)路径
方法:String
getRealPath(String path)
String b = context.getRealPath("/b.txt");//web目录下资源访问 System.out.println(b); String c = context.getRealPath("/WEB-INF/c.txt");//WEB-INF目录下的资源访问 System.out.println(c); String a = context.getRealPath("/WEB-INF/classes/a.txt");//src目录下的资源访问 System.out.println(a);
1
2
3
4
5
6
7
8
在Context
范围内提供初始化参数的语法
Web应用程序的context-param
元素的子元素用于定义应用程序范围中的初始化参数。 参数名称和参数值是context-param
的子元素。param-name
元素定义参数名称,param-value
定义其值。参考以下配置代码片段 -
<web-app>
......
<context-param>
<param-name>parameter_name</param-name>
<param-value>parameter_value</param-value>
</context-param>
......
</web-app>
2
3
4
5
6
7
8
获取初始化参数的ServletContext
示例
ContextServlet.java
public class ContextServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
// 设置服务器内容类型
response.setContentType("text/html");
// 获取服务器的输出对象
PrintWriter out = response.getWriter();
// 获取ServletContext对象
ServletContext context = getServletContext();
String driverName = context.getInitParameter("dname");
out.println("driver name is <b>"+driverName+"</b>");
out.close();
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Context.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ContextServlet</title>
</head>
<body>
<div style="text-align: center">
请<a href="context">点击这里</a>查看Context信息
</div>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
12
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>ContextServlet</display-name>
<welcome-file-list>
<welcome-file>Context.html</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>ContextServlet</servlet-name>
<servlet-class>ContextServlet</servlet-class>
</servlet>
<context-param>
<param-name>dname</param-name>
<param-value>com.mysql.jdbc.Driver</param-value>
</context-param>
<servlet-mapping>
<servlet-name>ContextServlet</servlet-name>
<url-pattern>/context</url-pattern>
</servlet-mapping>
</we-app>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Servlet相关配置
- urlpartten:Servlet访问路径
- 一个Servlet可以定义多个访问路径 : @WebServlet({"/d4","/dd4","/ddd4"})
- 路径定义规则:
- /xxx:路径匹配
- /xxx/xxx:多层路径,目录结构
- *.do:扩展名匹配
HttpServletRequest
获取所有请求的信息