在使用springMVC開發web項目中,數據庫的用戶名,密碼一般都是配置在.properties文件中
然后在通過.xml配置文件引入.properties的變量,例如
在config.properties文件中,配置如下變量,變量值配置在pom.xml的profile標簽下,在此就不再贅述
jdbc.driverClassName=com.mysql.jdbc.Driver jdbc.url=jdbc\:mysql\://${p.jdbc.url}/${p.jdbc.dbname}?useUnicode\=true&characterEncoding\=UTF-8&zeroDateTimeBehavior\=convertToNull&rewriteBatchedStatements\=true jdbc.username=${p.jdbc.username} jdbc.password=${p.jdbc.password}
在applicationContext.xml中,通過如下標簽引入這些變量值
<!-- 將多個配置文件讀取到容器中,交給Spring管理 --> <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>classpath:/properties/*.properties</value> </list> </property> </bean>
這樣對於是明文的帳號,密碼,是沒有問題的。但是如果我在配置文件中的帳號密碼是加密后的,那么如何進行使用配置呢?
解決辦法:
1.首先確定加密解密算法,這種情況下,我們肯定選擇是對稱性加密解密算法,首選DES算法,在這里就拿他舉例
2.完成加密解密算法,這個代碼很簡單,就不贅述,密鑰自己決定,保密即可
public class DESUtils { private static Key key; private static String KEY_STR="mykey"; static{ try { KeyGenerator generator = KeyGenerator.getInstance("DES"); SecureRandom secureRandom=SecureRandom.getInstance("SHA1PRNG"); secureRandom.setSeed(KEY_STR.getBytes()); generator.init(secureRandom); key = generator.generateKey(); generator=null; } catch (Exception e) { throw new RuntimeException(e); } } /** * 對字符串進行加密,返回BASE64的加密字符串 * <功能詳細描述> * @param str * @return * @see [類、類#方法、類#成員] */ public static String getEncryptString(String str){ BASE64Encoder base64Encoder = new BASE64Encoder(); System.out.println(key); try { byte[] strBytes = str.getBytes("UTF-8"); Cipher cipher = Cipher.getInstance("DES"); cipher.init(Cipher.ENCRYPT_MODE, key); byte[] encryptStrBytes = cipher.doFinal(strBytes); return base64Encoder.encode(encryptStrBytes); } catch (Exception e) { throw new RuntimeException(e); } } /** * 對BASE64加密字符串進行解密 * <功能詳細描述> * @param str * @return * @see [類、類#方法、類#成員] */ public static String getDecryptString(String str){ BASE64Decoder base64Decoder = new BASE64Decoder(); try { byte[] strBytes = base64Decoder.decodeBuffer(str); Cipher cipher = Cipher.getInstance("DES"); cipher.init(Cipher.DECRYPT_MODE, key); byte[] encryptStrBytes = cipher.doFinal(strBytes); return new String(encryptStrBytes,"UTF-8"); } catch (Exception e) { throw new RuntimeException(e); } } public static void main(String[] args) { String name ="root"; String password="1234"; String encryname = getEncryptString(name); String encrypassword = getEncryptString(password); System.out.println(encryname); System.out.println(encrypassword); System.out.println(getDecryptString(encryname)); System.out.println(getDecryptString(encrypassword)); } }
3.springMVC中需要實現解密的接口
需要覆蓋convertProperty方法,encryptPropNames存儲的是需要解密的屬性
public class EncryptPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer { private String[] encryptPropNames = {"jdbc.username", "jdbc.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; } } private boolean isEncryptProp(String propertyName) { for (String encryptName : encryptPropNames) { if (encryptName.equals(propertyName)) { return true; } } return false; } }
4.配置這個解密類
用 <bean id="propertyConfigurer" class="org.utils.EncryptPropertyPlaceholderConfigurer" > <property name="locations"> <list> <value>classpath:/properties/*.properties</value> </list> </property> </bean> 替換 <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>classpath:/properties/*.properties</value> </list> </property> </bean>
備注:實際使用中可能會遇到 sun.misc.BASE64Encoder無法使用的問題,下面給出解決辦法
解決方案1(推薦):
只需要在project build path中先移除JRE System Library,再添加庫JRE System Library,重新編譯后就一切正常了。
解決方案2:
Windows -> Preferences -> Java -> Compiler -> Errors/Warnings ->
Deprecated and trstricted API -> Forbidden reference (access rules): -> change to warning