前面文章参考:

IDEA(2020版)实现Servlet程序 – 每天进步一点点

IDEA(2020版)实现Servlet的生命周期 – 每天进步一点点

本文主要介绍在IDEA中实现ServletConfig和ServletContext

本文源代码:https://box356.lanzoub.com/i2P4u2ruvvna

1.ServletConfig接口

参考第一章代码,右击src文件夹,New—>Create New Servlet

名字为TestServlet4_4

参考代码如下:

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet(name = "TestServlet4_4",value = "/test44", initParams = {@WebInitParam(name = "encoding", value = "UFT-8"),})
public class TestServlet4_4 extends HttpServlet {
    protected void doGet(HttpServletRequest request,
                         HttpServletResponse response) throws ServletException, IOException {
        PrintWriter out = response.getWriter();
        // 获得ServletConfig对象
        ServletConfig config = this.getServletConfig();
        // 获得参数名为encoding对应的参数值
        String param = config.getInitParameter("encoding");
        out.println("encoding=" + param);
    }

    protected void doPost(HttpServletRequest request,
                          HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

在浏览器中输入

http://localhost:8080/Servlet01_war_exploded/test44

请注意,这个地址并不和课本上一致,后面的test44是来自于代码中的value值,前面的是Tomcat配置的地址。

效果如下:

2.ServletContext接口

当Servlet容器启动时,会为每个Web应用创建一个唯一一个ServletContext对象代表当前Web应用。ServletContext对象不仅封装了当前Web应用的所有信息,而且实现了多个Servlet之间数据的共享。

(1)获取Web应用程序的初始化参数

我们打开web—>WEB-INF,打开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">


    <context-param>
        <param-name>companyName</param-name>
        <param-value>baidu</param-value>
    </context-param>
    <context-param>
        <param-name>address</param-name>
        <param-value>beijing</param-value>
    </context-param>
    <context-param>
        <param-name>postalCode</param-name>
        <param-value>100000</param-value>
    </context-param>
</web-app>

然后创建test测试文件,右击src—>New—>Create New Servlet

Servlet名词起为TestServlet4_5

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;

@WebServlet(name = "TestServlet4_5",value = "/test45")
public class TestServlet4_5 extends HttpServlet {
    public void doGet(HttpServletRequest request,
                      HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        // 得到ServletContext对象
        ServletContext context = this.getServletContext();
        // 得到包含所有初始化参数名的Enumeration对象
        Enumeration<String> paramNames = context.getInitParameterNames();
        out.println("all the paramName and paramValue are following:");
        // 遍历所有的初始化参数名,得到相应的参数值并打印
        while (paramNames.hasMoreElements()) {
            String name = paramNames.nextElement();
            String value = context.getInitParameter(name);
            out.println(name + ":" + value);
            out.println("<br />");
        }
    }

    public void doPost(HttpServletRequest request,
                       HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

执行结果如下:

(2)实现多个Servlet对象数据共享

因为一个Web应用中的所有Servlet共享同一个SevletContext对象,所以ServletContext对象的域属性可以被该Web应用中所有的Servlet访问。

我们创建两个Servlet对象,一个使用set方法调用setAttribute写入数据,一个使用getAttribute获取刚才写入的数据。

然后创建test测试文件,右击src—>New—>Create New Servlet

名字命名为TestServlet4_6

代码参考如下:

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

@WebServlet(name = "TestServlet4_6",value = "/test46")
public class TestServlet4_6 extends HttpServlet {
    public void doGet(HttpServletRequest request,
                      HttpServletResponse response) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        // 通过setAttribute()方法设置属性值
        context.setAttribute("data", "this servlet save data");
    }

    public void doPost(HttpServletRequest request,
                       HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

再创建一个Servlet,命名为TestServlet4_7

代码参考如下:

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Properties;

@WebServlet(name = "TestServlet4_7",value = "/test47")
public class TestServlet4_7 extends HttpServlet {
    public void doGet(HttpServletRequest request,
                      HttpServletResponse response) throws ServletException, IOException {
        PrintWriter out = response.getWriter();
        ServletContext context = this.getServletContext();
        // 通过getAttribute()方法获取属性值
        String data = (String) context.getAttribute("data");
        out.println(data);
    }

    public void doPost(HttpServletRequest request,
                       HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

执行效果如下:

(3)读取Web应用下的资源文件

在实际开发中,有时候需要读取Web应用中的一些资源文件,例如配置文件、图片等。为此,ServletContext接口定义了一些读取Web资源的方法、这些方法是依靠Servlet容器来实现的。Servlet容器根据资源文件相对于Web应用的路径,返回关联资源文件的IO流、资源文件在文件系统的绝对路径等。

getResourceAsStream演示:

我们在src目录下创建一个文件,叫itcast.properties,里面的内容参考如下:

Company = itcast
Address = Beijing

然后右击src—>New—>Create New Servlet,名称就叫TestServlet4_8

代码参考如下:

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Properties;

@WebServlet(name = "TestServlet4_8",value = "/test48")
public class TestServlet4_8 extends HttpServlet {
    public void doGet(HttpServletRequest request,
                      HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        ServletContext context = this.getServletContext();
        PrintWriter out = response.getWriter();
        //获取相对路径中的输入流对象
        InputStream in = context.getResourceAsStream("/WEB-INF/classes/itcast.properties");
        Properties pros = new Properties();
        pros.load(in);
        out.println("Company=" + pros.getProperty("Company") + "<br />");
        out.println("Address=" + pros.getProperty("Address") + "<br />");
    }

    public void doPost(HttpServletRequest request,
                       HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

在浏览器里输入下面地址

http://localhost:8080/Servlet01_war_exploded/test48

实现的效果如下:

getRealPath用法演示

继续新建Servlet类,然后右击src—>New—>Create New Servlet,名称就叫TestServlet4_9

代码参考如下:

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Properties;

@WebServlet(name = "TestServlet4_9",value = "/test49")
public class TestServlet4_9 extends HttpServlet {
    public void doGet(HttpServletRequest request,
                      HttpServletResponse response) throws ServletException, IOException {
        PrintWriter out = response.getWriter();
        ServletContext context = this.getServletContext();
        //获取文件绝对路径
        String path = context.getRealPath("/WEB-INF/classes/itcast.properties");
        FileInputStream in = new FileInputStream(path);
        Properties pros = new Properties();
        pros.load(in);
        out.println("Company=" + pros.getProperty("Company"));
        out.println("Address=" + pros.getProperty("Address"));
    }

    public void doPost(HttpServletRequest request,
                       HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

我们在浏览器里输入下面的地址

http://localhost:8080/Servlet01_war_exploded/test49

效果如下: