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>
然后在代码中获取上面的两个参数。代码实现如下:
package com.vae.servlet; import java.io.IOException;
import java.util.Enumeration; import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; public class ServletConfigTest extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { ServletConfig config = this.getServletConfig(); //拿到init方法中的ServletConfig对象 // --获取当前Servlet 在web.xml中配置的名称(用的不多)
String sName = config.getServletName();
System.out.println("当前Servlet 在web.xml中配置的名称:"+sName); // --获取当前Servlet中配置的初始化参数(只能获取一个)经常用到
// String value = config.getInitParameter("name2");
// System.out.println(value); // --获取当前Servlet中配置的初始化参数(全部获取)经常用到
Enumeration enumration = config.getInitParameterNames();
while(enumration.hasMoreElements()){
String name = (String) enumration.nextElement();
String value = config.getInitParameter(name);
System.out.println(name+":"+value);
}
} public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
核心代码是第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:
package com.vae.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; public class ServletTest01 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
ServletContext context = this.getServletContext();
context.setAttribute("name", "smyhvae");
} public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
} }
ServletTest02.java:
package com.vae.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; public class ServletTest02 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
ServletContext context = this.getServletContext();
String myName = (String) context.getAttribute("name");
System.out.println(myName);
} public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
} }
我们在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:
package com.vae.servlet; 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 ServletTest03 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
ServletContext context = this.getServletContext(); // 得到上下文对象 // 获取单个的Context里面的初始化参数
String value1 = context.getInitParameter("username");
String value2 = context.getInitParameter("password");
System.out.println(value1 + ";" + value2);
System.out.println(); // 一次性获取Context里所有的初始化参数
Enumeration enumeration = context.getInitParameterNames();
while (enumeration.hasMoreElements()) {
String name = (String) enumeration.nextElement();
String value = context.getInitParameter(name);
System.out.println(name + ";" + value);
} } public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
} }
上面的代码可以看到,我们可以通过context.getInitParameter()方法获得初始化参数。
运行效果如下:

3、实现Servlet的转发
这里涉及到一些概念要区分:
- 请求重定向:302+Location(两次请求两次响应)
- 请求转发:服务器内不进行资源流转 (一次请求一次响应,来实现资源流转)
注:上方括号中的内容是二者的区别。打个比方,假如你找我借钱,如果是请求重定向的话,那你再去找别人借;如果是请求转发的话,那我去找别人借,然后再借给你。
代码举例:
ServletTest04.java实现请求转发:
package com.vae.servlet; import java.io.IOException; import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; /**
* ServletContext实现请求转发
*/
public class ServletTest04 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
RequestDispatcher dispatcher = this.getServletContext()
.getRequestDispatcher("/servlet/ServletTest05");// 参数中写虚拟路径
dispatcher.forward(request, response); // 执行完这一行代码后,将会跳到ServletTest05中去执行。 } public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
} }
通过19行代码拿到转发器dispatcher,这个转发器指向ServletTest05(参数中写虚拟路径),然后一旦执行完20行代码,就会跳到ServletTest05中去执行。
那么ServletTest05.java的代码如下:
package com.vae.servlet; import java.io.IOException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; /**
* ServletContext实现请求转发
*/
public class ServletTest05 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.getWriter().write("10000yuan");
} public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
} }
在浏览器中输入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:
package com.vae.servlet; import java.io.FileReader;
import java.io.IOException;
import java.util.Properties; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; public class ServletTest06 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Properties prop = new Properties(); // 注意导的包是import java.util.Properties;
17 prop.load(new FileReader(this.getServletContext().getRealPath("config.properties")));
System.out.println(prop.getProperty("username"));
System.out.println(prop.getProperty("password")); } public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
} }
核心代码是第17行中的this.getServletContext().getRealPath("config.properties")。
运行效果如下:

4.2 在很多情况下,Servlet中并不会处理大量的逻辑,而是直接调用其他的java代码,那就涉及到了下面的这个问题:
如果在非Servlet环境下要读取资源文件时可以采用类加载器加载文件的方式读取资源:MyService.class.getClassLoader().getResource("../../../config.properties").getPath()
那现在getResource()里面的路径该怎么写呢?只要记住一句话:类加载器从哪里加载类,就从哪里加载资源。这句话有点抽象,我们还是通过代码来看吧:
新建一个Servlet类:
ServletTest07.java:
package com.vae.servlet; import java.io.IOException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import com.vae.service.MyService; public class ServletTest07 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
MyService service = new MyService();
service.method();
} public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
} }
在16、17行代码中,调用了MyService类中的方法。下面来定义MyService类,在里面加载资源文件。
MyService.java:
package com.vae.service; import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Properties; public class MyService { public void method() throws FileNotFoundException, IOException{
//在没有ServletContext的环境下,如果想要读取资源,可以使用类加载器以加载类的方式加载资源,
//这里要注意,类加载器从哪个目录加载类,就从哪个目录加载资源,
//所以此处的路径一定要给一个相对于类加载目录的路径
Properties prop = new Properties();
prop.load(new FileReader(MyService.class.getClassLoader().getResource("config.properties").getPath()));
System.out.println(prop.getProperty("username"));
System.out.println(prop.getProperty("password"));
} }
在浏览器输入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的应用的更多相关文章
- (转)JavaWeb学习之Servlet(四)----ServletConfig获取配置信息、ServletContext的应用
[声明] 欢迎转载,但请保留文章原始出处→_→ 文章来源:http://www.cnblogs.com/smyhvae/p/4140877.html [正文] 一.ServletConfig:代表当前 ...
- Servlet生命周期 Servlet获取配置信息 ServletContext
一.Servlet生命周期 实例化 ——> 初始化 ——> 服务 ——> 销毁 出生:(实例化 然后 初始化)tomcat第一次访问,Servlet就出生(默认情况下) 活着:( ...
- JavaWeb学习之Servlet(二)----Servlet的生命周期、继承结构、修改Servlet模板
[声明] 欢迎转载,但请保留文章原始出处→_→ 文章来源:http://www.cnblogs.com/smyhvae/p/4140466.html 一.http协议回顾: 在上一篇文章中:JavaW ...
- (转)JavaWeb学习之Servlet(二)----Servlet的生命周期、继承结构、修改Servlet模板
[声明] 欢迎转载,但请保留文章原始出处→_→ 文章来源:http://www.cnblogs.com/smyhvae/p/4140466.html 一.http协议回顾: 在上一篇文章中:JavaW ...
- JavaWeb学习——了解Servlet
JavaWeb学习——了解Servlet 摘要:本文主要学习了什么是Servlet,以及如何使用Servlet进行开发. 基础知识 背景 随着互联网技术的发展,基于HTTP和HTML的web应用急速增 ...
- .net core 2.0 mvc 获取配置信息
mvc_core_config *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 ...
- .Net Standard(.Net Core)实现获取配置信息
一.前言 在.Net Framework框架有专门获取webconfig配置的方法供我们使用,但是在.Net Core或者.Net Standard中没有可以直接使用的方法来获取配置文件信息,下面就来 ...
- JavaWeb学习记录(八)——servlet获取配置信息
jdbc.properties内容如下: jdbcUrl=jdbc\:mysql\://localhost\:3306/animaluser=rootpass=root servlet获取资源信息代码 ...
- Servlet学习(二):ServletConfig获取参数;ServletContext应用:请求转发,参数获取,资源读取;类装载器读取文件
转载:http://www.cnblogs.com/xdp-gacl/p/3763559.html 一.ServletConfig讲解 1.1.配置Servlet初始化参数 在Servlet的配置文件 ...
随机推荐
- NYOJ 1058 部分和问题
部分和问题 时间限制:1000 ms | 内存限制:65535 KB 难度:2 描述 给定整数a1.a2........an,判断是否可以从中选出若干数,使它们的和恰好为K. 输入 首先, ...
- 【JavaEE】SSH+Spring Security基础上配置AOP+log4j
Spring Oauth2大多数情况下还是用不到的,主要使用的还是Spring+SpringMVC+Hibernate,有时候加上SpringSecurity,因此,本文及以后的文章的example中 ...
- JS中检测数据类型的几种方式及优缺点
1.typeof 用来检测数据类型的运算符 typeof value 返回值首先是一个字符串,其次里面包含了对应的数据类型,例如:"number"."string&quo ...
- 身份证校验(c++实现)
描述: 我国国标[GB 11643-1999]中规定:公民身份号码是18位特征组合码,由十七位数字本体码和一位数字校验码组成.排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码 ...
- JSON详解 .net
之前json掌握的不好,浪费了好多时间在查找一些json有关的转换问题,我所知道的方法只有把json序列化和反序列化一下,但是太麻烦了我觉得,所以就在找一些更简单又方便使用的方法.也许这个会有用吧,所 ...
- 使用WebMatrix发布网站
使用WebMatrix发布网站 WebMatrix 简介: Microsoft WebMatrix 是微软最新的 Web 开发工具,它包含了构建网站所需要的一切元素.您可以从开源 Web 项目或者内置 ...
- ABAP:区别CALL SCREEN/SET SCREEN/LEAVE TO SCREEN
1,CALL SCREEN XXXX将在Screen调用栈(CALL STACK)上面添加一层调用(进栈),调用XXXX的PBO和PAI,如果XXXX的Next Screen不为0,那么将继续其Nex ...
- 极光推送和百度lbs android sdk一起使用使用proguard 混淆的问题
主要是http得类被混淆后,导致apk定位失败.经过确认,保留apache 的http类就好了 # To enable ProGuard in your project, edit project.p ...
- 我在用的mac软件(1)--终端环境之iTerm2
之前一直有朋友要我分享下在用的mac软件,今天有空就来写一下,可能不止于软件,会有一些配置或者工具,或者叫环境更合适.有些可能一句话带过,有些会详细介绍.也不分类了,想到哪个就写出来.如果已经写的足够 ...
- 基础学习day04---数组的操作
一.数组基本常见操作 1.1.静态初始化 //第一种声明 //第一种声明 int [] arr=new int[5]; //第二种声明 int [] arr1=new int[]{5,3,8,1,9, ...