JavaWeb 速通Servlet(ServletConfig和ServletContext)

举报
Cyan_RA9 发表于 2023/09/01 09:43:26 2023/09/01
【摘要】 JavaWeb——ServletConfig 和 ServletContext 内容分享。

目录

一、ServletConfig

        1.基本介绍 : 

        2.基本功能 : 

        3.应用实例 : 

        4.细节补充 : 

二、ServletContext

        1.基本介绍 : 

        2.基本功能 : 

        3.获取Web工程相关信息 : 

        4.网页访问计数器 : 

            1° 代码实现  

            2° 代码优化 

三、Servlet(中)总结



一、ServletConfig

        1.基本介绍 : 

  1.     ServletConfig类是为Servlet程序的配置信息的类;
  2.     Servlet程序和ServletConfig对象都是由Tomcat负责创建;
  3.     Servlet程序默认是在第1次访问的时候被创建,ServletConfig则是Tomcat在创建servlet实例时,同时创建一个对应的ServletConfig对象

        2.基本功能 : 

  •     获取Servlet程序的servlet-name的值
  •     获取初始化参数init-param
  •     获取ServletContext对象

        3.应用实例 : 

                编写DBServlet类,要求该servlet可以获取到web.xml配置文件中的数据库登录信息。

                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>DBServlet</servlet-name>
        <servlet-class>db.DBServlet</servlet-class>
        <init-param>
            <param-name>username</param-name>
            <param-value>Five</param-value>
        </init-param>
        <init-param>
            <param-name>password</param-name>
            <param-value>12345</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>DBServlet</servlet-name>
        <url-pattern>/dBServlet</url-pattern>
    </servlet-mapping>
</web-app>

                DBServlet代码如下 : 

package db;

import jakarta.servlet.ServletConfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

/**
 * @author : Cyan_RA9
 * @version : 21.0
 */
public class DBServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        /*
            直接父类HttpServlet中没有getServletConfig方法,因此要向再上一层的父类GenericServlet中找。
            最终返回的就是GenericServlet中的config属性。
         */
        ServletConfig servletConfig = getServletConfig();
        String username = servletConfig.getInitParameter("username");
        String password = servletConfig.getInitParameter("password");

        System.out.println(("Init-Param username = " + username));
        System.out.println(("Init-Param password = " + password));
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }
}

                运行效果 : (如下GIF图)

编辑

        4.细节补充 : 

        当Servlet实例被创建时,Tomcat会同时创建一个对应的ServletConfig对象

        此时,如果重写了init方法,必须定义super.init(config);语句,这时Tomcat就会把创建的ServletConfig对象作为实参传递到init方法的形参列表,并通过super语句最终将该ServletConfig实例赋值给GenericServlet类的config属性

        eg : 

    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
    }

        如此一来,才能在其他方法中通过getServletConfig方法获取到正确的config属性。


二、ServletContext

        1.基本介绍 : 

  1.         ServletContext是一个接口,表示Servlet上下文对象。
  2.         一个web工程,只有一个ServletContext对象实例;ServletContext对象是在web工程启动的时候创建,在web工程终止的时销毁
  3.         获取ServletContext对象既可以通过ServletConfig.getServletContext()也可以直接通过this.getServletContext(),来获得其对象的引用。
  4.         由于一个WEB应用中的所有Servlet共享同一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象来实现多个Servlet间通讯ServletContext对象通常也被称之为域对象。
        PS : 
       
ServletContext对象的数据存储形式为key-value键值对,类似于Map集合

        2.基本功能 : 

  •     获取web.xml中配置的上下文参数context-param整个web应用相关,而不是属于某个Servlet)
  •     动态地获取当前的工程路径(Application Context),格式 :/工程路径
  •     获取工程部署后,在服务器硬盘上的绝对路径(out目录
  •     像Map集合一样存取数据(keg-value键值对),且同一Web应用下的多个Servlet,共享ServletContext对象的数据

        3.获取Web工程相关信息 : 

                定义一个servlet,要求该servlet可以获取到当前Web应用的相关信息(上下文参数、项目路径、实际工作路径)
                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>ProjectServlet</servlet-name>
        <servlet-class>middle.ProjectServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>ProjectServlet</servlet-name>
        <url-pattern>/psToGetInfo</url-pattern>
    </servlet-mapping>
    
    <!--配置整个Web应用的相关信息-->
    <context-param>
        <param-name>website</param-name>
        <param-value>https://blog.csdn.net/TYRA9?spm=1010.2135.3001.5343</param-value>
    </context-param>
    <context-param>
        <param-name>blogger</param-name>
        <param-value>Cyan_RA9</param-value>
    </context-param>
</web-app>

                ProjectServlet代码如下 : 

package middle;

import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

/**
 * @author : Cyan_RA9
 * @version : 21.0
 */
public class ProjectServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.获取ServletContext对象
        ServletContext servletContext = this.getServletContext();

        //2.获取web.xml中配置的上下文参数
        String website = servletContext.getInitParameter("website");
        String blogger = servletContext.getInitParameter("blogger");
        System.out.println("website = " + website);
        System.out.println("blogger = " + blogger);

        //3.获取整个Web应用的项目路径
        String contextPath = servletContext.getContextPath();
        System.out.println("contextPath = " + contextPath);

        //4.获取工程部署后,在磁盘的绝对路径(实际工作时访问的路径)
            // "/"表示项目(部署后)的根路径
        String realPath = servletContext.getRealPath("/");
        System.out.println("realPath = " + realPath);
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }
}

                运行效果:(如下GIF图)

编辑

        4.网页访问计数器 : 

            1° 代码实现  

                要求统计某一个Web工程下所有servlet累计被访问的次数,并将该次数以标题形式返回给浏览器。
                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>CountServlet</servlet-name>
        <servlet-class>middle.CountServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>CountServlet</servlet-name>
        <url-pattern>/countServlet</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>CountServlet_EX</servlet-name>
        <servlet-class>middle.CountServlet_EX</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>CountServlet_EX</servlet-name>
        <url-pattern>/countServletEX</url-pattern>
    </servlet-mapping>
</web-app>

                分别定义CountServlet和CountServlet_EX两个servlet进行模拟;
                CountServlet代码如下 : 

package middle;

import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.io.PrintWriter;

public class CountServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = this.getServletContext();
        System.out.println("servletContext = " + servletContext);
        System.out.println("servletContext's runtime Class = " + servletContext.getClass());
        System.out.println("==========================================");

        Object visits = servletContext.getAttribute("visits");
        if (visits == null) {    //说明是第一次访问该Web工程
            servletContext.setAttribute("visits", 1);
            visits = 1;
        } else {                 //说明是非首次访问该Web工程
            visits = Integer.parseInt(visits + "") + 1;
            servletContext.setAttribute("visits", visits);
        }

        resp.setContentType("text/html; charset=utf-8");
        PrintWriter writer = resp.getWriter();
        writer.print("<h1>网站被访问了" + visits + "次了捏🤗</h1>");

        writer.flush();
        writer.close();
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }
}

                CountServlet_EX代码如下 : 

package middle;

import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.io.PrintWriter;

public class CountServlet_EX extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = this.getServletContext();
        System.out.println("servletContext_EX = " + servletContext);
        System.out.println("servletContext_EX's runtime Class = " + servletContext.getClass());
        System.out.println("-----------------------------------------------");

        Object visits = servletContext.getAttribute("visits");
        if (visits == null) {
            servletContext.setAttribute("visits", 1);
            visits = 1;
        } else {
            visits = Integer.parseInt(visits + "") + 1;
            servletContext.setAttribute("visits", visits);
        }

        resp.setContentType("text/html; charset=utf-8");
        PrintWriter writer = resp.getWriter();
        writer.print("<h1>网站被访问了" + visits + "次了捏🤗</h1>");

        //保险起见!
        writer.flush();
        writer.close();
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }
}

                运行效果 : (如下GIF图)

编辑

                在IDEA中可以看到,两个servlet使用的ServletContext对象是同一个,如下图所示 : 

编辑

            2° 代码优化 

                可以将CountServlet和CountServlet_EX中重复冗余的代码封装到一个工具类中,在该工具类中定义静态方法,用于返回网站被访问的总次数。

                WebUtils类代码如下 : 

package middle;

import jakarta.servlet.ServletContext;

public class WebUtils {
    public static Integer visitCount(ServletContext servletContext) {
        Object visits = servletContext.getAttribute("visits");
        if (visits == null) {
            servletContext.setAttribute("visits", 1);
            visits = 1;
        } else {
            visits = Integer.parseInt(visits + "") + 1;
            servletContext.setAttribute("visits", visits);
        }

        return Integer.parseInt(visits + "");
    }
}

                接着,在CountServlet和CountServlet_EX类中去调用visitCount静态方法即可,如下图所示 : 

编辑

                运行效果 :(如下GIF图)

编辑

三、Servlet(中)总结

        (1) 熟悉ServletConfig创建的时机 (Tomcat在创建Servlet实例时创建其对应的ServletConfig;最终使用的是GenericServlet中的config属性);

        (2) 掌握ServletConfig的API(获取定义在<servlet></servlet>中的初始化参数);

        (3) 熟悉ServletContext的特性(一个Web工程仅对应一个ServletContext对象);

        (4) 熟悉ServletContext的功能(获取Web应用的上下文参数;获取工程路径;获取工程部署后的绝对路径;作为同一Web工程下servlet的共享数据的容器)

        (5) 掌握ServletContext对象获取Web项目信息的API (getInitParameter, getContextPath, getRealPath)

        (6) 掌握ServletContext对象操作属性的API (getAttribute, setAttribute)。

        System.out.println("END------------------------------------------------------------------------------"); 

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

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

全部回复

上滑加载中

设置昵称

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

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

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