ServletConfig和ServletContext详解

ServletConfig

  • String getServletName()  -- 获取当前Servlet在web.xml中配置的名字
  • String getInitParameter(String name) -- 获取当前Servlet指定名称的初始化参数的值
  • Enumeration getInitParameterNames()  -- 获取当前Servlet所有初始化参数的名字组成的枚举
  • ServletContext getServletContext()  -- 获取代表当前web应用的ServletContext对象

当servlet配置了初始化参数后,web容器在创建servlet实例对象时,会自动将这些初始化参数封装到ServletConfig对象中,

并在调用servlet的init()方法时,将ServletConfig 对象传递给servlet。进而,通过ServletConfig对象就可以得到当前servlet的初始化参数。

1)初始化参数配置在<init-param>标签中,如:

<servlet>
        <servlet-name>springServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:/conf/app-mvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

2)服务器会自动封装在ServletConfig中,我们利用init()或者init(ServletConfig config)方法,可以只获取一次ServletConfig对象,

然后通过其getInitParameter()方法,获取配置好的参数。

ServletConfig对象也可以直接通过父类GenericServlet封装好的getServletConfig()方法获取或直接通过父类封装的getInitParameter()直接获取。

@Override  
public void init(ServletConfig config) throws ServletException {  
      
    // 如果重写父类带参数的init()方法,这句一定写。  
    // 不然拿不到ServletConfig 对象,空指针。  
    // 原因在于,父类中代参的init()实现的时候,先this.config = config;然后调用无参this.init();  
    super.init(config);  
      
    String userName = config.getInitParameter("userName");  
      
    String userName2 = this.getInitParameter("userName");  
      
    String userName3 = this.getServletConfig().getInitParameter("userName");  
      
    logger.debug("初始化参数1: "+userName+" | "+"初始化参数2: "+userName2+" | 初始化参数3: "+userName3);  
      
}  
  
@Override  
public void init() throws ServletException {  
      
    String userName2 = this.getInitParameter("userName");  
      
    String userName3 = this.getServletConfig().getInitParameter("userName");  
      
    logger.debug("初始化参数4: "+userName2+" | 初始化参数5: "+userName3);  
      
}  

3)注意点:如果重写父类带参数的init()方法,这句一定写,super.init(config),不然拿不到ServletConfig 对象,空指针。原因在于,父类中代参的init()实现的时候,先this.config = config;然后调用无参this.init()。其实你复写两个init()方法后,输出的顺序也解释了这一点。推荐使用不带参数的init()方法。父类代码以及上例输出如下:

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

4)通过getInitParameterNames(),可以获取枚举类型的所有初始化参数。

 

ServletContext

 

1、简介:

1)生命周期:Web容器在启动时,它会为每个Web应用程序都创建一个对应的ServletContext对象,它代表当前Web应用。ServletContext对象只在Web应用被关闭时才被销毁;不同的Web应用,ServletContext各自独立存在。

2)获取:SevletConfig 对象中维护了 ServletContext 对象的引用,通过 SevletConfig.getServletContext()方法获取ServletContext 对象。或者直接调用封装好的getServletContext ()方法即可获取。 

3)作用:由于一个Web应用中的所有 Servlet 共享同一个ServletContext 对象,因此 Servlet  对象之间可以通过ServletContext  对象来实现通讯。 ServletContext 对象通常也对称之为context 域对象。

 

2、应用:

1)获取上下文参数。context-param 标签配置得参数是供web应用共享的,所有的servlet都可以访问。

<web-app>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath:/conf/app-root.xml
        </param-value>
    </context-param>
</web-app>
// 知识点二:获取上下文参数,上下文参数是给所有Servlet使用的  
String xxx= servletContext.getInitParameter("XXX");  
logger.debug("获取上下文参数: " + xxx);  

2)利用ServletContext,实现 Servlet  对象之间通讯。 主要是4个有关 Attribute 的方法:setAttribute()、getAttribute()、removeAttribute()、getAttributeNames()。

// 所有servlet实现通信  
servletContext.setAttribute("new_userName", userName);  
String new_userName = (String) servletContext.getAttribute("new_userName");  
logger.debug("所有servlet实现通信: " + new_userName);  
servletContext.removeAttribute("new_userName");  
servletContext.getAttributeNames(); 

3)利用ServletContext获取资源文件的方法。首先创建一个配置文件jdbc.properties,放在source文件夹comfig下;其次写一个配置文件读取方法:

/** 
 * 抽出的方法,固定写法 
 * @param in 
 * @throws IOException 
 */  
private void getProperites(InputStream in) throws IOException {  
    Properties props = new Properties();  
    props.load(in);  
    String url = props.getProperty("url");  
    String username = props.getProperty("username");  
    String password = props.getProperty("password");  
      
    logger.debug(url);  
    logger.debug(username);  
    logger.debug(password);  
}  

A、getResource() :获取资源文件的URL后,直接通过openStream()得到流。

// 1-利用 getResource 得到URL ,然后直接 构建IO流  
URL url = servletContext.getResource("/WEB-INF/classes/jdbc.properties");//得到URL              
InputStream in_url = url.openStream();//直接得到流  
getProperites(in_url);//获取资源文件  

解释:"/WEB-INF/classes/jdbc.properties": 以“/”开头,代表web工程 部署好以后的配置文件的地址,src其实就是/WEB-INF的classes文件夹。

 

B、利用 getResourceAsStream() 获取配置文件。——最常用。

// 2-1 利用 getResourceAsStream 获取配置文件  
// 以“/”开头,代表web工程 部署好以后的配置文件的地址,src其实就是/WEB-INF的classes文件夹  
InputStream in = servletContext.getResourceAsStream("/WEB-INF/classes/jdbc.properties");  
this.getProperites(in);  

C、getRealPath() 得到资源文件的绝对路径。利用文件流,获取资源文件。

注意,不能使用传统的相对路径获取资源文件。

如:FileInputStream fileIn = new FileInputStream("/classes/jdbc.properties");因为相对的是Java虚拟机的路径,即这边是tomcat的bin/start.bat所在的文件夹,这样肯定找不到资源文件。可以再toncat的bin下新classes/jdbc.properties,试验看看。

// 2-2 getRealPath 得到资源文件的绝对路径  
            // 这种方式可以获取文件的名称,可以用于下载文件得开发。  
            String realPath = servletContext.getRealPath("/WEB-INF/classes/jdbc.properties");  
            logger.debug("资源文件的绝对路径 : " + realPath);  
                          
            // 在web项目中不能直接使用传统相对路径访问文件,如  
            // FileInputStream fileIn = new FileInputStream("/classes/jdbc.properties");  
            // 因为相对的是Java虚拟机的路径,即这边是tomcat的bin/start.bat所在的文件夹,这样肯定找不到资源文件。http://  
            // 可以再toncat的bin下新建classes/jdbc.properties,试验看看  
            FileInputStream fileIn = new FileInputStream(realPath);  
            this.getProperites(fileIn);  

 

D、地址的写法。地址给谁用的。如果是给服务器用的,以"/"代表当前web应用; 如果是给浏览器用的,代表网址。

/* 
         * 原则:地址给谁用的。如果是给服务器用的,以"/"代表当前web应用; 如果是给浏览器用的,代表网址。 
         */  
          
          
        //转发 -服务器使用,"/"是当前web应用  
        request.getRequestDispatcher("/my.jsp").forward(request, response);  
          
        //重定向-浏览器使用,增加上下文路径  
        response.sendRedirect("/JavaWeb/my.jsp");  
          
        //获取资源-getRealPath。  
        this.getServletContext().getRealPath("/my.jsp");  
          
        //获取资源-getResourceAsStream  
        this.getServletContext().getResourceAsStream("/my.jsp");  
          
        //页面地址的-浏览器使用  
//      <form action="/JavaWeb/my.jsp">  

 

4)利用ClassLoader获取资源文件。在《java进阶(六):Java类加载器》中已经有涉及到。这边作补充。

A、getResourceAsStream() 。利用classLoader获取资源文件 不能以'/'打头

// 3-1 利用classLoader获取资源文件 不能以'/'打头  
// 新建一个与src同级别的source文件夹comfig,里面存放 jdbc.properties文件  
InputStream is = this.getClass().getClassLoader().getResourceAsStream("jdbc.properties");  
this.getProperites(is);  
  
// 3-1-1 变化的 classLoader获取资源文件 ,项目中常用。  
      ClassLoader loader = Thread.currentThread().getContextClassLoader();  
      InputStream resourceAsStream = loader.getResourceAsStream("jdbc.properties");  
      this.getProperites(resourceAsStream);  

B、getResource():得到绝对路径,然后获取配置文件。

// 3-2 利用类加载器读取配置文件,不能实时的获取最新的配置文件信息。类加载器加载过的类,就不会再加载  
// getResource()返回的是URL,然后getPath()再获取绝对路径,这样就可以获取更新后的数据  
URL classUrl = this.getClass().getClassLoader().getResource("jdbc.properties");  
String path = classUrl.getPath();  
logger.debug("利用getResource() 获取配置文件的路径: "+path);  
this.getProperites(new FileInputStream(path));  

 

参考文献:

Servlet学习笔记(五):ServletConfig和ServletContext详解

JavaWeb学习之Servlet(四)----ServletConfig获取配置信息、ServletContext的应用

posted @ 2017-10-24 17:49  图生  阅读(581)  评论(0编辑  收藏  举报