Servlet常用类剖析

举报
执久呀 发表于 2022/07/25 07:10:58 2022/07/25
【摘要】 ​目录通过继承HttpServlet实现Servlet程序 使用idea创建Servlet程序Servlet的继承体系 doGet和dopost源码 servlet方法部分源码ServletConfig类ServletConfig类的三大作用ServletContext类什么是ServletContext?什么是域对象?对照示意表:ServletContext类的四个作用1、获取web.xm...


目录


通过继承HttpServlet实现Servlet程序

 使用idea创建Servlet程序

Servlet的继承体系

 doGet和dopost源码

 servlet方法部分源码

ServletConfig类

ServletConfig类的三大作用

ServletContext类

什么是ServletContext?

什么是域对象?

对照示意表:

ServletContext类的四个作用

1、获取web.xml中的配置的上下文参数,

 易错点:

获取当前工程路径

获取部署后在服务器硬盘上的绝对路径

map一样存取数据


通过继承HttpServlet实现Servlet程序

实际开发中,一般使用继承HttpServlet类的方法去实现Servlet程序。

步骤:

1、编写一个类去继承HttpServlet类

2、根据业务需要重写doGet或doPost方法

3、到web.xml中配置Servlet程序

1、编写一个类,Alt+insert快捷键重写里一些需要的方法

编辑


import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class HelloServlet2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       // super.doGet(req, resp);
        System.out.println("HelloServlet2的 get请求");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
      //  super.doPost(req, resp);
        System.out.println("HelloServlet2的 post请求");
    }
}

到web.xml文件中配置访问路径

    <servlet>
        <servlet-name>HelloServlet2</servlet-name>
        <servlet-class>com.servlet.HelloServlet2</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>HelloServlet2</servlet-name>
        <url-pattern>/hello2</url-pattern>
    </servlet-mapping>

将表单中的访问地址hello改变为hello2

运行提交后:

编辑

 使用idea创建Servlet程序

选择要实现的包→Servlet程序

编辑

 配置信息

编辑

勾选上用的就是3.0的注解配置 

 只需要在web.xml中加上路径即可(其他的已经自动生成了)

    <servlet-mapping>
        <servlet-name>HelloServlet3</servlet-name>
        <url-pattern>/hello3</url-pattern>
    </servlet-mapping>

Servlet的继承体系

编辑

 doGet和dopost源码

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String msg = lStrings.getString("http.method_get_not_supported");
        this.sendMethodNotAllowed(req, resp, msg);
    }
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String msg = lStrings.getString("http.method_post_not_supported");
        this.sendMethodNotAllowed(req, resp, msg);
    }

 servlet方法部分源码

 protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String method = req.getMethod();
        long lastModified;
        if (method.equals("GET")) {
            lastModified = this.getLastModified(req);
            if (lastModified == -1L) {
                this.doGet(req, resp);
            } else {
                long ifModifiedSince;
                try {
                    ifModifiedSince = req.getDateHeader("If-Modified-Since");
                } catch (IllegalArgumentException var9) {
                    ifModifiedSince = -1L;
                }

                if (ifModifiedSince < lastModified / 1000L * 1000L) {
                    this.maybeSetLastModified(resp, lastModified);
                    this.doGet(req, resp);
                } else {
                    resp.setStatus(304);
                }
            }
        }

ServletConfig类

  • ServletConfig是Servlet程序的配置信息类。
  • Servlet程序和ServletConfig对象都是有Tomcat负责创建,我们负责使用。
  • Servlet程序默认是一次访问的时候创建,ServletConfig是每个Servlet程序创建时,就创建一个对应的ServletConfig对象

ServletConfig类的三大作用

1、可以获取Servlet程序的别名(servlet-name的值)

2、获取初始化参数init-param

3、获取ServletContent对象

所处位置init方法

1、获取servlet别名

  public void init(ServletConfig servletConfig) throws ServletException {
         System.out.println("HelloServlet 的别名是"+servletConfig.getServletName()); 
  }

2、获取初始化参数init-param,其他的前面谢过了

现在web.xml文件中配<init-param>

<!--servlet标签给Tomcat配置Servlet程序-->
    <servlet>
        <!-- servlet-name给Servlet程序起一个别名(一般别名起为类名)-->
        <servlet-name>HelloServlet</servlet-name>
        <!--servlet-class是Servlet程序的全类名 -->
        <servlet-class>com.servlet.HelloServlet</servlet-class>

        <!--init-param时初始化参数,这是个键值对可以写很多对 -->
        <init-param>
            <!-- 参数名-->
            <param-name>username</param-name>
            <!--是参数的值 -->
            <param-value>root</param-value>
        </init-param>
        <init-param>
        <!-- 参数名-->
        <param-name>url</param-name>
        <!--是参数的值 -->
        <param-value>jdbc:mysql://localhost:3306/text</param-value>
        </init-param>
    </servlet>

在实现Servlet接口的类中的init()下

  // 2、获取初始化参数init-param
        System.out.println("初始化参数username的值是"+servletConfig.getInitParameter("username"));
        System.out.println("初始化参数url的值是"+servletConfig.getInitParameter("url"));

3、获取ServlertContent对象

 // 3、获取ServletContent对象
        System.out.println("servletcontent对象是"+servletConfig.getServletContext());

以上运行结果:

编辑

每一个ServletConfig程序独立 ,在web.xml 中每个类中信息不共享,

重写init方法时得加上super.init(config),得访问父类的init初始化方法,否则报错

继承体系可以得知ServletConfig在GenericServlet类中,该类中的init定义:

    public void init(ServletConfig config) throws ServletException {
        this.config = config;
        this.init();
    }

所以如果重写init方法,必须加上super.init(config),否则父类的init方法不会执行(父类中中的保存操作执行不了)

ServletContext类

什么是ServletContext?

1、ServletContent是一个接口,他表示Servlet上下文对象

2、一个web工程,只有一个ServletContext对象实例。

3、ServletContent对象是一个域对象。

4、在web工程启动后创建,在web工程结束后销毁

什么是域对象?

域对象,是可以像Map一样存取数据的对象,叫做域对象。

这里的域指的是存取数据的操作范围。

对照示意表:

存数据 取数据 删除数据
Map put() get() remove()
域对象 setAttribute() getAttribute() removeAttribute()

ServletContext类的四个作用

1、获取web.xml中的配置的上下文参数context-param

2、获取当前的工程路径你,格式:/工程路径

3、获取部署后在服务器硬盘上的绝对路径

4、像Map一样存取数据

用快捷方式创建一个类ContextServlet,在web.xml中配置路径(   其余的已经自动生成了)

    <servlet>
        <servlet-name>ContextServlet</servlet-name>
        <servlet-class>com.servlet.ContextServlet</servlet-class>
    </servlet>
<!-- 上面自动生成了,下面要自己书写的路径-->
    <servlet-mapping>
        <servlet-name>ContextServlet</servlet-name>
        <url-pattern>/contextServlet</url-pattern>
    </servlet-mapping>

1、获取web.xml中的配置的上下文参数,

首先得在web.xml中配置context-param(一般写在其他servlet之上)

<!--context-param是上下文参数(他属于整个web工程)-->
    <context-param>
        <!--参数名 -->
        <param-name>username</param-name>
        <!--参数值-->
        <param-value>context</param-value>
    </context-param>
<!--可以写多对上下文参数-->
    <context-param>
        <param-name>password</param-name>
        <param-value>root</param-value>
    </context-param>

在ContextServlet类中doGet()方法

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1、获取web.xml中的配置的上下文参数context-param
        //获取对象
        ServletContext context = getServletConfig().getServletContext();
        String username = context.getInitParameter("username");
        String password = context.getInitParameter("password");
        System.out.println("context-param参数username的值是"+username);
        System.out.println("context-param参数password的值是"+password);
    }
}

运行之后结果是: 

编辑

 易错点:

①:在配置web.xml文件中地址中的/斜杆不要忘记,否则会报地址无效

 <url-pattern>/contextServlet</url-pattern>

②:在类中获取参数是应在doGet()方法中书写,否则运行之后访问地址不会显示处对应的信息

获取当前工程路径

     System.out.println("当前工程路径:"+context.getContextPath());

编辑


获取部署后在服务器硬盘上的绝对路径


System.out.println("获取工程部署的路径"+context.getRealPath("/"));

编辑

 这个斜杆/表示到当前工程的路径

编辑

map一样存取数据

创建一个Servlet类,在web.xml文件中配置好路径

   <servlet>
        <servlet-name>ContextServlet1</servlet-name>
        <servlet-class>com.servlet.ContextServlet1</servlet-class>
    </servlet>
<!-- 以上自动配好-->
  <servlet-mapping>
        <servlet-name>ContextServlet1</servlet-name>
        <url-pattern>/contextServlet1</url-pattern>
    </servlet-mapping>

在类中:

public class ContextServlet1 extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         //获取ServletContext对象
        ServletContext context = getServletContext();
        System.out.println("保存之前Context获取key1的值是:"+context.getAttribute("key1"));
        context.setAttribute("key1","value1");
        System.out.println("context获取数据key1的值为:"+context.getAttribute("key1"));
    }
}

我们直接可以用getServletContext()获取对象,这样简单些,而不用getServletConfig().getServletContext();

我们ctrl+b看源码可知:

    public ServletContext getServletContext() {
        return this.getServletConfig().getServletContext();
    }

源代码已经做好了那步,所以我们直接返回即可。

编辑



我们继续定义一个类叫ContextServlet2

public class ContextServlet2 extends HttpServlet {


    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletContext context = getServletContext();
        System.out.println("ContextServlet2中 context获取数据key1的值为:"+context.getAttribute("key1"));
    }
}

部署就省略了,运行之后

编辑

 不难发现当ContextServlet1中的有数据存入,ContextServlet2中就可以查到该数据。也可以context下的数据是共享数据

 编辑

 ContextServlet对象在web工程启动后创建,在web工程结束后销毁,且共享

重启和重新部署都会导致web工程销毁

编辑

 ContextServlet1、2的地址也是一样的

编辑


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。