您的位置:首页 > 编程语言 > Java开发

spring-使用外部属性文件及加密解密文件属性

2018-02-05 23:47 399 查看

s1.使用PropertyPlaceholderConfiguer属性文件

1.jdbc.properties文件

driverClassName=com.mysql.jdbc.Driver
url:jdbc:mysql://localhost:3306/testdb
username=root
password=123


2.xml文件引入属性文件

<!-- 引入配置文件 -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfiguer"
p:location="class:jdbc.preperties"
p:fileEncoding="utf-8"/>

<!-- 使用属性值 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
p:driverClassName="${drverClassName}"
p:url="${url}"
p:username="${userName}"
p:password="${password}"/>


3.PropertyPlaceholderConfigurer其他属性

locations:配置多个配置文件(配置 list 一样)

fileEncoding:编码格式

order:如歌配置多个PropertyPlaceholderConfigurer,通过该属性指定优先顺序

placeholderPrefix:指定占位符前缀,默认为“${”

placeholderSuffix:占位符后缀,默认为“}”

<bean id="propertyPlaceholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:/opt/demo/config/demo-db.properties</value>
<value>classpath:/opt/demo/config/demo-db2.properties</value>
</list>
4000

</property>
</bean>


4.使用”<”context:property-placeholder”>”引入属性文件

//这种方式比较优雅,但如果想要配置日他额外高级属性,如属性加密,使用数据库保存配置信息等,必须使用扩展的PropertyPlaceholderConfigurer类并使用bean配置方式
<context:property-placeholder location="class:jdbc.properties"/>

//引入多个配置文件 逗号分隔
<context:property-placeholder
location="classpath:constants.properties ,
classpath:constants_new.properties"
fileEncoding="utf-8"
/>


5.在基于注解的java类配置中引用属性

@Component
public class Test{
//@Value注解可以为Bean注入一个字面量,也可通过@Value("#{proName}")形式注入值
@Value("com.mysql.jdbc.Driver")
private String driverClassName;

@Value("${url}")
private String url;
}


s2.对属性文件加密

PropertyPlaceholderConfigurer继承自PropertyResourceConfigurer类,后者有几个protected方法用于对属性使用之前对属性列表中的属性进行转换。

void convertProperties(Properties props):属性文件中的所有属性值都封装在props中,覆盖此方法,可以对所有属性值进行转换

String convertProperty(String propertyName,String property Value):在加载属性文件并读取文件属性值时,都会调用此方法,进行转换处理

String convertPropertyValue(String orginalValue):和上一个方法类似,只不过没有传入属性名

1.加密解密工具类(DES对称加密)

package com.gdy.util;

import lombok.extern.log4j.Log4j;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import java.security.Key;
import java.security.SecureRandom;

/**
* des 加解密方法
*/
@Log4j
public class DESUtils {

private static Key key;

/**
* 对str进行DES加密
* @param str  加密的字符串
* @param key_str 加密的秘钥
* @return 加密后的字符串
*/
public static String getEncryptString(String str,String key_str) {
BASE64Encoder base64en = new BASE64Encoder();
try {
setKey2(key_str);
byte[] strBytes = str.getBytes("UTF8");
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] encryptStrBytes = cipher.doFinal(strBytes);
return base64en.encode(encryptStrBytes);
} catch (Exception e) {
log.warn("字符串des加密失败:"+e);
throw new RuntimeException(e);
}
}

/**
* 对str进行DES解密
* @param str 解密的 字符串
* @param key_str 解密的秘钥
* @return 解密后的字符串
*/
public static String getDecryptString(String str,String key_str) {
BASE64Decoder base64De = new BASE64Decoder();
try {
setKey2(key_str);
byte[] strBytes = base64De.decodeBuffer(str);
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] decryptStrBytes = cipher.doFinal(strBytes);
return new String(decryptStrBytes, "UTF8");
} catch (Exception e) {
log.warn("字符串des解密失败:"+e);
throw new RuntimeException(e);
}
}

//Linux 系统下正常运行
public static void setKey2(String strKey) {
try {
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
DESKeySpec keySpec = new DESKeySpec(strKey.getBytes("utf-8"));
key = keyFactory.generateSecret(keySpec);
} catch (Exception e) {
e.printStackTrace();
}finally{

}
}

public static void main(String[] args) {
String key = "111";
String key2 = "111";
System.out.println(getEncryptString(key,key2));
String key3 = "";
// System.out.println(getDecryptString(key3,key2).trim());

}

}


2.加密配置文件 jdbc.properties

driverClassName=com.mysql.jdbc.Driver
url:jdbc:mysql://localhost:3306/testdb
username=WnplV/ietfQ=
password=gJQ9O+q34qk=


3.扩展PropertyPlaceholderConfigurer,覆盖String convertProperty(String propertyName,String propertyValue)方法,对userName和password解密

package com.smart.placeholder;

import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;

public class EncryptPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer {

/**需要解密的属性key*/
private String[] encryptPropNames ={"userName","password"};

@Override
protected String convertProperty(String propertyName, String propertyValue) {
if(isEncryptProp(propertyName)){
String decryptValue = DESUtils.getDecryptString(propertyValue);
System.out.println(decryptValue);
return decryptValue;
}else{
return propertyValue;
}
}

/**
* 判断是否是加密的属性
* @param propertyName
* @return
*/
private boolean isEncryptProp(String propertyName){
for(String encryptPropName:encryptPropNames){
if(encryptPropName.equals(propertyName)){
return true;
}
}
return false;
}
}


4.使用传统的配置方式

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!--1.使用传统的PropertyPlaceholderConfigurer引用属性文件  -->
<!--    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:fileEncoding="utf-8">
<property name="locations">
<list>
<value>classpath:com/smart/placeholder/jdbc.properties</value>
</list>
</property>
</bean>-->

<!--2.使用context命名空间的配置引用属性文件  -->
<!--    <context:property-placeholder
location="classpath:com/smart/placeholder/jdbc.properties" file-encoding="utf8"/>
<bean id="utf8" class="java.lang.String">
<constructor-arg value="utf-8"></constructor-arg>
</bean>-->

<!--3.使用加密版的属性文件  -->
<bean class="com.smart.placeholder.EncryptPropertyPlaceholderConfigurer"
p:location="classpath:com/smart/placeholder/jdbc.properties"
p:fileEncoding="utf-8"/>

<context:component-scan base-package="com.smart.placeholder"/>

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close"
p:driverClassName="${driverClassName}"
p:url="${url}"
p:password="${password}" />

</beans>


s3.属性文件自身的引用

db=testdb
url=jdbc:mysql://localhost:3306/${db}


s4.引用Bean的属性值

有时配置文件的属性不适合放在配置文件中,如集群部署的时候,希望能动态的调整属性,spring提供了#{beanName.beanProp}的方式引用另一个Bean的值

public class SysConfig{

private int sessionTimeOut;
private int maxtabPageNum;
private DataSource dataSource;

//模拟充数据库中查找属性值
public void initFromDB(){
this.sessionTimeOut = 30;
this.maxtabPageNum = 10;
}

public int getSessionTimeOut(){
return sessioinTimeOut;
}

public int getMaxtabPagNum(){
return maxtabPagNum;
}

public void setDataSource(DataSource dataSource){
th
c4cc
is.dataSource = dataSource;
}
}


在xml配置文件中,先将SysConfig定义成一个Bean,通过#{beanName.beanProp}引入属性值

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <context:property-placeholder
location="classpath:com/smart/placeholder/jdbc.properties"/>

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close"
p:driverClassName="${driverClassName}"
p:url="${url}"
p:username="${userName}"
p:password="${password}"/>

<bean id="sysConfig" class="com.smart.beanprop.SysConfig"
init-method="initFromDB"
p:dataSource-ref="dataSource"/>

<bean class="com.smart.beanprop.ApplicationManager"
p:maxTabPageNum="#{sysConfig.maxTabPageNum}"
p:sessionTimeout="#{sysConfig.sessionTimeout}"/>
</beans>


java注解通过@Value(“#{beanName.beanProp}”)引入属性值

public class ApplicationManager(){
@Value("${SysConfig.sessionTimeOut}")
private int sessionTimeOut
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: