JavaWeb之Servlet中ServletConfig和ServletContext
【声明】
欢迎转载,但请保留文章原始出处→_→
文章来源:http://www.cnblogs.com/smyhvae/p/4140877.html
【正文】
一、ServletConfig:代表当前Servlet在web.xml中的配置信息(用的不多)
- String getServletName() -- 获取当前Servlet在web.xml中配置的名字
- String getInitParameter(String name) -- 获取当前Servlet指定名称的初始化参数的值
- Enumeration getInitParameterNames() -- 获取当前Servlet所有初始化参数的名字组成的枚举
- ServletContext getServletContext() -- 获取代表当前web应用的ServletContext对象
在Servlet的配置文件中,可以使用一个或多个<init-param>标签为servlet配置一些初始化参数。
当servlet配置了初始化参数后,web容器在创建servlet实例对象时,会自动将这些初始化参数封装到ServletConfig对象中,并在调用servlet的init方法时,将ServletConfig对象传递给servlet。进而,程序员通过ServletConfig对象就可以得到当前servlet的初始化参数信息。
这样做的好处是:如果将数据库信息、编码方式等配置信息放在web.xml中,如果以后数据库的用户名、密码改变了,则直接很方便地修改web.xml就行了,避免了直接修改源代码的麻烦。
代码举例:
新建一个名为ServletConfigTest的Servlet,然后在web.xml中的<servlet>标签下,通过<init-param>标签为这个servlet配置两个初始化参数:

<servlet>
<servlet-name>ServletConfigTest</servlet-name>
<servlet-class>com.vae.servlet.ServletConfigTest</servlet-class>
<init-param>
<param-name>name1</param-name>
<param-value>value1</param-value>
</init-param>
<init-param>
<param-name>encode</param-name>
<param-value>utf-8</param-value>
</init-param>
</servlet>

然后在代码中获取上面的两个参数。代码实现如下:

1 package com.vae.servlet;
2
3 import java.io.IOException;
4 import java.util.Enumeration;
5
6 import javax.servlet.ServletConfig;
7 import javax.servlet.ServletException;
8 import javax.servlet.http.HttpServlet;
9 import javax.servlet.http.HttpServletRequest;
10 import javax.servlet.http.HttpServletResponse;
11
12 public class ServletConfigTest extends HttpServlet {
13
14 public void doGet(HttpServletRequest request, HttpServletResponse response)
15 throws ServletException, IOException {
16
17 ServletConfig config = this.getServletConfig(); //拿到init方法中的ServletConfig对象
18
19 // --获取当前Servlet 在web.xml中配置的名称(用的不多)
20 String sName = config.getServletName();
21 System.out.println("当前Servlet 在web.xml中配置的名称:"+sName);
22
23 // --获取当前Servlet中配置的初始化参数(只能获取一个)经常用到
24 // String value = config.getInitParameter("name2");
25 // System.out.println(value);
26
27 // --获取当前Servlet中配置的初始化参数(全部获取)经常用到
28 Enumeration enumration = config.getInitParameterNames();
29 while(enumration.hasMoreElements()){
30 String name = (String) enumration.nextElement();
31 String value = config.getInitParameter(name);
32 System.out.println(name+":"+value);
33 }
34 }
35
36 public void doPost(HttpServletRequest request, HttpServletResponse response)
37 throws ServletException, IOException {
38 doGet(request, response);
39 }
40 }

核心代码是第17行,通过this.getServletConfig()方法拿到init方法中的ServletConfig对象,然后获取配置信息。
运行程序,后台打印日志如下:

二、ServletContext:代表当前web应用(非常重要)
WEB容器在启动时,它会为每个WEB应用程序都创建一个对应的ServletContext对象,它代表当前web应用。
ServletConfig对象中维护了ServletContext对象的引用,开发人员在编写servlet时,可以通过ServletConfig.getServletContext方法获得ServletContext对象。
由于一个WEB应用中的所有Servlet共享同一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象来实现通讯。ServletContext对象通常也被称之为context域对象。
ServletContext的应用:
1.做为域对象可以在整个web应用范围内共享数据。
这里涉及到一些概念:
- 域对象:在一个可以被看见的范围内共享数据用到对象
- 作用范围:整个web应用范围内共享数据
- 生命周期:当服务器启动web应用加载后创建出ServletContext对象后,域产生。当web应用被移除出容器或服务器关闭,随着web应用的销毁域销毁。
代码举例:
ServletTest01.java:

1 package com.vae.servlet;
2
3 import java.io.IOException;
4
5 import javax.servlet.ServletContext;
6 import javax.servlet.ServletException;
7 import javax.servlet.http.HttpServlet;
8 import javax.servlet.http.HttpServletRequest;
9 import javax.servlet.http.HttpServletResponse;
10
11 public class ServletTest01 extends HttpServlet {
12
13 public void doGet(HttpServletRequest request, HttpServletResponse response)
14 throws ServletException, IOException {
15 ServletContext context = this.getServletContext();
16 context.setAttribute("name", "smyhvae");
17 }
18
19 public void doPost(HttpServletRequest request, HttpServletResponse response)
20 throws ServletException, IOException {
21 doGet(request, response);
22 }
23
24 }

ServletTest02.java:

1 package com.vae.servlet;
2
3 import java.io.IOException;
4
5 import javax.servlet.ServletContext;
6 import javax.servlet.ServletException;
7 import javax.servlet.http.HttpServlet;
8 import javax.servlet.http.HttpServletRequest;
9 import javax.servlet.http.HttpServletResponse;
10
11 public class ServletTest02 extends HttpServlet {
12
13 public void doGet(HttpServletRequest request, HttpServletResponse response)
14 throws ServletException, IOException {
15 ServletContext context = this.getServletContext();
16 String myName = (String) context.getAttribute("name");
17 System.out.println(myName);
18 }
19
20 public void doPost(HttpServletRequest request, HttpServletResponse response)
21 throws ServletException, IOException {
22 doGet(request, response);
23 }
24
25 }

我们在ServletTest01中给Context加一个参数name(16行),然后就能在ServletTest02中得到这个参数了(16行)。
context中常用的方法有:
- void setAttribute(String,Object);
- Object getAttribute(String);
- void removeAttribute(String);
2、获取WEB应用的初始化参数
我们在第一段中,通过<init-param>标签为某一个单独的servlet加配置信息,这种配置信息在其他的Servlet中是无法访问到的。可如果我们使用<context-param>标签(与Servlet标签并列)为整个Web应用配置属性的话,那所有的Servlet就都能访问里面的参数了。例如:可以把数据库的配置信息放在这里。
这里涉及到一些概念不要混淆:
- 请求参数 parameter --- 浏览器发送过来的请求中的参数信息
- 初始化参数 initparameter --- 在web.xml中为Servlet或ServletContext配置的初始化时带有的基本参数
- 域属性 attribute --- 四大作用域中存取的键值对
代码举例:
在web.xml中为整个web应用添加初始化参数:用户名、密码。代码位置如下:

然后接下来我们在代码中来获取这些参数。代码如下:
ServletTest03.java:

1 package com.vae.servlet;
2
3 import java.io.IOException;
4 import java.util.Enumeration;
5
6 import javax.servlet.ServletContext;
7 import javax.servlet.ServletException;
8 import javax.servlet.http.HttpServlet;
9 import javax.servlet.http.HttpServletRequest;
10 import javax.servlet.http.HttpServletResponse;
11
12 public class ServletTest03 extends HttpServlet {
13
14 public void doGet(HttpServletRequest request, HttpServletResponse response)
15 throws ServletException, IOException {
16 ServletContext context = this.getServletContext(); // 得到上下文对象
17
18 // 获取单个的Context里面的初始化参数
19 String value1 = context.getInitParameter("username");
20 String value2 = context.getInitParameter("password");
21 System.out.println(value1 + ";" + value2);
22 System.out.println();
23
24 // 一次性获取Context里所有的初始化参数
25 Enumeration enumeration = context.getInitParameterNames();
26 while (enumeration.hasMoreElements()) {
27 String name = (String) enumeration.nextElement();
28 String value = context.getInitParameter(name);
29 System.out.println(name + ";" + value);
30
31 }
32
33 }
34
35 public void doPost(HttpServletRequest request, HttpServletResponse response)
36 throws ServletException, IOException {
37 doGet(request, response);
38 }
39
40 }

上面的代码可以看到,我们可以通过context.getInitParameter()方法获得初始化参数。
运行效果如下:

3、实现Servlet的转发
这里涉及到一些概念要区分:
- 请求重定向:302+Location(两次请求两次响应)
- 请求转发:服务器内不进行资源流转 (一次请求一次响应,来实现资源流转)
注:上方括号中的内容是二者的区别。打个比方,假如你找我借钱,如果是请求重定向的话,那你再去找别人借;如果是请求转发的话,那我去找别人借,然后再借给你。
代码举例:
ServletTest04.java实现请求转发:

1 package com.vae.servlet;
2
3 import java.io.IOException;
4
5 import javax.servlet.RequestDispatcher;
6 import javax.servlet.ServletException;
7 import javax.servlet.http.HttpServlet;
8 import javax.servlet.http.HttpServletRequest;
9 import javax.servlet.http.HttpServletResponse;
10
11 /**
12 * ServletContext实现请求转发
13 */
14 public class ServletTest04 extends HttpServlet {
15
16 public void doGet(HttpServletRequest request, HttpServletResponse response)
17 throws ServletException, IOException {
18 RequestDispatcher dispatcher = this.getServletContext()
19 .getRequestDispatcher("/servlet/ServletTest05");// 参数中写虚拟路径
20 dispatcher.forward(request, response); // 执行完这一行代码后,将会跳到ServletTest05中去执行。
21
22 }
23
24 public void doPost(HttpServletRequest request, HttpServletResponse response)
25 throws ServletException, IOException {
26 doGet(request, response);
27 }
28
29 }

通过19行代码拿到转发器dispatcher,这个转发器指向ServletTest05(参数中写虚拟路径),然后一旦执行完20行代码,就会跳到ServletTest05中去执行。
那么ServletTest05.java的代码如下:

1 package com.vae.servlet;
2
3 import java.io.IOException;
4
5 import javax.servlet.ServletException;
6 import javax.servlet.http.HttpServlet;
7 import javax.servlet.http.HttpServletRequest;
8 import javax.servlet.http.HttpServletResponse;
9
10 /**
11 * ServletContext实现请求转发
12 */
13 public class ServletTest05 extends HttpServlet {
14
15 public void doGet(HttpServletRequest request, HttpServletResponse response)
16 throws ServletException, IOException {
17 response.getWriter().write("10000yuan");
18 }
19
20 public void doPost(HttpServletRequest request, HttpServletResponse response)
21 throws ServletException, IOException {
22 doGet(request, response);
23 }
24
25 }

在浏览器中输入url,效果如下:

4.加载资源文件:
我们先在WebRoot的根目录下新建一个资源文件config.properties,这里有一个问题需要注意:
4.1在Servlet中读取资源文件时:
如果写相对路径或绝对路径,这个路径指的是【当前程序启动的目录下】里面的路径。所以,在web环境下,就是tomcat启动的目录即tomcat/bin,所以找不到资源。效果如下:

如果写硬盘的路径D:\\apache-tomcat-7.0.57\\webapps\\WebTest\\config.properties,可以找到资源,但是只要一换发布环境,这个硬盘路径很可能是错误的,同样不行。
为了解决这样的问题,ServletContext提供了getRealPath方法,在这个方法中传入一个路径,这个方法的底层会在传入的路径的前面拼接当前web应用的硬盘路径,从而得到当前资源的硬盘路径,这种方式即使换了发布环境,方法的底层也能得到正确的web应用的路径从而永远都是正确的资源的路径。代码如下:
this.getServletContext().getRealPath("config.properties")
代码举例:
先在WebRoot的根目录下新建一个文件为config.properties,里面的参数如下:
config.properties:
username=smyhvae
password=007
紧接着,新建一个Servlet,代码如下:
ServletTest06.java:

1 package com.vae.servlet;
2
3 import java.io.FileReader;
4 import java.io.IOException;
5 import java.util.Properties;
6
7 import javax.servlet.ServletException;
8 import javax.servlet.http.HttpServlet;
9 import javax.servlet.http.HttpServletRequest;
10 import javax.servlet.http.HttpServletResponse;
11
12 public class ServletTest06 extends HttpServlet {
13
14 public void doGet(HttpServletRequest request, HttpServletResponse response)
15 throws ServletException, IOException {
16 Properties prop = new Properties(); // 注意导的包是import java.util.Properties;
17 prop.load(new FileReader(this.getServletContext().getRealPath("config.properties")));
18
19 System.out.println(prop.getProperty("username"));
20 System.out.println(prop.getProperty("password"));
21
22 }
23
24 public void doPost(HttpServletRequest request, HttpServletResponse response)
25 throws ServletException, IOException {
26 doGet(request, response);
27 }
28
29 }

核心代码是第17行中的this.getServletContext().getRealPath("config.properties")。
运行效果如下:

4.2 在很多情况下,Servlet中并不会处理大量的逻辑,而是直接调用其他的java代码,那就涉及到了下面的这个问题:
如果在非Servlet环境下要读取资源文件时可以采用类加载器加载文件的方式读取资源:MyService.class.getClassLoader().getResource("../../../config.properties").getPath()
那现在getResource()里面的路径该怎么写呢?只要记住一句话:类加载器从哪里加载类,就从哪里加载资源。这句话有点抽象,我们还是通过代码来看吧:
新建一个Servlet类:
ServletTest07.java:

1 package com.vae.servlet;
2
3 import java.io.IOException;
4
5 import javax.servlet.ServletException;
6 import javax.servlet.http.HttpServlet;
7 import javax.servlet.http.HttpServletRequest;
8 import javax.servlet.http.HttpServletResponse;
9
10 import com.vae.service.MyService;
11
12 public class ServletTest07 extends HttpServlet {
13
14 public void doGet(HttpServletRequest request, HttpServletResponse response)
15 throws ServletException, IOException {
16 MyService service = new MyService();
17 service.method();
18 }
19
20 public void doPost(HttpServletRequest request, HttpServletResponse response)
21 throws ServletException, IOException {
22 doGet(request, response);
23 }
24
25 }

在16、17行代码中,调用了MyService类中的方法。下面来定义MyService类,在里面加载资源文件。
MyService.java:

1 package com.vae.service;
2
3 import java.io.FileNotFoundException;
4 import java.io.FileReader;
5 import java.io.IOException;
6 import java.util.Properties;
7
8 public class MyService {
9
10 public void method() throws FileNotFoundException, IOException{
11 //在没有ServletContext的环境下,如果想要读取资源,可以使用类加载器以加载类的方式加载资源,
12 //这里要注意,类加载器从哪个目录加载类,就从哪个目录加载资源,
13 //所以此处的路径一定要给一个相对于类加载目录的路径
14 Properties prop = new Properties();
15 prop.load(new FileReader(MyService.class.getClassLoader().getResource("config.properties").getPath()));
16 System.out.println(prop.getProperty("username"));
17 System.out.println(prop.getProperty("password"));
18 }
19
20 }

在浏览器输入url后,后台输出如下:

【特别注意】第15行代码中getResource()里面的路径。
类加载器从哪个目录加载类,就从哪个目录加载资源,所以此处的路径一定要给一个相对于类加载目录的路径
我们先看一下这个工程发布到tomcat里面的目录:

进入WEB-INF目录下,是下面的样子:

上图中的classes目录和工程文件的src目录等价。
(1)如果config.properties文件放在src目录下,那路径为:getResource("config.properties")
(2)如果config.properties文件的位置如下:

那路径和上面的代码一样:getResource("com/vae/servlet/config.properties")
(3)如果config.properties文件和MyService.java文件并列,那路径为:getResource("com/vae/service/config.properties")
(4)如果config.properties文件的位置如下:

此时config.properties文件和classes文件并列:

那路径为:getResource("../config.properties") 注:"../"表示上一级目录。
(5)如果config.properties文件放在整个工程文件的根目录下,是无效的,因为此时文件并没有发布到Tomcat。
JavaWeb之Servlet中ServletConfig和ServletContext的更多相关文章
- Java Servlet(三):Servlet中ServletConfig对象和ServletContext对象
本文将记录ServletConfig/ServletContext中提供了哪些方法,及方法的用法. ServletConfig是一个抽象接口,它是由Servlet容器使用,在一个servlet对象初始 ...
- JavaWeb(一)-Servlet中的Config和Context
一.ServletConfig对象 1.1获取一个servletConfig对象 1)通过初始化方法获得一个servletconfig 2)通过继承父类(GenericServlet.)得到一个ser ...
- Servlet、ServletConfig、ServletContext深入学习
1.Servlet学习 1.Servlet生命周期 Servlet 加载—>实例化—>服务—>销毁. init(servletConfig):(经过自己的测试发现会先调用这个而不是i ...
- JavaWeb学习笔记:ServletConfig()和ServletContext()
ServletConfig()和ServletContext() 1.ServletConfig() ServletConfig是一个接口,它由server提供商来实现. ServletConfig封 ...
- servlet中ServletConfig的使用
转自:http://www.zzzj.com/html/20090117/69483.html 前言 相对于ServletContext,ServletConfig是针对特定的Servlet的参数或属 ...
- IT兄弟连 JavaWeb教程 Servlet中定义的变量的作用域类型
在Java语言中,局部变量和实力变量有着不同的作用于,它们的区别如下: 局部变量在一个方法中定义,每当一个线程执行局部变量所在的方法时,在线程的堆栈中就会创建这个局部变量,当线程执行完该方法,局部变量 ...
- JavaWeb(一)Servlet中的ServletConfig与ServletContext
前言 前面我介绍了一下什么是servlet,它的生命周期,执行过程和它的原理.这里我们做一个简单的回顾! 什么是Servlet? servlet 是运行在 Web 服务器中的小型 Java 程序(即: ...
- JavaWeb之Servlet: ServletConfig 与 ServletContext
ServletConfig对象 什么是ServletConfig对象 ServletConfig对象,叫Servlet配置对象.主要用于加载配置文件的初始化参数. 创建时机 ServletConfig ...
- JavaWeb学习总结(四)—ServletConfig和ServletContext
一.ServletConfig 1. ServletConfig介绍: ServletConfig是Servlet中的init()方法的参数类型,服务器会在调用init()方法时传递ServletCo ...
随机推荐
- 启动 nexus, major.minor 51.0 版本不支持
a).Nexus的2.6版本及其以后版本 使用的Java的jdk7. b).Nexus的2.0-2.5版本 使用Java的jdk6的update30版本及其以后的jdk6版本 使用Java的jdk7的 ...
- const变量指针赋值给非const类型的指针运行结果
在c++可以定义一个const变量,然后把变量的值赋给一个非const指针,可以通过指针来改变const变量的值吗?下面的截图给出了答案
- phalApi框架打印SQL语句
http://demo.phalapi.net/?service=User.getBaseInfo&user_id=1&__sql__=1
- Linux Vim替换字符串的一些方法小结
使用Linux环境 进行开发工作的程序猿经常有编辑器之争,是vim牛还是emacs棒.二者都是程序猿的开发神器,不管用好哪一个都会使你的工作事半功倍. 本文重点介绍 Vim的替换字符串方法技巧,这些方 ...
- 使用ntpdate校正linux系统的时间
当Linux服务器的时间不对的时候,可以使用ntpdate工具来校正时间. 安装:yum install ntpdate ntpdate简单用法: # ntpdate ip # ntpdate 210 ...
- UVaLive 4597 Inspection (网络流,最小流)
题意:给出一张有向图,每次你可以从图中的任意一点出发,经过若干条边后停止,然后问你最少走几次可以将图中的每条边都走过至少一次,并且要输出方案,这个转化为网络流的话,就相当于 求一个最小流,并且存在下界 ...
- HDU 1242 Rescue (BFS+优先队列)
题意:X代表卫兵,a代表终点,r代表起始点,.代表路,#代表墙,走过.要花费一秒,走过x要花费2秒,求从起点到终点的最少时间. 析:一看到样例就知道是BFS了吧,很明显是最短路径问题,不过又加了一个条 ...
- 获取iOS 设备上崩溃日志 (Crash Log)的方法
1. iTunes同步获取 大部分用户会使用iTunes软件来管理iPhone,这样同步的Crash日志就会同步到电脑上,我们需要在特定的路径里面查找 Mac OS X:~/Library/Logs/ ...
- (字符串处理)Fang Fang -- hdu -- 5455 (2015 ACM/ICPC Asia Regional Shenyang Online)
链接: http://acm.hdu.edu.cn/showproblem.php?pid=5455 Fang Fang Time Limit: 1500/1000 MS (Java/Others) ...
- HDU6026 Deleting Edges 2017-05-07 19:30 38人阅读 评论(0) 收藏
Deleting Edges Time ...