servletcontext对象详解

版权声明:本文为博主原创,无版权,未经博主允许可以随意转载,无需注明出处,随意修改或保持可作为原创! https://blog.csdn.net/qq_41517071/article/details/83116310

2018年10月17日19:21:38于易动


 ServletContext对象: 
   特点:上下文环境对象:对应整个web应用的。一个web应用只能有一个ServletContext对象: 
   
   

1:ServletContext的生命周期:

 
   诞生:web部署到服务器。启动服务器,此时上下文环境对象创建。只要 
      是tomcat服务器不关闭,上下文环境对象一直存在。 
      
   销毁:关闭服务器或者是从web服务器上卸载该程序的时候,该对象销毁。 
    
 

 2:ServletContext的获取:主要有三种获取方式如下


 。this.getServletConfig()的getServletContext();
 this.getServletContext();
 request.getServletContext();

代码如下

其中方式1和2本质相同



import java.io.IOException;

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

/*
 * 获得ServletContext对象的方式: 
 * 三种: 
 */
public class ContextServletDemo01 extends HttpServlet {

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

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");
		
		
		// 获得上下文环境对象: 
		
//		方式一: ServletConfig 对象: getServletContext(); ServletContext 
		
		ServletContext context = this.getServletConfig().getServletContext();
		
		
		//方式二: 
		ServletContext context2 = this.getServletContext();
		
		//方式三: 通过request 对象获得: 
		ServletContext context3 = request.getServletContext();
		
		
		System.out.println(context== context2);
		
		// 通过不同种方式 : 获得的ServletContext对象是同一个对象: 
		
		
		System.out.println(context3);// 地址:  org.apache.catalina.core.ApplicationContextFacade@36046a62
		
	}

}

 

上面三种方式获取的servlet的对象都是同一个对象,验证代码如下:
 

import java.io.IOException;

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

/*
 * 判断获得context 对象是否是同一个对象: 
 */
public class ContextServletDemo02 extends HttpServlet {

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

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");
		
		
		ServletContext context = this.getServletConfig().getServletContext();
		System.out.println(context);// 地址: 
	}

}


 
 3:ServletContext的作用:

 
    a:作为域对象的使用:  
       域:本质上是一个map结构:存数据,取数据。  
       域的作用范围:作用范围是:在整个web应用程序当中。 

的servlet中一共有三大域对象,JSP中一共有四大域对象。一般情况下不往域对象中存数据,原因在 

1生命周期太长2作用范围太广(一般是tomcat把数据存在这个域对象当中)
    
    存数据的方法:setAttribute(key,value); 向域对象当中存放的键值对作为域的一个属性而存在。 
    取出来:getAttribute(key); 通过给定的key获得key对应的值。 
                               (1)取出来的值一定是Object类型:需要强转
                               (2)如果指定的属性的名称不存在,将获得一个null。 

扫描二维码关注公众号,回复: 3919220 查看本文章

代码如下(域对象可以被所有的servlet对象共享,所以骚一把一个小服务程序存用另一个来取):

现在浏览器访问运行这个小服务程序,把数据存进去(最后一个是删除操作)

存的时候可以键重复但是会覆盖,查的时候键不存在的话返回null

import java.io.IOException;

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

/*
 * 在 context 域对象当中存放数据: 
 */
public class ContextServletDemo03 extends HttpServlet {

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

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");
		
		//存放数据: 
		ServletContext application = this.getServletContext();
		
		application.setAttribute("username", "俊哥");
		application.setAttribute("username", "俊哥2");
		application.setAttribute("username", "俊哥3");
		application.setAttribute("password", "000000");
		
		application.removeAttribute("password"); 
		
		
	}

}

访问完上面之后再访问下面这个servlet的:

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;

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

/*
 * 从ServletContext 对象当中获得值: 
 */
public class ContextServletDemo04 extends HttpServlet {

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

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");
		
		
		ServletContext context = this.getServletContext();
		
		//域对象的方法: 
		String  name = (String)context.getAttribute("username");
		String  pass = (String)context.getAttribute("password");
		
	    //向客户端浏览器输出内容: 
//		response.getWriter().println(name+" "+pass);
		PrintWriter out = response.getWriter();
		
		
		
		//获得所有的属性的名称: 
		Enumeration<String> names = context.getAttributeNames();
		while(names.hasMoreElements()){
			String n = names.nextElement();
			Object attribute = this.getServletContext().getAttribute(n);
			System.out.println("attName:"+n+"  value:"+attribute);
			System.out.println();
		}
		
		out.println(name);
		out.println("<br/>");
		out.println(pass);
		
		out.close(); 
		
		
		// ======================
		//获得应用级别的初始化参数: 
		
		//获得ServletContext对象: 
//		ServletContext context = request.getServletContext();
		
		String value = context.getInitParameter("encoding");
		System.out.println("context-initParam:"+value);
		
	}

}


            
    移除:removeAttribute(key); 通过指定的密钥,将密钥和密钥对应的值移除。 
    获得所有的密钥的名称:getAttributeNames(); 返回的是一个枚举类型  
    
        
    .b:获得应用级别的初始化参数: 

相对于这种初始化,只能在当前的servlet当中访问

<init-param>
     	<param-name>username</param-name>
     	<param-value>王导演</param-value>
</init-param>

应用级别的初始化参数,可以在当前应用所有的servlet中访问

<!-- 配置一个应用级别的初始化参数:  -->
 <context-param>
 	     <param-name>encoding</param-name>
     	<param-value>gbk</param-value>
 </context-param>
 <context-param>
 	     <param-name>encoding1</param-name>
     	<param-value>utf-8</param-value>
 </context-param>

对应的小服务程序如下:

下面代码中倒数第二行用软编码,比起硬编码好处在于不需要修改源码,直接改配置。利于后期维护和扩展

import java.io.IOException;
import java.util.Enumeration;

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

/*
 * 获得应用级别的初始化参数: 
 */
public class ContextServletDemo05 extends HttpServlet {

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

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		
		
		
		
		//获得应用级别的初始化参数: 
		
		//获得ServletContext对象: 
		ServletContext context = request.getServletContext();
		
		String value = context.getInitParameter("encoding");//gbk
		System.out.println("context-initParam:"+value);
		
		//获得所有的参数的名称: 
		Enumeration<String> names = context.getInitParameterNames();
		while(names.hasMoreElements()){
			String name = names.nextElement();
			String val = context.getInitParameter(name);
			System.out.println(name+" "+val);
		}
		
		
		
		request.setCharacterEncoding(value);
//此处用value 而不写死,直接从web.xml中获取value值。
		response.setContentType("text/html;charset="+value+"");
	}

}


    c:能够获得资源: 
         (1)能够获得资源的真实路径:真实的路径,是文件在tomcat上的真实的存放的位置  在文件上传和文件下载的时候,会使用到 
         .getRealPath(“path” );
         路径:指定路径的时候可以使用/开头。也可以不适应/开头。
         使用/ 开头:相对于当前的网应用。 
         不适用/开头:也是相对于当前的网应用。 
       代码如下:
          其实就这一个方法啦~~~~

import java.io.IOException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/*
 * 获得文件的真实目录: 
 * getRealPath()
 */

public class ServletContextDemo06 extends HttpServlet {

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

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");
		
		
		ServletContext context = this.getServletContext();
		String path = context.getRealPath("a.txt");//相对路径:  相对于当前的web 应用: 
		System.out.println(path);
		
		// C:\Users\Mrzhang\javaEE\javaEE-07\javaEE-01\apache-tomcat-7.0.42\webapps\javaEE-05\a.txt
		
		
		
		String path1 = context.getRealPath("/a.txt");//  / 相对路径: 相对于当前的web应用: 
		System.out.println(path1);
		
		
		//获得web-inf下的文件的真实路径: 
		String path2=  context.getRealPath("/WEB-INF/b.txt");
		System.out.println(path2);
		
		//获得com.yidongxueyuan.web.servlet包下的c.txt文件的真实路径: 
		String path3= context.getRealPath("/WEB-INF/classes/com/yidongxueyuan/web/servlet/c.txt");
		System.out.println(path3);

	}

}


                     
                        
         (2)能够获得指定目录下的所有的资源 
            .getResourcePaths(“path”);能够获得路径下的所有的文件。返回的是一个set集合。 
            案例:getResourcePaths(“/ WEB-INF”); WEB-INF这个目录具有安全性该目录下的内容不会被外界浏览器直接访问                                                                                       的。 
            
            代码如下:

 

package com.yidongxueyuan.web.servlet;

import java.io.IOException;
import java.util.Set;

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

/*
 * 获得web-inf下的所有的资源路径: 
 */
public class ServletContextDemo07 extends HttpServlet {

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

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");
		
		ServletContext context = this.getServletContext();
		Set<String> paths = context.getResourcePaths("/WEB-INF");//能够获得web-inf下的所有的资源: web.xml classes lib a.txt
		System.out.println(paths);
		
		
		
	}

}


         (3)获得资源流:     
方式一:使用ServletContext的对象:      
           A.TXT文件当中的数据:      
           的getResourceAsStream(“路径“); 不管是/开头不是/开头,相当于当前的web应用。 
方式二:使用类的加载器,加载类路径下的资源: 
                     实现步骤: 
           a:获得类的加载器: 
           b:使用类的加载器的:getResourceAsStream(“path”); 可以是/可以不是/:相对于:类路径.classes路径。 
           此方法只能获得类路径下的资源
方式三:使用类的方法获得资源流:
            a:获得类: 
            b:使用类当中的APi方法:getResourceAsStream(“path”);
             /开头:相对路类,类路径: 
             不以/开头:相对于当前文件存在的位置。  

 此方法只能获得类路径下的资源    

综上:如果获得webroot下面的内容,可以使用servletcontext。   

          如果获得类路径下的内容,请使用类的加载器。

import java.io.IOException;
import java.io.InputStream;

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

import org.apache.commons.io.IOUtils;

/*
 * servlet 获得资源流:  a.txt 目录当中的数据。 
 * 自己完成 读取: b.txt 
 * 
 * 使用类的加载器: 读取c.txt 文件当中的数据。 
 * 
 * jar包: 
 * 
 */
public class ServletContextDemo08 extends HttpServlet {

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

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");
		
		//获得a.txt文件当中的数据: 
		ServletContext context = this.getServletContext();
		InputStream in = context.getResourceAsStream("/a.txt");
		/*int len=0; 
		while((len=in.read())!=-1){
			System.out.print((char)len);
		}
		in.close();
		*/
		
		
		String val = IOUtils.toString(in);
		//这个其实是对上面那一段偏底层的代码的封装
	
		System.out.println(val);
		IOUtils.closeQuietly(in);
		
		// /WEB-INF/classes/d.txt;  calsses 类路径: 读取类路径当中的资源, 使用类的加载器读取。  
//		readFile(request,response); 
		readFileByClass(request,response);
		
	}
	
	
	//使用类的加载器  读取d.txt   文件: src 下创建:  部署到tomcat 下的时候, 文件在classes 下。 
	// classes 目录: 类路径: 类路径下的资源通常使用类的在加载器读取。 
	public void readFile(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//获得类的加载器: 
		Class clazz= ServletContextDemo08.class; 
		ClassLoader loader = clazz.getClassLoader();
//		InputStream in = loader.getResourceAsStream("d.txt"); // 相对于:类路径: classes  
		InputStream in = loader.getResourceAsStream("/d.txt"); // 相对于:类路径: classes  
		
		String string = IOUtils.toString(in);
		response.getWriter().println(string);
		IOUtils.closeQuietly(in);
	}
	
	
	//使用Class 获得资源流: //获得a.txt  a.txt没有在类路径下,所以不能被Class 类的方法获得。  
	// class 只能获得类路径下的内容:  d.txt  c.txt 
	public void readFileByClass(HttpServletRequest request, HttpServletResponse response) throws IOException{
		Class clazz= ServletContextDemo08.class; 
//		InputStream in = clazz.getResourceAsStream("/d.txt"); // / : 相对路径: 相对于类路径: classes 
	    InputStream in = clazz.getResourceAsStream("c.txt");// 相对路径: 相对于当前文件所在的位置: 												     
		System.out.println(IOUtils.toString(in));
		IOUtils.closeQuietly(in);
    }
	
	
	

}

 

猜你喜欢

转载自blog.csdn.net/qq_41517071/article/details/83116310