适配器(GenericServlet)改造Servlet
JavaWeb系列教程
JavaWeb—Servlet
模擬Servlet本質(zhì)
使用IDEA開發(fā)Servlet程序
Servlet對象的生命周期
適配器(GenericServlet)改造Servlet
ServletConfig
Servlet–ServletContext
HttpServlet源碼分析
web站點(diǎn)歡迎頁
一篇學(xué)會HttpServletRequest
如果大家覺得有幫助的話,不妨動動小手,點(diǎn)贊收藏一波,也方便后面的復(fù)習(xí)哈
我們發(fā)現(xiàn)在編寫一個Servlet類的時候,要實(shí)現(xiàn)它的所有方法,但是事實(shí)上,我們一般只是使用service方法,這樣就會讓代碼看著很丑陋,那么我們要怎么解決呢?
我們在說解決問題之前,先來看看這樣的一個例子
適配器設(shè)計(jì)模式Adapter
- 手機(jī)直接插到220V的電壓上,手機(jī)直接就報(bào)廢了。怎么辦?可以找一個充電器。這個充電器就是一個適配器。手機(jī)連接適配器。適配器連接220V的電壓。這樣問題就解決了。
同樣的道理,我們也可以使用這樣的思想,來解決這個問題
-
編寫一個GenericServlet類,這個類是一個抽象類,其中有一個抽象方法service。
GenericServlet實(shí)現(xiàn)Servlet接口。
GenericServlet是一個適配器。
以后編寫的所有Servlet類繼承GenericServlet,重寫service方法即可。
package com.bjpowernode.servlet;import jakarta.servlet.*;import java.io.IOException;
import java.io.PrintWriter;/*** @author zengyihong* @create 2022--03--06 20:08*/
public class AServlet extends GenericServlet {@Overridepublic void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {response.setContentType("text/html");PrintWriter out = response.getWriter();//獲取ServletContext對象ServletConfig config = this.getServletConfig();ServletContext context = config.getServletContext();out.print(context);}
}
思考:GenericServlet類是否需要改造一下?怎么改造?更利于子類程序的編寫?
-
思考第一個問題:我們提供了一個GenericServlet之后,init方法還會執(zhí)行嗎?
- 還會執(zhí)行。會執(zhí)行GenericServlet類中的init方法。
- 很明顯,子類中如果這個方法,它就會去父類找相應(yīng)的方法
-
思考第二個問題:init方法是誰調(diào)用的?
- Tomcat服務(wù)器調(diào)用的。
-
思考第三個問題:init方法中的ServletConfig對象是誰創(chuàng)建的?是誰傳過來的?
- 都是Tomcat干的。
- Tomcat服務(wù)器先創(chuàng)建了ServletConfig對象,然后調(diào)用init方法,將ServletConfig對象傳給了init方法。
- 如果對上面幾個問題不大理解的話,大家可以先去看看servlet的生命周期
-
思考一下Tomcat服務(wù)器偽代碼:
public class Tomcat {public static void main(String[] args){// .....// Tomcat服務(wù)器偽代碼// 創(chuàng)建LoginServlet對象(通過反射機(jī)制,調(diào)用無參數(shù)構(gòu)造方法來實(shí)例化LoginServlet對象)Class clazz = Class.forName("com.bjpowernode.javaweb.servlet.LoginServlet");Object obj = clazz.newInstance();// 向下轉(zhuǎn)型Servlet servlet = (Servlet)obj;// 創(chuàng)建ServletConfig對象// Tomcat服務(wù)器負(fù)責(zé)將ServletConfig對象實(shí)例化出來。// 多態(tài)(Tomcat服務(wù)器完全實(shí)現(xiàn)了Servlet規(guī)范)ServletConfig servletConfig = new org.apache.catalina.core.StandardWrapperFacade();// 調(diào)用Servlet的init方法servlet.init(servletConfig);// 調(diào)用Servlet的service方法// ....}
}
但是ServletConfig對象以后肯定是要在service方法中使用的,那么怎么才可以保證ServletConfig對象在service方法中能夠使用呢? 我們很容易就想到了成員變量
init方法中的ServletConfig對是Tomcat服務(wù)器創(chuàng)建好的
- 這個ServletConfig對象目前在init方法的參數(shù)上,屬于局部變量
- 那么怎么才能使用呢?------成員變量
- ServletConfig對象將來肯定是要用在service方法的,怎么保證ServletConfig對象在service方法中調(diào)用呢-----調(diào)用getServletConfig()方法
思考一下,還有一種可能,需要子類重寫父類的init方法,但是這樣就會導(dǎo)致父類的init方法不執(zhí)行,那么ServletConfig對象就是null了,那么將來就會有很大的麻煩,我們就不要讓這個方法被子類重寫,可以在方法加上final修飾,但是如果子類就是想要重寫呢? 但是這個時候子類沒有辦法重寫,那到底要怎么辦呢
解決辦法:再GenericServlet類中添加一個無參的init方法,供子類進(jìn)行重寫。
上面那個過程都是我們自己一步一步根據(jù)需求推出來的,是不是感覺好麻煩,一會這樣,一會那樣的,不過好消息是,GenericServlet這個類不需要我們寫,官方已經(jīng)提供好了,而且官方寫的代碼考慮的肯定比我們周全
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//package jakarta.servlet;import java.io.IOException;
import java.io.Serializable;
import java.util.Enumeration;public abstract class GenericServlet implements Servlet, ServletConfig, Serializable {private static final long serialVersionUID = 1L;private transient ServletConfig config;public GenericServlet() {}public void destroy() {}public String getInitParameter(String name) {return this.getServletConfig().getInitParameter(name);}public Enumeration<String> getInitParameterNames() {return this.getServletConfig().getInitParameterNames();}public ServletConfig getServletConfig() {return this.config;}public ServletContext getServletContext() {return this.getServletConfig().getServletContext();}public String getServletInfo() {return "";}public void init(ServletConfig config) throws ServletException {this.config = config;this.init();}public void init() throws ServletException {}public void log(String message) {this.getServletContext().log(this.getServletName() + ": " + message);}public void log(String message, Throwable t) {this.getServletContext().log(this.getServletName() + ": " + message, t);}public abstract void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;public String getServletName() {return this.config.getServletName();}
}
大家看到我們所寫和官網(wǎng)提供的思路其實(shí)是大同小異的。
希望得到大家的支持
總結(jié)
以上是生活随笔為你收集整理的适配器(GenericServlet)改造Servlet的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用IDEA开发Servlet程序
- 下一篇: Servlet----ServletCo