Servlet、Servlet的5个接口方法、生命周期、以及模拟实现 HttpServlet 来写接口的基本原理

Servlet、Servlet的5个接口方法、生命周期、以及模拟实现 HttpServlet 来写接口的基本原理

DAY15.1 Java核心基础

Servlet

Servlet是一个接口,是java的基础,java之所以编写web的程序,接收请求并响应,就是因为Sevlet接口

Java 类实现了Servlet接口的时候就可以接收并响应请求,成为web服务器

Web服务器就是接收请求,然后处理并响应结果

代码示例:

创建一个HelloServlet,实现Servlet接口,实现它的方法

yes,需要先导入相关的包

xml

复制代码

javax.servlet

javax.servlet-api

4.0.1

provided

java

复制代码

@WebServlet("/hello")

public class HelloServlet implements Servlet {

/**

* 初始化方法

* @param servletConfig

* @throws ServletException

*/

@Override

public void init(ServletConfig servletConfig) throws ServletException {

System.out.println("执行了初始化方法");

}

/**

* 配置方法 ,一般不用

* @return

*/

@Override

public ServletConfig getServletConfig() {

return null;

}

/**

* 业务方法

* @param servletRequest

* @param servletResponse

* @throws ServletException

* @throws IOException

*/

@Override

public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {

System.out.println("执行了业务方法");

}

/**

* 获取Servlet的名称 ,一般不用

* @return

*/

@Override

public String getServletInfo() {

return "";

}

/**

* 销毁方法

*/

@Override

public void destroy() {

}

}

重要的实现方法:

public void init(ServletConfig servletConfig):第一次调用Servlet的时候执行,只执行一次

public void service(ServletRequest servletRequest, ServletResponse servletResponse):调用一次执行一次

public void destroy():关闭Tomcat 的时候执行一次

但是这些都是非静态方法,非静态方法调用的时候必须创建对象,才能使用这些方法

那么什么时候创建这个对象?如何创建这个对象呢?

是Tomcat通过反射的机制调用实现类的无参构造 动态创建的对象

要注意实现类的WebUrl映射不能设置为同样的url,不然Tomcat会报错,比如:

java

复制代码

@WebServlet("/hello")

public class HelloServlet1 implements Servlet

java

复制代码

@WebServlet("/hello")

public class HelloServlet2 implements Servlet

报错提示不能映射为同一个url模式

首先创建了 HelloServlet 对象,调用了对象的 init 方法,调用了对象的 service 方法

Servlet 的生命周期:先有对象,初始化对象,调用对象的方法

当第一次访问 Servlet 的时候创建 Servlet 的实例化对象

Tomcat根据请求找到相应的Servlet实现类,是通过注解进行匹配的

Servlet是一个单例模式,一次创建多次调用

Servlet 的生命周期

当请求某个Servlet的时候,首先会创建Servlet这个对象的实例化对象(Tomcat通过反射机制创建),然后调用init方法进行初始化操作,然后调用service方法进行完成业务处理,当重复请求同一个Servlet的时候不会再次创建这个实例化对象,而是直接使用service方法完成业务操作,因为这个对象被Tomcat保存到了一个容器之中,然后在关闭Tomcat的时候会调用destory方法进行销毁

构造函数:只调用一次,在创建的时候

init方法:只调用一次,第一次创建的时候

service方法:多次重复调用,每次请求调用一次

destory犯法:只调用一次,在Tomcat关闭的时候调用

Servlet 接口中只有service方法经常使用,其它4个方法基本没用

如果每次实现的时候都需要实现5个方法,太麻烦了,代码太多了,如何解决呢?

可以用继承一个BaseServlet,然后后面直接继承这个基础类,只需要重写service方法即可

java

复制代码

@WebServlet("/base")

public class BaseServlet implements Servlet {

/**

* 初始化方法

* @param servletConfig

* @throws ServletException

*/

@Override

public void init(ServletConfig servletConfig) throws ServletException {

System.out.println("执行了初始化方法");

}

/**

* 配置方法 ,一般不用

* @return

*/

@Override

public ServletConfig getServletConfig() {

return null;

}

/**

* 业务方法

* @param servletRequest

* @param servletResponse

* @throws ServletException

* @throws IOException

*/

@Override

public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {

System.out.println("Base执行了业务方法");

}

/**

* 获取Servlet的名称 ,一般不用

* @return

*/

@Override

public String getServletInfo() {

return "";

}

/**

* 销毁方法

*/

@Override

public void destroy() {

}

}

通过继承可以实现只实现service方法,不需要全部重写

java

复制代码

@WebServlet("/test2")

public class TestServlet extends BaseServlet{

@Override

public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {

System.out.println("test2");

}

}

启动Tomcat访问http://localhost:3030/test2,可以看见他调用了TestServlet的service方法

站在父亲的肩膀上省事

但是在我们的日常使用中我们是不是只需要重写一个doGet方法和一个doPost方法就可以实现业务板块了呢,这个时候就需要将service的业务分类了,这边不细分,先写get和post方法的处理,那我们是写在实现类还是写在父类呢,当然是写在父类基础类呀,这样我们就不用管父类的分发工作了,我们只需要写一个get和post方法即可实现接收get和post请求,这样说着太空洞了,我们来代码展示:

基本类:BaseServlet(我们自己创建的父类)

小知识:

HttpServletRequest:ServletRequest的子类,内置多个可以获取到请求信息的函数

HttpServletResponse:ServletResponse的子类,可以封装信息通过HttpServletResponse的函数返回到浏览器

java

复制代码

@WebServlet("/base")

public class BaseServlet implements Servlet {

/**

* 初始化方法

* @param servletConfig

* @throws ServletException

*/

@Override

public void init(ServletConfig servletConfig) throws ServletException {

System.out.println("执行了初始化方法");

}

/**

* 配置方法 ,一般不用

* @return

*/

@Override

public ServletConfig getServletConfig() {

return null;

}

/**

* 业务方法

* @param servletRequest

* @param servletResponse

* @throws ServletException

* @throws IOException

*/

@Override

public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {

System.out.println("Base执行了业务方法");

HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;

HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;

String method = httpServletRequest.getMethod();

System.out.println("当前请求的方法:"+method);

System.out.println("User-agent:"+httpServletRequest.getHeader("User-agent"));

switch (method){

case "GET":

doGet(httpServletRequest,httpServletResponse);

break;

case "POST":

doPost(httpServletRequest,httpServletResponse);

break;

default:

System.out.println("不支持的请求方法");

break;

}

}

/**

* 获取Servlet的名称 ,一般不用

* @return

*/

@Override

public String getServletInfo() {

return "";

}

/**

* 销毁方法

*/

@Override

public void destroy() {

}

// 处理Get请求

public void doGet(HttpServletRequest request, HttpServletResponse response) {

System.out.println("调用了doGet方法");

}

// 处理Post请求

public void doPost(HttpServletRequest request, HttpServletResponse response) {

System.out.println("调用了doPost方法");

}

}

可以看见这个类实现了Servlet接口必须实现的5个接口

然后这个类的service业务接口做了一个分类实现

测试类TestServlet:继承了基本类 BaseServlet,简化了代码

java

复制代码

@WebServlet("/test2")

public class TestServlet extends BaseServlet{

@Override

public void doPost(HttpServletRequest request, HttpServletResponse response) {

System.out.println("重写的doPost方法");

}

@Override

public void doGet(HttpServletRequest request, HttpServletResponse response) {

System.out.println("重写的doGet方法");

}

}

只需要重写一个doGet或者一个doPost方法就可以实现对应类型接口的业务实现了,这样开发者就可以着重到业务代码里面了

来看看Serlet方法常见的写网络接口的方式:

java

复制代码

@WebServlet("/test")

public class Test extends HttpServlet {

@Override

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

resp.setCharacterEncoding("GBK");

resp.getWriter().write("Hello World,这是Tomcat!");

}

}

可以看见他也是继承了一个HttpServlet类,然后实现了一个doGet方法就完成了,是不是感觉好像和上面有几分相似,哈哈哈,你自己体会体会

总结:

第一代 BaseServlet 实现 Servlet 接口,实现全部 5 个方法

第二代 TestServlet继承 BaseServlet,重写 service 方法

第三代开发者自定义的类继承 BaseServlet,重写 doGet 和 doPost 方法即可

区分不同的请求类型,进行分发

将 ServletRequest 和 ServletResponse 全部强转为子类类型 HttpServletRequest 和 HttpServletResponse

Servlet 的调用体系,通过继承的方式将原本的工作分层三层去完成,每一次都承担一些任务,最终来到开发者自定义这层之后,工作量会减少很多,因为其父类已经完成了其他的工作,只保留最核心的方法交由开发者自定义的类来实现,提高了开发效率,减少了代码量。

继承是 Java 中代码复用的重要应用之一,父类所做的工作,子类可以直接继承,就不需要额外再次去完成重复的工作了,提高代码的效率,开发效率。

相关文章

手机虚拟空间哪个好用?
365bet育在线网址

手机虚拟空间哪个好用?

⌚ 08-27 👁️‍🗨️ 8552
手机特殊符号输入指南:轻松掌握多种输入方法
beat365手机版官方网站

手机特殊符号输入指南:轻松掌握多种输入方法

⌚ 10-09 👁️‍🗨️ 9050
2010年世界杯足彩竞猜方案 三种新附加玩法出台
365结束投注什么意思

2010年世界杯足彩竞猜方案 三种新附加玩法出台

⌚ 08-28 👁️‍🗨️ 9096