• Servlet--取得初始化配置信息



    关于这块内容,主要就是玩一个接口:ServletConfig。先翻下API,了解一下。
    定义:
    public interface ServletConfig
    这个接口定义了一个对象,通过这个对象,Servlet引擎配置一个Servlet并且允许Servlet获得一个有关它的ServletContext接口的说明。每一个ServletConfig对象对应着一个唯一的Servlet。
    方法:
    1、getInitParameter public String getInitParameter(String name);
    这个方法返回一个包含Servlet指定的初始化参数的String。如果这个参数不存在,返加空值。

    2、getInitParameterNames public Enumeration getInitParameterNames();

    这个方法返回一个列表String对象,该对象包括Servlet的所有初始化参数名。如果Servlet没有初始化参数,getInitParameterNames返回一个空的列表。
    3、getServletContext public ServletContext getServletContext();

    返回这个Servlet的ServletContext对象。


    现在我们在看一下Tomcat中这个接口的实现,Tomcat使用了门面模式,也就是将ServletConfig封装一下,里面提供的各个方法就是ServletConfig这个对象的各个方法。下面贴出源码:

    package org.apache.catalina.core;
    
    import java.util.Enumeration;
    import javax.servlet.ServletConfig;
    import javax.servlet.ServletContext;
    
    public final class StandardWrapperFacade implements ServletConfig
    {
    
    	private ServletConfig config = null;
    
    	private ServletContext context = null;
    
    	public StandardWrapperFacade(StandardWrapper config)
    	{
    		super();
    		this.config = (ServletConfig) config;
    	}
    
    	public String getServletName()
    	{
    		return config.getServletName();
    	}
    
    	public ServletContext getServletContext()
    	{
    		if (context == null)
    		{
    			context = config.getServletContext();
    			if ((context != null) && (context instanceof ApplicationContext))
    				context = ((ApplicationContext) context).getFacade();
    		}
    		return (context);
    	}
    
    	public String getInitParameter(String name)
    	{
    		return config.getInitParameter(name);
    	}
    
    	public Enumeration getInitParameterNames()
    	{
    		return config.getInitParameterNames();
    	}
    
    }
    


    OK,现在言归正传细致的了解下这个接口。
    Servlet在有些情况下可能需要访问Servlet容器或借助Servlet容器访问外部的资源,所以呢,Serlvet引擎需要将表示Servlet容器的对象传递给Servlet。另外,在web.xml文件中为某个Servlet设置的友好名称和初始化参数等信息也需要传递给该Servlet。


    Servlet引擎将代表Servlet容器的对象(ServletContext)和Servlet的配置参数信息一并封装到一个称为ServletConfig的对象中,之后在初始化Servlet实例对象时传递给该Servlet。ServletConfig接口则用于定义ServletConfig对象需要对外提供的方法,以便在Servlet程序中可以调用这些方法来获取有关信息。Servlet引擎调用Servlet的实例对象的init(ServletConfig config)方法将ServletConfig对象传递给Servlet。Servlet.getServletConfig()方法必须返回init(ServletConfig config)方法传递进来的这个ServletConfig对象的引用。


    一定要注意这里封装着2个东西呢:一个是代表Servlet容器的对象,一个是Servlet的配置参数信息。如何区分这2个东西呢?
    1,ServletConfig是servlet访问配置数据的一个对象,由容器创建,每个servlet独享。仅对本servlet有效,一个servlet的ServletConfig 对象不能被另一个 servlet 访问。主要用来读取 web.xml 中配置的Servlet初始信息,不能被其它 Servlet 共享。还可以用于访问 ServletContext。
    2,ServletContext是多个Servlet共享数据的对象。对同一个Web应用中的任何servlet,在任何时间都有效。对应整个Web Application运行环境,可以用来读取 web.xml 中配置的应用初始信息,写日志,共享数据等。ServletContext被所有Servlet共享。可以理解为真正意义上的全局对象。具体的关于这对象,看下面的整理:  

    Servlet引擎为每个WEB应用程序都创建一个对应的ServletContext对象,ServletContext对象被包含在ServletConfig对象中,调用ServletConfig.getServletContext方法可以返回ServletContext对象的引用。由于一个WEB应用程序中的所有Servlet都共享同一个ServletContext对象,所以,ServletContext对象被称之为 application 对象(Web应用程序对象)。  
    功能:获取WEB应用程序的初始化参数,记录日志,application域范围的属性,访问资源文件,获取虚拟路径所映射的本地路径,WEB应用程序之间的访问,ServletContext的其他方法。 


    通过上面的了解,关于一些概念上的理解就不做赘述了,现在想说的就是为什么要玩这2个东西,为什么要去Servlet初始化的配置信息呢?为WEB应用程序设置初始化参数的好处在于不需要修改Servlet源程序,就可以改变一些参数信息。也就是说,防止硬编码,防止后续的维护去改代码。

    OK,现在通过2个例子,现在写一个自己的Servlet实现Servlet接口,实现2个功能。

    1,使用SerlvetConfig来获取Servlet的<init-param>,从而获得一个Servlet的初始化参数

    package linkin;
    
    import java.io.IOException;
    import java.util.Enumeration;
    
    import javax.servlet.Servlet;
    import javax.servlet.ServletConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    
    public class LinkinServlet implements Servlet
    {
    
    	public LinkinServlet()
    	{
    		System.out.println("LinkinServlet...");
    	}
    
    	@Override
    	public void destroy()
    	{
    		System.out.println("destroy...");
    	}
    
    	@Override
    	public ServletConfig getServletConfig()
    	{
    		return null;
    	}
    
    	@Override
    	public String getServletInfo()
    	{
    		return null;
    	}
    
    	@Override
    	public void init(ServletConfig servletConfig) throws ServletException
    	{
    		String name = servletConfig.getInitParameter("name");
    		System.out.println(name);
    		Enumeration<String> enumeration = servletConfig.getInitParameterNames();//name,yourName
    		while (enumeration.hasMoreElements())
    		{
    			String value = (String) enumeration.nextElement();
    			System.out.println(value + ":" + servletConfig.getInitParameter(value));
    		}
    
    	}
    
    	@Override
    	public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException
    	{
    		System.out.println("service...");
    	}
    
    }
    

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    	<servlet>
    		<servlet-name>LinkinServlet</servlet-name>
    		<servlet-class>linkin.LinkinServlet</servlet-class>
    		<init-param>
    			<param-name>name</param-name>
    			<param-value>LinkinPark...</param-value>
    		</init-param>
    		<init-param>
    			<param-name>yourName</param-name>
    			<param-value>NightWish...</param-value>
    		</init-param>
    	</servlet>
    	<servlet-mapping>
    		<servlet-name>LinkinServlet</servlet-name>
    		<url-pattern>/LinkinServlet</url-pattern>
    	</servlet-mapping>
    
    </web-app>
    

     

    这里有一个优化,现在这个ServletConfig对象是init()方法的一个参数,也就是说现在获取Servlet的初始化参数也只能在这个方法内,我要是想在别的方法里面获得相关的初始化参数怎么办呢?

    很简单,扩大ServletConfig对象的作用域就好了。将ServletConfig对象定义成类成员变量,在init里面赋值就OK。GenericServlet其实就是这么做的,只不过它这个ServletConfig对象是用private修饰的。


    2,使用ServletContext来获取<context-param>参数,从而获得整个web应用的初始化参数

    package linkin;
    
    import java.io.IOException;
    import java.util.Enumeration;
    
    import javax.servlet.Servlet;
    import javax.servlet.ServletConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    
    public class LinkinServlet implements Servlet
    {
    
    	public LinkinServlet()
    	{
    		System.out.println("LinkinServlet...");
    	}
    
    	@Override
    	public void destroy()
    	{
    		System.out.println("destroy...");
    	}
    
    	@Override
    	public ServletConfig getServletConfig()
    	{
    		return null;
    	}
    
    	@Override
    	public String getServletInfo()
    	{
    		return null;
    	}
    
    	@Override
    	public void init(ServletConfig servletConfig) throws ServletException
    	{
    		System.out.println(servletConfig.getServletContext().getInitParameter("name"));
    		Enumeration<String> enumeration = servletConfig.getServletContext().getInitParameterNames();
    		while (enumeration.hasMoreElements())
    		{
    			String value = (String) enumeration.nextElement();
    			System.out.println(value + ":" + servletConfig.getServletContext().getInitParameter(value));
    		}
    
    	}
    
    	@Override
    	public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException
    	{
    		System.out.println("service...");
    	}
    
    }
    

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    	
    	<context-param>
    		<param-name>name</param-name>
    		<param-value>LinkinPark...</param-value>
    	</context-param>
    	
    	<context-param>
    		<param-name>name1</param-name>
    		<param-value>LinkinPark1...</param-value>
    	</context-param>
    	
    	<servlet>
    		<servlet-name>LinkinServlet</servlet-name>
    		<servlet-class>linkin.LinkinServlet</servlet-class>
    	</servlet>
    	
    	<servlet-mapping>
    		<servlet-name>LinkinServlet</servlet-name>
    		<url-pattern>/LinkinServlet</url-pattern>
    	</servlet-mapping>
    
    </web-app>
    




  • 相关阅读:
    不务正业系列-浅谈《过气堡垒》,一个RTS玩家的视角
    [LeetCode] 54. Spiral Matrix
    [LeetCode] 40. Combination Sum II
    138. Copy List with Random Pointer
    310. Minimum Height Trees
    4. Median of Two Sorted Arrays
    153. Find Minimum in Rotated Sorted Array
    33. Search in Rotated Sorted Array
    35. Search Insert Position
    278. First Bad Version
  • 原文地址:https://www.cnblogs.com/LinkinPark/p/5233011.html
Copyright © 2020-2023  润新知