创建javaee的web项目
在使用servlet之前我们需要先创建一个javaee的web项目,一个web项目通常包含下面一些文件:
src
web
WEB-INF
lib
classes
index.jsp
- src:存放java源代码
- web:存放静态资源和动态资源
- WEB-INF:该目录下的所有文件无法从浏览器中直接访问
- lib:存放相关的jar包
- classes:存放编译后的class文件
- index.jsp:web项目中默认访问的首页
application context(项目上下文),通过配置项目上下文可以在tomcat部署多个项目。
什么是servlet
servlet是一门用于开发动态web资源的技术,可以运行在Web服务器中的小型Java程序,有时也叫做服务器端的小应用程序,servlet是server applet两个单词的组合而成。servlet 可以通过 HTTP协议接收和响应来自 Web 客户端的请求。
创建servlet步骤:
- 创建一个javaee的web项目
- 编写一个Java类,实现javax.servlet.Servlet接口,并重写该接口中的抽象方法
- 在web.xml文件中配置该servlet(如果使用注解方式的话,无需配置web.xml)
- 将该web项目部署到tomcat中并启动
web访问流程图:
服务器端程序是实现了servlet接口的程序,servlet的主要作用其实就是处理和响应客户端的请求。
创建一个Servlet 类
public class FirstServlet implements Servlet {
@Override
public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException {
System.out.println("Hello Servlet");
}
@Override
public void destroy() {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void init(ServletConfig arg0) throws ServletException {
}
}
servlet创建好之后,需要在web.xml文件中进行配置,给servlet一个可以访问的URI地址:
<!-- 创建一个servlet实例 -->
<servlet>
<!-- 给servlet取一个名字,该名字需与servlet-mapping中的servlet-name一致 -->
<servlet-name>firstServlet</servlet-name>
<!-- servlet的包名+类名 -->
<servlet-class>com.xuejun.servlet.FirstServlet</servlet-class>
</servlet>
<!-- 给servlet一个可以访问的URI地址 -->
<servlet-mapping>
<!-- servlet的名字,与 servlet中的servlet-name一致-->
<servlet-name>firstServlet</servlet-name>
<!-- URI地址:http://locahost:8080/Servlet/nihao-->
<url-pattern>/nihao</url-pattern>
</servlet-mapping>
tomcat也被称为是servlet的容器
servlet执行流程
- 客户端向tomcat发送请求,http://localhost:8080/Servlet/nihao
- tomcat根据请求的URL找到名称为Servlet的应用
- tomcat根据请求的URI"/nihao"找到web.xml文件中url-pattern与之对应的标签
- tomcat根据url-pattern标签中的servlet-name定位com.xuejun.servlet.FirstServlet类。
- tomcat实例化FirstServlet类
- 调用FirstServlet类中的init方法
- 调用FirstServlet类中的service方法
- FirstServlet将数据响应给客户端
- 调用distroy方法销毁FirstServlet
servlet的生命周期
Servlet 生命周期指的是,Servlet 对象的创建、Servlet 对象的初始化、Servlet 对象服
务的执行,及最终 Servlet 对象被销毁的整个过程。
servlet生命周期图:
Servlet 的整个生命周期过程的执行,均由 Web 服务器负责管理,程序员无法控制其执行流程。但程序员可以获取到 Servlet 的生命周期时间点,并可以指定让 Servlet 做一些业务相关的事情。
servlet的特征
- Servlet是单例多线程的,只创建一个servlet对象,但是每次请求都会起一个线程并在自己线程栈内存中执行service方法。
- 一个 Servlet 实例只会执行一次无参构造器与 init()方法,并且是在第一次访问时执行。
- 用户每提交一次对当前 Servlet 的请求,就会执行一次 service()方法。
- 一个 Servlet 实例只会执行一次 destroy()方法,在应用停止时执行。
- 由于 Servlet 是单例多线程的,所以为了保证其线程安全性,一般情况下是不建议在 Servlet类中定义可修改的成员变量,因为每个线程均可修改这个成员变量,会出现线程安全问题。
- 默认情况下,Servlet 在 Web 容器启动时是不会被实例化的。
tomcat启动时创建servlet实例
在tomcat启动时,默认不会创建servlet实例,如果想要让tomcat在启动时创建servlet实例的话,只需要在web.xml中添加load-on-startup标签即可
<servlet>
<servlet-name>lifeServlet</servlet-name>
<servlet-class>com.xuejun.servlet.LifeServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>lifeServlet</servlet-name>
<url-pattern>/life</url-pattern>
</servlet-mapping>
添加load-on-startup的作用是,标记是否在 Tomcat启动时创建并初始化这个 Servlet实例。它的值必须是一个整数。
- 当值大于等于 0 时,表示容器在启动时就加载并初始化这个 Servlet,数值越小,该 Servlet的优先级就越高,其被创建的也就越早;
- 当值相同时,容器会自己选择创建顺序。
GenericServlet类
继承GenericServlet类
/**
* 继承GenericServlet
*/
public class SimpleServlet extends GenericServlet {
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
System.out.println("SimpleServlet继承自GenericServlet");
}
}
GenericServlet类
GenericServlet类是一个抽象类,实现了servlet接口
和ServletConfig接口
并重写了除了service方法以外的全部方法,这样子类在继承GenericServlet类时,只需重写service方法。如果想要使用destroy方法时,直接重写GenericServlet类中的destroy方法就行,而在GenericServlet类中的destroy方法本身就是一个空实现,里面没有代码。
HttpServlet类
继承HttpServlet类
常用的http提交方式有get和post
(除此之外还有put、delete),在之前所编写的servlet中是无法直接处理这两种提交方式的,为了方便开发,JavaEE规范的API提供了javax.servlet.http.HttpServlet类,在实际开发中也经常使用继承HttpServlet类的方式创建一个servlet。
//继承HttpServlet处理get和post请求
public class HttpTest01 extends HttpServlet {
@Override
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("执行doGet方法");
}
@Override
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("执行doPost方法");
}
}
创建servlet的三种方式
- 定一个类实现javax.servlet.Servlet接口
- 定义一个类继承javax.servet.GenericServlet类
- 定义一个类继承javax.servlet.http.HttpServlet类
Servlet(爷爷) –> GenericServlet(爸爸) –> HttpServlet(儿子)
- tomcat通过Servlet接口中的init方法将ServletConfig对象传递过去,所以Servlet接口依赖ServletConfig接口。
- Servlet接口中通过调用getServletConfig方法可以获取ServletConfig对象,所以Servlet接口也关联ServletConfig接口。
- 在ServletConfig接口中通过getServletContext方法获取ServletContext对象,所以ServletConfig接口关联ServletContext接口。
- GenericServlet类分别实现了Servlet接口和ServletConfig接口
- HttpServlet类继承了GenericServlet类
- HttpServletRequest接口继承ServletRequest接口
- HttpServletResponse接口继承ServletResponse接口