GenericServlet
1,GenericServlet是什么?
它也是一个Servlet类,是一个抽象类。
下面是它的源代码。
public abstract class GenericServlet implements Servlet, ServletConfig, Serializable {}
2,GenericServlet有什么作用?已经有了Servlet为什么还需要提供GenericServlet?
2.1,直接实现Servlet接口有什么缺点?
从上一章得Servlet基础中得例子可以看出:
要想完成一个webapp的创建,必须的满足Servlet规范。也就是说一定得实现Servlet接口,
我们知道一个类要实现一个接口必须要实现接口的所有方法。问题就来了,我们程序员在编写servlet类的时候,其实最主要是要用service方法,其它方法很少用到。这样代码是很不理想的。
2.2,使用模板方法设计模式解决Servlet的缺点
创建一个类(这个类就是GenericServlet)实现Servlet接口,把经常使用的方法改成抽象方法(所以这个类也得变成抽象类),其它的方法可以默认实现 。当然 还可以补充方法。
当你想创建一个Servlet类的时候就可以直接继承该类,serviece方法是一定要重写的。其它方法可以选择重不重写。
ServletConfig
从上面我们可以看到GenericServlet不仅实现了Servlet接口,还实现类ServletConfig接口。
而且Servlet类中还有一个getServletConfig的方法。那么ServletConfig究竟是什么呢?
1,ServletConfig是什么?
ServletConfig接口在:javax.servlet.ServletConfig
显然ServletConfig是Servlet规范中的一员
2,ServletConfig是干嘛的?
Config是哪个单词的缩写:configuration(配置)
ServletConfig对象被翻译为:Servlet对象的配置信息对象。
一个Servlet对象就有一个配置信息对象。
3,ServletConfig对象当中包装类什么信息呢?
<servlet>
<servlet-name>configTest</servlet-name>
<servlet-class>com.javaweb.servlet.ConfigTestServlet</servlet-class>
</servlet>
ServletConfig对象中包装的信息是:
web.xml文件中<select></select>标签的配置信息
Tomcat解析web.xml文件,将web.xml文件中的<select></select>标签的配置信息自动包装到ServletConfig对象中。
4,ServletConfig对象是谁创建的?在什么时候创建的?
Tomcat服务器(WEB服务器)创建了ServletConfig对象。
在创建Servlet对象的时候,同时创建了ServletConfig对象
注意:一个Servlet对象对应一个ServletConfig对象
5,ServletConfig接口有哪些常用方法
注意:以下方法在代码中体现作用
Enumeration<String> getInitParameterNames();
String getInitParameter(String name);
ServletContext getServletContext();
String getServletName();
以上的四个方法,在自己编写的Servlet类中可以使用this调用,(这个Servlet继承了GenericServlet)
6,ServletConfig接口方法代码示例:
6.1,web.xml的配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>configTest</servlet-name>
<servlet-class>com.javaweb.servlet.ConfigTestServlet</servlet-class>
<!-- 这里是可以配置一个Servlet对象的初始化信息的 -->
<init-param>
<param-name>driver</param-name>
<param-value>com.mysql.cj.jdbc.Driver</param-value>
</init-param>
<init-param>
<param-name>url</param-name>
<!-- 将&符号重写成:&如下:-->
<param-value>jdbc:mysql://localhost:3306/db2?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC</param-value>
</init-param>
<init-param>
<param-name>user</param-name>
<param-value>root</param-value>
</init-param>
<init-param>
<param-name>password</param-name>
<param-value>123456</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>configTest</servlet-name>
<url-pattern>/test</url-pattern>
</servlet-mapping>
</web-app>
package com.javaweb.servlet;
import javax.servlet.*;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
public class ConfigTestServlet extends GenericServlet {
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
servletResponse.setContentType("Text/html;charset=UTF-8");
PrintWriter out = servletResponse.getWriter();
//获取ServletConfig
ServletConfig servletConfig = this.getServletConfig();
//输出该对象
System.out.println(servletConfig);//org.apache.catalina.core.StandardWrapperFacade@5321de25
out.print("ServletConfig对象是:"+servletConfig);
out.print("<br/>");
//获取<servlet-name></servlet-name>
String name = servletConfig.getServletName();
out.print("<servlet-name>"+name+"</servlet-name>");//configTest
out.print("<br/>");
//通过ServletConfig的两个方法,可以获取到web.xml文件中的初始化参数配置信息
//Enumeration<String> getInitParameterNames()
//String getInitParameter(String name)
Enumeration<String> initParameterNames = servletConfig.getInitParameterNames();
//遍历集合
while (initParameterNames.hasMoreElements()){
String parameterName = initParameterNames.nextElement();
out.print(parameterName+"<br/>");
//password driver user url
}
//通过初始化参数的name获取value
String driver = servletConfig.getInitParameter("driver");
out.print(driver);//com.mysql.cj.jdbc.Driver
//怎么获取ServletContext对象?
//第一种通过ServletConfig对象获取ServletContext对象
ServletContext application = servletConfig.getServletContext();
//输出
out.print("<br/>"+application);//org.apache.catalina.core.ApplicationContextFacade@5dae17d8
//第二种方式:通过this(继承了GenericServlet)获取,
ServletContext application2 = this.getServletContext();
out.print("<br/>"+application2);//org.apache.catalina.core.ApplicationContextFacade@5dae17d8
}
}
ServletText
从上面我们可以看到,ServletConfig和GenericServlet都有getServletContext()的方法。
那么ServletContext是什么呢?
1,ServletContext是什么?
ServletConfig是接口,也是Servlet规范中的一员。
全路径名称:javax.servlet.ServletContext
2,ServletContext有什么用呢?
ServletContext怎么理解:
context是什么意思:context:上下文/环境
ServletContext:Servlet对象的环境对象/Servlet对象的上下文对象
ServletContext对象其实对应的是整个web.xml文件。
50个学生,每个学生都是一个Servlet,这50个对象都在一个教室中,那么这个教室就相当于ServletContext对象
放在ServletContext对象中的数据,说有Servlet一定是共享的
比如:一个教室中的空调是说有学生共享的,一个教室的语文老师是说有学生共享的。
ServletContext是应用级对象
Tomcat是一个容器,一个容器当中可以放多个webapp,一个webapp(应用)对应一个ServletContext对象
3,ServletContext由谁创建?什么时候创建?
1,ServletContext是谁实现的:
Tomcat服务器(WEB服务器),实现了ServletContext接口。 public class org.apache.catalina.core.ApplicationContextFacade implements ServletContext{}
2,ServletContext对象是什么时候创建的,在什么时候销毁的的:
ServletContext对象在WEB服务器启动的时候创建的。
ServletContext对象是WEB服务器创建的。
对应一个webapp来说,ServletContext对象只有一个。
ServletContext对象在服务器关闭的时候销毁
4,ServletContext接口中有哪些常用的方法?
注意:虽然都是初始化参数,但是这里是上下文的初始化参数,在所有<servlet></servlet>标签外面 *
public String getInitParameter(String name);//通过初始化参数的name获取value
public Enumeration<String> getInitParameterNames();//获取所有的初始化参数name
* 以上两个方法获取的是以下信息 *
<!--上下文的初始化参数,以下的这些配置信息,可以通过ServletConfig对象来获取 --> * <context-param>
<param-name>pageSize</param-name>
<!-- 每页显示的数据条数 -->
<param-value>10</param-value>
</context-param>
<context-param>
<param-name>startIndex</param-name>
<param-value>0</param-value>
</context-param> *
注意:以上的配置信息属于应用级的配置信息,一般一个项目中共享的配置信息会被放到以上的标签中。
如果你的配置信息只想给某一个servlet作为参考,那么你只需要配置到servlet标签中,使用<init-param></init-param>标签
使用ServletConfig对象来获取
//public String getContextPath(); 获取context path(获取应用上下文的根)
//public String getRealPath(String path); 获取文件的绝对路径(真实路径) *
*通过ServletContext对象也是可以记录日志的 *
public void log(String message);
public void log(String message,Throwable t);
代码示例:
package com.javaweb.servlet;
import javax.servlet.*;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
public class AServlet extends GenericServlet {
@Override
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
//获取ServletContext对象
ServletContext application = this.getServletContext();
out.print("ServletContext对象是:"+application);
out.print("<br/>");
//获取上下文的初始化参数
Enumeration<String> initParameterNames = application.getInitParameterNames();
while (initParameterNames.hasMoreElements()){
String name=initParameterNames.nextElement();
String value = application.getInitParameter(name);
out.print(name+"="+value+"<br/>");
//startIndex=0
//pageSize=10
}
//获取context path(获取应用上下文的根);
//public String getContextPath(); 很重要:因为在Java源代码当中有一些地方可能会需要应用的根路径,这个方法可以动态的获取应用的根路径
//在Java源码当中,不要将应用的根路径写死,因为你有冤都不知道这个应用在最终部署的时候,起一个什么名字。
String contextPath = application.getContextPath();
out.print(contextPath+"<br/>");// "/servlet04"
// public String getRealPath(String path);
// 获取文件的绝对路径(真实路径)
//后面加”/“,代表是从web的根下开始找
// String realPath = application.getRealPath("/index.html");//可以
//后面不加”/“,默认也是从web的根下开始找
String realPath = application.getRealPath("index.html");//不加”/“也可以
out.print(realPath+"<br/>");
String realPath1 = application.getRealPath("/common/common.html");
out.print(realPath1+"<br/>");
//准备数据
User user = new User("jack", "123");
//向ServletContext应用域中存储数据
application.setAttribute("userObj",user);
//取出来(在A中取)
Object userObj = application.getAttribute("userObj");
//输出到浏览器
out.print(userObj+"<br/>");
}
}
package com.javaweb.servlet;
import javax.servlet.*;
import java.io.IOException;
import java.io.PrintWriter;
public class BServlet extends GenericServlet {
@Override
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
//获取ServletContext对象
ServletContext application = this.getServletContext();
out.print("ServletContext对象是:"+application);
//log记录日志
//这个日志会记录在哪里?
//CATALINA_HOME/logs目录下
//如果使用的是原始的你方法,没有集成开发工具 ,是可以记录到tomcat的logs目录下的
//但是,使用集成开发工具,会记录到相关的文件中
application.log("大家好,我是一个学习IT的小萌新。");
//我的原始的tomcat的路径是:D:\apache-tomcat-9.0.68
//Using CATALINA_BASE: "C:\Users\cxvqq\AppData\Local\JetBrains\IntelliJIdea2021.3\tomcat\6b4fb480-0ba5-4dee-b2f7-1287a36abb30"
//该目录下的logs文件的catalina...文件是记录:服务器端Java程序运行的控制台信息
//localhost_access...文件记录的是:访问的日志(一次请求一次记录)
//localhost..文件记录的是:ServletConfig对象的log方法记录的日志信息
// 就是application.log("大家好,我是一个学习IT的小萌新。"),
out.print("<br/>");
//取出来(如果直接访问会是null,需要先发送A请求把数据存进去)
Object userObj = application.getAttribute("userObj");
//输出到浏览器
out.print(userObj+"<br/>");
}
}