目录
一、ServletContext获取真实路径
二、通过ResourceBundle类获取配置文件资源
三、ClassLoader方式读取
四、使用Sping提供的PropertiesLoaderUtils类
五、@Value("${content}")方式
使用request的ServletContext获取文件的绝对路径,通过文件流读出来
优点:1、可以读取任意位置的文件
2、采用文件流读取,所以可以读取不同格式的文件
缺点:不能在servlet外面读取配置文件,必须要有HttpServletRequest,Web环境适用
public class ServletContextDemo {
public void readByServletContext(HttpServletRequest request, HttpServletResponse response) throws IOException {
// 获取文件的绝对地址
String realPath = request.getServletContext().getRealPath("config.properties");
// 使用InputStreamReader,指定编码格式,解决中文乱码
InputStreamReader reader = new InputStreamReader(new FileInputStream(realPath),"GBK");
Properties pros = new Properties();
// 加载流文件
pros.load(reader);
// 通过key获取对应的值
String userName = pros.getProperty("userName");
String chineseName = pros.getProperty("chineseName");
System.out.println(userName+":"+chineseName);
System.out.println("真实地址:"+realPath);
}
}
编写单元测试(使用SpringBoot的方式):
@RunWith(SpringRunner.class)
@SpringBootTest(classes=ServletContextDemo.class)
public class ServletContextDemoTest {
private MockHttpServletRequest request;
private MockHttpServletResponse response;
@Before
public void setUp(){
request = new MockHttpServletRequest();
// 这里设不设置无所谓,主要是使用InputStreamReader时要致指定编码格式
request.setCharacterEncoding("GBK");
response = new MockHttpServletResponse();
}
@Test
public void readByServletContext() throws IOException {
ServletContextDemo demo = new ServletContextDemo();
demo.readByServletContext(request,response);
}
}
测试结果:
优点:1、可以以全限定类名的方式加载资源
2、可以在非web应用里加载资源
缺点:只能加载类下面的资源文件,且只能读取properties文件
使用方式:
1.配置文件放在resource源包下,不用加后缀
PropertiesUtil.getProfileByResourceBundle("config");
2.放在包里面的
PropertiesUtil.getProfileByResourceBundle("com.test.config");
演示代码——获取指定key
public class Demo {
public static void main(String[] args) throws IOException {
// 使用文件名读取,不能带文件后缀
ResourceBundle bundle = ResourceBundle.getBundle("config".trim());
String userName = bundle.getString("userName");
String chineseName = bundle.getString("chineseName");// 乱码
// 解决文件读取乱码
String newName = new String(chineseName.getBytes("ISO-8859-1"), "GBK");
System.out.println(userName+" 转码前:"+chineseName+" 转码后:"+newName);
}
}
测试结果:
演示代码——获取所有key
public class Demo {
public static void main(String[] args) throws IOException {
// 使用文件名读取,不能带文件后缀
ResourceBundle bundle = ResourceBundle.getBundle("config".trim());
// 拿到所有的key
Enumeration keys = bundle.getKeys();
while(keys.hasMoreElements()){// 遍历元素获取值
String key = keys.nextElement();
String value = bundle.getString(key);
System.out.println(key+":"+value);
}
}
}
优点:1、可以在非Web应用中读取配置资源信息,
2、可以读取任意的资源文件信息
缺点:只能加载类classes下面的资源文件
代码示例:
public class Demo {
public static void main(String[] args) throws IOException {
// 类加载器方式,使用相对路径
InputStream stream = Demo.class.getClassLoader().getResourceAsStream("config.properties");
// 解决中文乱码,使用了reader指定编码格式
InputStreamReader reader = new InputStreamReader(stream,"GBK");
Properties pros = new Properties();
pros.load(reader);
// 获取资源
String userName = pros.getProperty("userName");
String chineseName = pros.getProperty("chineseName");
}
}
非常简单的一种方式,引入Spring的相关依赖即可
public class Demo {
public static void main(String[] args) throws IOException {
// 使用全限定名
Properties props = PropertiesLoaderUtils.loadAllProperties("config.properties");
// 获取资源
String userName = props.getProperty("userName");
}
}
这里使用SpringBoot的方式:
1、首先引入SpringBoot的单元测试依赖
org.springframework.boot
spring-boot-starter-test
test
2、需要读取的配置文件demo.properties
content=this_is_a_String
chineseContent=中文字符串
3、使用注解获取配置文件的内容,创建ValueDemo.java
@PropertySource("classpath:demo.properties")
//@Component
@Configuration
public class ValueDemo {
@Value("${content}")// 使用注解获取值
private String content;
@Value("${chineseContent}")
private String chineseContent;
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getChineseContent() {
return chineseContent;
}
public void setChineseContent(String chineseContent) {
this.chineseContent = chineseContent;
}
}
@PropertySource可以指定读取的配置文件,通过@Value注解获取值;通常标识在@Configuration配置类上。
@Value注解可以用在字段和方法上,通常用于从属性配置文件中读取属性值,也可以设置默认值。
@Configuration用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义,初始化Spring容器。
SpringBoot默认使用一个全局的配置文件,配置文件名是固定的;
1.application.properties
2.application.yml(或者是yaml)
注:当读取的配置文件名不是以上命名时,需要使用@PropertySource注解指定读取的配置文件。
// 读取多个配置文件
@PropertySource(value = { "classpath:demo01.properties", "classpath:demo02.properties"})
public class UserSpringConfig {
...
}
@Configuration和@Component的区别:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {
@AliasFor(
annotation = Component.class
)
String value() default "";
}
从定义来看, @Configuration
注解本质上还是 @Component
,因此
或者 @ComponentScan
都能处理@Configuration
注解的类。
4、创建SpringBoot启动类MyApplication.java
@SpringBootApplication
@ComponentScan(basePackages = "springdemo")//自动扫描组件,指定包
public class MyApplication {
public static void main(String[] args) {
Logger logger = LoggerFactory.getLogger(MyApplication.class);
try {
SpringApplication.run(MyApplication.class);
logger.info("springBoot启动成功...");
} catch (Exception e) {
logger.info("SpringBoot启动失败...");
}
}
}
创建一个配置类,在配置类上添加 @ComponentScan 注解。该注解默认会扫描该类所在的包下所有的配置类,相当于之前的
当扫描的文件不在启动类(MyApplication.java)所在的包时,需要在启动类上添加此注解,指明扫描的包。
5、启动单元测试获取结果
@RunWith(SpringRunner.class)
@SpringBootTest(classes= MyApplication.class)// classes属性将某些类纳入测试环境的容器中
public class ValueDemoTest {
@Autowired
private ValueDemo valueDemo;
@Test
public void getContext() throws IOException, InterruptedException {
// 不能直接new(空指针异常),需要使用注解注入@Autowired
// ValueDemo valueDemo = new ValueDemo();
String str = new String(valueDemo.getChineseContent().getBytes("ISO-8859-1"), "GBK");
System.out.println("获取内容:"+valueDemo.getContent()+" 获取中文内容:"+str);
}
}
在@SpringBootTest注解的参数classes中加入参数,表示将某些类纳入测试环境的容器中。上述案例中,使用@SpringBootTest(classes= ValueDemo.class)也可以得到预期结果
测试结果: