- 自己写的GenericServlet
- 让实现Servlet的GenericServlet 类变成适配器
- 改造GenericServlet
- GenericServlet源码
- ServletConfig
- ServletContext
- 注意
类上加上abstract关键字
GenericServlet.java
public abstract class GenericServlet implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public abstract void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException;
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
子类LoginServlet .java
public class LoginServlet extends GenericServlet {
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("正在处理用户请求,请稍后。。。");
ServletConfig servletConfig = this.getServletConfig();
System.out.println("service方法中获取到ServletConfig对象:" + servletConfig);
}
}
改造GenericServlet
GenericServlet.java
public abstract class GenericServlet implements Servlet {
// 成员变量
private ServletConfig servletConfig;
@Override
public final void init(ServletConfig servletConfig) throws ServletException { // 加final关键字防止init方法被子类重写
System.out.println("Tomcat创建好的servletConfig对象:" + servletConfig);
this.servletConfig = servletConfig;
//调用init()方法
this.init();
}
public void init(){
}
@Override
public ServletConfig getServletConfig() {
return servletConfig;
}
@Override
public abstract void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException;
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
子类LoginServlet .java
public class LoginServlet extends GenericServlet {
// 重写init方法
@Override
public void init() {
System.out.println("重写的init方法执行");
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("正在处理用户请求,请稍后。。。");
ServletConfig servletConfig = this.getServletConfig();
System.out.println("service方法中获取到ServletConfig对象:" + servletConfig);
}
}
GenericServlet源码
public abstract class GenericServlet implements Servlet, ServletConfig, Serializable {
private static final long serialVersionUID = 1L; // 固定序列化版本号,代码后续修改不会被认为是一个新类,便于维护
private transient ServletConfig config; // 添加transient关键字,表示不参与序列化
// 无参构造
public GenericServlet() {
}
public void destroy() {
}
public String getInitParameter(String name) {
return this.getServletConfig().getInitParameter(name);
}
public Enumeration 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();
}
// 这个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();
}
}
ServletConfig
ServletConfig被称为Servlet的配置信息对象。
public class ConfigTestServlet extends GenericServlet {
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
servletResponse.setContentType("text/html");
PrintWriter out = servletResponse.getWriter();
// 获取ServletConfig对象
ServletConfig servletConfig = this.getServletConfig();
// 输出
// org.apache.catalina.core.StandardWrapperFacade@c091ed2
out.print("ServletConfig对象:" + servletConfig.toString());
out.print("
");
// 获取
String servletName = servletConfig.getServletName();
out.print(""+servletName+" "); // ConfigTestServlet
out.print("
");
// 通过ServletConfig对象的两个方法,获取web.xml文件中的初始化参数配置信息
// java.util.Enumeration getInitParameterNames() 获取所有初始化参数的name
Enumeration initParameterNames = servletConfig.getInitParameterNames();
// 遍历集合
while (initParameterNames.hasMoreElements()) {
String parameterName = initParameterNames.nextElement();//取元素
String initParameter = servletConfig.getInitParameter(parameterName);
out.print(parameterName + "=" + initParameter);
out.print("
");
}
// java.lang.String getInitParameter(java.lang.String name) 通过初始化参数的name获取value
// 实际上获取一个Servlet对象的初始化参数,可以不用获取ServletConfig对象,可以直接通过this,因为当前类继承了GenericServlet
Enumeration initParameterNames1 = this.getInitParameterNames();
// 遍历集合
while (initParameterNames1.hasMoreElements()) {
String parameterName1 = initParameterNames1.nextElement();//取元素
String initParameter1 = this.getInitParameter(parameterName1);
out.print(parameterName1 + "=" + initParameter1);
out.print("
");
}
}
}
ServletContext
ServletContext被称为Servlet上下文对象,也叫应用域。如果所有的用户共享一份数据,这个数据很少被修改,数据量很小,可以将这些数据放到ServletContext这个应用域中,并且放在ServletContext对象中的数据一般都是只读的。
public class ContextTestServlet extends GenericServlet {
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
servletResponse.setContentType("text/html");
PrintWriter out = servletResponse.getWriter();
// 获取ServletContext()对象
ServletContext application = this.getServletContext();
// org.apache.catalina.core.ApplicationContextFacade@c091ed2
out.print("ServletContext对象是:" + application + "
");
// 获取上下文的初始化参数
Enumeration initParameterNames = application.getInitParameterNames();
while (initParameterNames.hasMoreElements()) {
String name = initParameterNames.nextElement();
String value = application.getInitParameter(name);
out.print(name + "=" + value + "
");
}
// getContextPath()这个方法可以动态获取应用的根路径(非常重要)
String contextPath = application.getContextPath();
out.print(contextPath + "
");
// 获取文件的绝对路径
String realPath = application.getRealPath("/index.jsp"); // "/" 代表的是web的根
out.print(realPath + "
");
// 记录日志
// 在控制台的"CATALINA_BASE"后的文件目录能找到日志文件
application.log("Hello JavaWeb"); // 在 localhost.2022-05-12.log 里打印
// "CATALINA_BASE"后的文件目录中的日志文件
//catalina.2022-05-12.log 服务器端的java程序运行的控制台信息
//localhost.2022-05-12.log ServletContext对象的log方法记录的日志信息存储到这个文件中
//localhost_access_log.2022-05-12.txt 访问日志
}
}
注意
以后我们编写Servlet类的时候,实际上是不会去直接继承GenericServlet类的,因为我们是B/S结构的系统,这种系统是基于HTTP超文本传输协议的,在Servlet规范当中,提供了一个类叫做HttpServlet,它是专门为HTTP协议准备的一个Servlet类,我们编写的Servlet类要继承HttpServlet。
它们之间的继承结构:
- javax/jakarta.servlet.Servlet(接口)
- javax/jakarta.servlet.GenericServlet implements Servlet(抽象类)
- javax/jakarta.servlet.http.HttpServlet extends GenericServlet(抽象类)



