什么是Servelt?
它是java动态web的技术,是javaweb开发的基石,它是运行在Web应用服务器中(Tomcat),sun公司提供了一个API接口叫做Servlet,需要使用Servlet开发,必须实现这个接口中的方法,就可以实现接收客户端以及做出响应给浏览器
准备工作
- 需要导入javax.servlet-api和javax.servlet.jsp-api(运行jsp需要的jar包)
maven则添加依赖
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp/javax.servlet.jsp-api -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.3</version>
<scope>provided</scope>
</dependency>
- 编写一个Servlet类,实现Servlet接口
public class HelloWorldServlet implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
//在servlet创建时执行,且只执行一次
}
@Override
public ServletConfig getServletConfig() {
//获取Servlet配置
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
//提供服务的方法,每一次servlet被访问时执行,可多次执行
System.out.println("hello world");
//设置响应体的内容类型以及编码方式
servletResponse.setContentType("text/html;charset=UTF-8");
//通过流输出到浏览器
servletResponse.getWriter().write("你好,Hello World");
}
@Override
public String getServletInfo() {
//获取Servlet信息,版本,作者等等
return null;
}
@Override
public void destroy() {
//销毁方法,在服务器正常关闭servlet被销毁时执行,只执行一次。
}
}
- 配置web服务器(这里用的是tomcat)
启动tomcat
- 默认访问webapp(web)下面的index.jsp页面
服务器内执行原理
- 当我们在启动Tomcat服务器时,会将当前工程打包成一个war包,可以看到该目录下有index.jsp文件,当我们浏览器请求访问该路径时可以响应给客户端页面
- 而该目录下有一个WEB-INF目录,它里面有我们写的一个Servle类,当我们按照这个路径访问时,并不能访问到,原因是它已经规定了WEB-INF目录下的资源对外部是不能访问的,因此我们可以利用映射将该Servlet类到某个请求路径中,才能进行访问,需要在web.xml中配置
基于xml方式
<!-- 配置servlet请求路径-->
<servlet>
<!-- 给Servlet起一个名字-->
<servlet-name>hello</servlet-name>
<!-- 映射到某一个Servlet类-->
<servlet-class>servlet.HelloWorldServlet</servlet-class>
</servlet>
<!-- 配置mapping映射-->
<servlet-mapping>
<!-- 对应的Servlet名字-->
<servlet-name>hello</servlet-name>
<!-- 映射到指定的url请求路径-->
<url-pattern>/hello</url-pattern>
</servlet-mapping>
当然也支持注解方式
- 当浏览器请求该路径时http://localhost/hello,服务器接受到浏览器请求,响应给浏览器内容
Servlet生命周期
- init()方法
//在servlet创建时执行,且只执行一次
- service(ServletRequest servletRequest, ServletResponse servletResponse)方法
//提供服务的方法,每一次servlet被访问时执行,可多次执行
- destroy()方法
//销毁方法,在服务器正常关闭servlet被销毁时执行,只执行一次。
当启动Tomcat的时,未访问Servlet类,即对象未被创建,控制台未执行init()方法
当访问Servlet类时,对象被创建,先执行init()方法初始化,再执行service业务方法
当访问多次请求时,而init()方法只被执行一次,Servlet中service()的业务方法则被执行多次
当关闭tomcat服务器时,释放Servelt对象,调用destroy()方法
总结
- Servlet对象相当于单例模式,创建一个对象,可反复使用,可以节省内存空间,防止创建过多的对象影响性能
- 该对象的创建是由tomcat来创建,当浏览器访问Servlet时,Tomcat会查询Servlet实例对象是否存在,不存在则通过反射机制创建,原理就是我们配置web.xml中的映射中class全类名或者是注解中对应的类拿到该类的默认无参数构造函数创建对象;存在则直接执行Servlet中service()业务方法
public class HelloWorldServlet implements Servlet {
//无参数构造方法,无参构造函数只调用一次,目的是创建对象
public HelloWorldServlet() {
System.out.println("Servlet对象被创建啦.....");
}
@Override
public void init(ServletConfig servletConfig) throws ServletException {
//在servlet创建时执行,且只执行一次
System.out.println("对Servlet完成初始化操作");
}
@Override
public ServletConfig getServletConfig() {
//获取Servlet配置
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
//提供服务的方法
//每一次servlet被访问时执行,可多次执行
System.out.println("执行了Servlet中Service业务方法");
}
@Override
public String getServletInfo() {
//获取Servlet信息,版本,作者等等
return null;
}
@Override
public void destroy() {
//销毁方法,在服务器正常关闭servlet被销毁时执行,只执行一次。
System.out.println("释放了Servlet对象");
}
}
当浏览器请求访问该Servlet对象时,Servlet对象先创建,再进行初始化,再执行service()方法
已经创建有对象,当访问多次请求路径时,不会再进行创建对象
ServletConfig类
- 它是一个接口,用来描述Servlet基本信息
public interface ServletConfig {
String getServletName();
ServletContext getServletContext();
String getInitParameter(String var1);
Enumeration<String> getInitParameterNames();
}
它有四个方法
1.getServletName()用来返回Servlet名称,(如果使用注解则为全类名/如果使用web.xml则为servlet-name中的值)
- 基于注解配置Servlet
- 基于web.xml配置
代码演示
public void init(ServletConfig servletConfig) throws ServletException {
//在servlet创建时执行,且只执行一次
System.out.println(servletConfig.getServletName());
System.out.println("对Servlet完成初始化操作");
}
2.getInitParameter(String var1)获取Servlet中初始化参数,它在web.xml中可以自行配置
结果:
3.getInitParameterNames()获取Servlet中所有初始化参数,它在web.xml中可以自行配置,返回的是一个集合类型Enumeration,迭代取出
4.getServletContext()方法获取当前Servlet上下文对象,也是接口类型,作用是可以获取整个Servlet服务中所有的信息
这里讲解一个比较重要的方法getContextPath(),获取当前上下文路径
ServletConfig和ServletContext区别
- ServletConfig作用于某一个实现了Servlet的接口的实例,每一个Servlet实例都有对应的ServletConfig
- ServletContext作用于整个web应用,一个web应用对应一个ServletContext
- 多个Servlet实例对象对应一个ServletContext
测试示例:
通过流程图来看整个过程