Java修改文件扩展属性,扩展Spring-实现对外部引用的属性文件的 属性值 进行加密、解密...

当我们在使用Spring进行开发时,我们经常使用占位符引用属性文件的属性值来简化我们的配置及使我们的配置具有更高的灵活性和通用性。

使用这种方式的好处这里就不赘述了,这里要讲的是怎样对此外部属性文件的属性值进行加密、解密。

以下是我们熟悉的配置:jdbc.properties

4f1150b881333f12a311ae9ef34da474.pngdriver=oracle.jdbc.OracleDriver

4f1150b881333f12a311ae9ef34da474.pngdburl=jdbc:oracle:thin:@127.0.0.1:1521:root

4f1150b881333f12a311ae9ef34da474.pngusername=myusr

4f1150b881333f12a311ae9ef34da474.pngpassword=mypassword

applicationContext.xml

4f1150b881333f12a311ae9ef34da474.png        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">4f1150b881333f12a311ae9ef34da474.png4f1150b881333f12a311ae9ef34da474.png4f1150b881333f12a311ae9ef34da474.pngclasspath:jdbc.properties4f1150b881333f12a311ae9ef34da474.png4f1150b881333f12a311ae9ef34da474.png4f1150b881333f12a311ae9ef34da474.png4f1150b881333f12a311ae9ef34da474.png4f1150b881333f12a311ae9ef34da474.png4f1150b881333f12a311ae9ef34da474.png4f1150b881333f12a311ae9ef34da474.png4f1150b881333f12a311ae9ef34da474.png4f1150b881333f12a311ae9ef34da474.png4f1150b881333f12a311ae9ef34da474.png

但当我们配置一个应用的时候,假设打成myapp.jar文件,并不希望将一些配置文件一同打在jar里。

原因是:

有的配置文件要经常改动,例如:由于环境的不同,数据库的连接信息要经常变动,出于安全方面的考虑,密码要经常变换。

一旦配置文件有了修改,就要停止myapp.jar程序,重新打包,再启动myapp.jar,这样无疑对于维护人员来说是很杯具的。

如果我们将配置文件放在myapp.jar外面,那么每次修改配置文件后,只要重启myapp.jar即可。

在配置一些敏感属性的时候(例如密码等),需要对其进行加密。

我们期望看到的jdbc.properties的内容是这样的:

4f1150b881333f12a311ae9ef34da474.pngjdbc.properties

4f1150b881333f12a311ae9ef34da474.pngdriver=oracle.jdbc.OracleDriver

4f1150b881333f12a311ae9ef34da474.pngdburl=jdbc:oracle:thin:@127.0.0.1:1521:root

4f1150b881333f12a311ae9ef34da474.pngusername=myusr

4f1150b881333f12a311ae9ef34da474.pngpassword={3DES}VwHsU01hJOqskgCppbmTXg==

对password属性值进行3DES加密(这里提供了对加密方式的配置),其他的属性值不变。

既达到了安全的效果,又让配置清晰明了。

好了,让我们开始来实现我们的需求吧。

我们从org.springframework.beans.factory.config.PropertyPlaceholderConfigurer这个类入手。

因为之前我们都是用这个类来完成对外部属性文件的引用的。

读了一下这个类的代码,没发现能入手的地方,继续找它的父类。

最终,PropertiesLoaderSupport.java 这个抽象类被我们发现了。其中的loadProperties方法便是我们的入口。

看此方法的注释大意是:加载属性到已给出的实例(翻译的很白痴,汗)。

原来Spring先是生成一个Properties的实例,然后通过这个loadProperties方法,将属性的键值对设置到该实例中。该实例相当于一个篮子,进入方法时,是一个空篮子,待方法返回时,将篮子装满。

以下请看代码,对该段代码进行简单理解:

1fa987a29c6482f53d401256f96355eb.png

ca75c07623e1b494fee67e8f316fc310.gif/** *//**d18c02628675d0a2c816449d98bda930.png     * Load properties into the given instance.

d18c02628675d0a2c816449d98bda930.png     *@paramprops the Properties instance to load into

d18c02628675d0a2c816449d98bda930.png     *@throwsjava.io.IOException in case of I/O errors

d18c02628675d0a2c816449d98bda930.png     *@see#setLocations

8f1ba5b45633e9678d1db480c16cae3f.png*/1fa987a29c6482f53d401256f96355eb.png

ca75c07623e1b494fee67e8f316fc310.gifprotectedvoidloadProperties(Properties props)throwsIOException9b8a8a44dd1c74ae49c20a7cd451974e.png{

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gifif(this.locations!=null)9b8a8a44dd1c74ae49c20a7cd451974e.png{

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.giffor(inti=0; i{//遍历属性文件列表d18c02628675d0a2c816449d98bda930.pngResource location=this.locations[i];//取得一个属性文件句柄97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gifif(logger.isInfoEnabled())9b8a8a44dd1c74ae49c20a7cd451974e.png{

d18c02628675d0a2c816449d98bda930.png                    logger.info("Loading properties file from"+location);

ecedf933ec37d714bd4c2545da43add2.png                }d18c02628675d0a2c816449d98bda930.png                InputStream is=null;

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.giftry9b8a8a44dd1c74ae49c20a7cd451974e.png{

d18c02628675d0a2c816449d98bda930.png                    is=location.getInputStream();

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gifif(location.getFilename().endsWith(XML_FILE_EXTENSION))9b8a8a44dd1c74ae49c20a7cd451974e.png{//判断该属性文件是否为.xml文件d18c02628675d0a2c816449d98bda930.pngthis.propertiesPersister.loadFromXml(props, is);//此处略过,我们只考虑.properties文件ecedf933ec37d714bd4c2545da43add2.png}97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gifelse9b8a8a44dd1c74ae49c20a7cd451974e.png{

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gifif(this.fileEncoding!=null)9b8a8a44dd1c74ae49c20a7cd451974e.png{//加载属性文件 入口1d18c02628675d0a2c816449d98bda930.pngthis.propertiesPersister.load(props,newInputStreamReader(is,this.fileEncoding));

ecedf933ec37d714bd4c2545da43add2.png                        }97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gifelse9b8a8a44dd1c74ae49c20a7cd451974e.png{//加载属性文件 入口2d18c02628675d0a2c816449d98bda930.pngthis.propertiesPersister.load(props, is);

ecedf933ec37d714bd4c2545da43add2.png                        }ecedf933ec37d714bd4c2545da43add2.png                    }ecedf933ec37d714bd4c2545da43add2.png                }97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gifcatch(IOException ex)9b8a8a44dd1c74ae49c20a7cd451974e.png{

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gifif(this.ignoreResourceNotFound)9b8a8a44dd1c74ae49c20a7cd451974e.png{

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gifif(logger.isWarnEnabled())9b8a8a44dd1c74ae49c20a7cd451974e.png{

d18c02628675d0a2c816449d98bda930.png                            logger.warn("Could not load properties from"+location+":"+ex.getMessage());

ecedf933ec37d714bd4c2545da43add2.png                        }ecedf933ec37d714bd4c2545da43add2.png                    }97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gifelse9b8a8a44dd1c74ae49c20a7cd451974e.png{

d18c02628675d0a2c816449d98bda930.pngthrowex;

ecedf933ec37d714bd4c2545da43add2.png                    }ecedf933ec37d714bd4c2545da43add2.png                }97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.giffinally9b8a8a44dd1c74ae49c20a7cd451974e.png{

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gifif(is!=null)9b8a8a44dd1c74ae49c20a7cd451974e.png{

d18c02628675d0a2c816449d98bda930.png                        is.close();

ecedf933ec37d714bd4c2545da43add2.png                    }ecedf933ec37d714bd4c2545da43add2.png                }ecedf933ec37d714bd4c2545da43add2.png            }ecedf933ec37d714bd4c2545da43add2.png        }8f1ba5b45633e9678d1db480c16cae3f.png    }

在入口1、入口2处实现load接口的是org.springframework.util.DefaultPropertiesPersister.java。

分别看一下这两个方法:

1.void load(Properties props, Reader reader) // 入口1分支

2.load(Properties props, InputStream is)     // 入口2分支

先看入口2的方法吧,因为它将是被我们淘汰的方法。原因是它不适合我们改造

以下是入口load方法的实现:

1fa987a29c6482f53d401256f96355eb.png

ca75c07623e1b494fee67e8f316fc310.gifpublicvoidload(Properties props, InputStream is)throwsIOException9b8a8a44dd1c74ae49c20a7cd451974e.png{

d18c02628675d0a2c816449d98bda930.png        props.load(is);//props为java.util.Properties对象。8f1ba5b45633e9678d1db480c16cae3f.png}

props为java.util.Properties对象,所以想要在这里做文章会比较麻烦。

所以我选择入口1.

1fa987a29c6482f53d401256f96355eb.png

ca75c07623e1b494fee67e8f316fc310.gifpublicvoidload(Properties props, Reader reader)throwsIOException9b8a8a44dd1c74ae49c20a7cd451974e.png{

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gifif(loadFromReaderAvailable)9b8a8a44dd1c74ae49c20a7cd451974e.png{

d18c02628675d0a2c816449d98bda930.png//On JDK 1.6+d18c02628675d0a2c816449d98bda930.pngprops.load(reader);//入口3ecedf933ec37d714bd4c2545da43add2.png}97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gifelse9b8a8a44dd1c74ae49c20a7cd451974e.png{

d18c02628675d0a2c816449d98bda930.png//Fall back to manual parsing.d18c02628675d0a2c816449d98bda930.pngdoLoad(props, reader);//入口4ecedf933ec37d714bd4c2545da43add2.png}8f1ba5b45633e9678d1db480c16cae3f.png    }

入口3也被放弃,理由同放弃入口2。

让我们看看入口4的具体实现:

1fa987a29c6482f53d401256f96355eb.png

ca75c07623e1b494fee67e8f316fc310.gifprotectedvoiddoLoad(Properties props, Reader reader)throwsIOException9b8a8a44dd1c74ae49c20a7cd451974e.png{

d18c02628675d0a2c816449d98bda930.png        BufferedReader in=newBufferedReader(reader);

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gifwhile(true)9b8a8a44dd1c74ae49c20a7cd451974e.png{

d18c02628675d0a2c816449d98bda930.png            String line=in.readLine();

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gifif(line==null)9b8a8a44dd1c74ae49c20a7cd451974e.png{

d18c02628675d0a2c816449d98bda930.pngreturn;

ecedf933ec37d714bd4c2545da43add2.png            }d18c02628675d0a2c816449d98bda930.png            line=StringUtils.trimLeadingWhitespace(line);

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gifif(line.length()>0)9b8a8a44dd1c74ae49c20a7cd451974e.png{

d18c02628675d0a2c816449d98bda930.pngcharfirstChar=line.charAt(0);

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gifif(firstChar!='#'&&firstChar!='!')9b8a8a44dd1c74ae49c20a7cd451974e.png{

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gifwhile(endsWithContinuationMarker(line))9b8a8a44dd1c74ae49c20a7cd451974e.png{

d18c02628675d0a2c816449d98bda930.png                        String nextLine=in.readLine();

d18c02628675d0a2c816449d98bda930.png                        line=line.substring(0, line.length()-1);

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gifif(nextLine!=null)9b8a8a44dd1c74ae49c20a7cd451974e.png{

d18c02628675d0a2c816449d98bda930.png                            line+=StringUtils.trimLeadingWhitespace(nextLine);

ecedf933ec37d714bd4c2545da43add2.png                        }ecedf933ec37d714bd4c2545da43add2.png                    }d18c02628675d0a2c816449d98bda930.pngintseparatorIndex=line.indexOf("=");

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gifif(separatorIndex==-1)9b8a8a44dd1c74ae49c20a7cd451974e.png{

d18c02628675d0a2c816449d98bda930.png                        separatorIndex=line.indexOf(":");

ecedf933ec37d714bd4c2545da43add2.png                    }d18c02628675d0a2c816449d98bda930.png//从这里开始便是我们要改造的地方了。

d18c02628675d0a2c816449d98bda930.png//得到value后,我们将value进行解密,然后再装到props这个篮子里。d18c02628675d0a2c816449d98bda930.pngString key=(separatorIndex!=-1?line.substring(0, separatorIndex) : line);

d18c02628675d0a2c816449d98bda930.png                    String value=(separatorIndex!=-1)?line.substring(separatorIndex+1) :"";

d18c02628675d0a2c816449d98bda930.png                    key=StringUtils.trimTrailingWhitespace(key);

d18c02628675d0a2c816449d98bda930.png                    value=StringUtils.trimLeadingWhitespace(value);

d18c02628675d0a2c816449d98bda930.png                    props.put(unescape(key), unescape(value));

ecedf933ec37d714bd4c2545da43add2.png                }ecedf933ec37d714bd4c2545da43add2.png            }ecedf933ec37d714bd4c2545da43add2.png        }8f1ba5b45633e9678d1db480c16cae3f.png    }

知道了要改造的地方,那么我们写代码吧。

新建类:DecryptPropertyPlaceholderConfigurer.java继承PropertyPlaceholderConfigurer.java

新建类:DecryptPropertiesPersister.java继承DefaultPropertiesPersister.java

由于

locations、propertiesPersister、fileEncoding、ignoreResourceNotFound 这些变量在抽象类PropertiesLoaderSupport.java中并没有提供set方法。

所以我们在DecryptPropertyPlaceholderConfigurer.java声明这些成员变量并将父类的覆盖。

其中propertiesPersister变量用我们写的DefaultPropertiesPersister类来实现。

具体代码:

DecryptPropertyPlaceholderConfigurer.java

4f1150b881333f12a311ae9ef34da474.pngimportjava.io.IOException;

4f1150b881333f12a311ae9ef34da474.pngimportjava.io.InputStream;

4f1150b881333f12a311ae9ef34da474.pngimportjava.io.InputStreamReader;

4f1150b881333f12a311ae9ef34da474.pngimportjava.util.Properties;

4f1150b881333f12a311ae9ef34da474.png

4f1150b881333f12a311ae9ef34da474.pngimportorg.springframework.beans.factory.config.PropertyPlaceholderConfigurer;

4f1150b881333f12a311ae9ef34da474.pngimportorg.springframework.core.io.Resource;

4f1150b881333f12a311ae9ef34da474.png

1fa987a29c6482f53d401256f96355eb.png

ca75c07623e1b494fee67e8f316fc310.gifpublicclassDecryptPropertyPlaceholderConfigurerextendsPropertyPlaceholderConfigurer9b8a8a44dd1c74ae49c20a7cd451974e.png{

d18c02628675d0a2c816449d98bda930.pngprivateResource[]                 locations;

d18c02628675d0a2c816449d98bda930.pngprivateDecryptPropertiesPersister propertiesPersister=newDecryptPropertiesPersister();

d18c02628675d0a2c816449d98bda930.pngprivateString                     fileEncoding="utf-8";

d18c02628675d0a2c816449d98bda930.pngprivatebooleanignoreResourceNotFound=false;

d18c02628675d0a2c816449d98bda930.png

d18c02628675d0a2c816449d98bda930.png    @Override

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gifpublicvoidsetLocations(Resource[] locations)9b8a8a44dd1c74ae49c20a7cd451974e.png{

d18c02628675d0a2c816449d98bda930.pngthis.locations=locations;

ecedf933ec37d714bd4c2545da43add2.png    }d18c02628675d0a2c816449d98bda930.png

d18c02628675d0a2c816449d98bda930.png    @Override

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gifpublicvoidsetFileEncoding(String encoding)9b8a8a44dd1c74ae49c20a7cd451974e.png{

d18c02628675d0a2c816449d98bda930.pngthis.fileEncoding=encoding;

ecedf933ec37d714bd4c2545da43add2.png    }d18c02628675d0a2c816449d98bda930.png

d18c02628675d0a2c816449d98bda930.png    @Override

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gifpublicvoidsetIgnoreResourceNotFound(booleanignoreResourceNotFound)9b8a8a44dd1c74ae49c20a7cd451974e.png{

d18c02628675d0a2c816449d98bda930.pngthis.ignoreResourceNotFound=ignoreResourceNotFound;

ecedf933ec37d714bd4c2545da43add2.png    }d18c02628675d0a2c816449d98bda930.png

d18c02628675d0a2c816449d98bda930.png    @Override

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gifpublicvoidloadProperties(Properties props)throwsIOException9b8a8a44dd1c74ae49c20a7cd451974e.png{

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gifif(this.locations!=null)9b8a8a44dd1c74ae49c20a7cd451974e.png{

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.giffor(inti=0; i{

d18c02628675d0a2c816449d98bda930.png                Resource location=this.locations[i];

d18c02628675d0a2c816449d98bda930.png                InputStream is=null;

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.giftry9b8a8a44dd1c74ae49c20a7cd451974e.png{

d18c02628675d0a2c816449d98bda930.png                    is=location.getInputStream();

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gifif(location.getFilename().endsWith(XML_FILE_EXTENSION))9b8a8a44dd1c74ae49c20a7cd451974e.png{

d18c02628675d0a2c816449d98bda930.pngthis.propertiesPersister.loadFromXml(props, is);

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gif                    }else9b8a8a44dd1c74ae49c20a7cd451974e.png{

d18c02628675d0a2c816449d98bda930.pngthis.propertiesPersister.doLoad(props,newInputStreamReader(is,

d18c02628675d0a2c816449d98bda930.pngthis.fileEncoding));

ecedf933ec37d714bd4c2545da43add2.png                    }97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gif                }catch(IOException ex)9b8a8a44dd1c74ae49c20a7cd451974e.png{

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gifif(this.ignoreResourceNotFound)9b8a8a44dd1c74ae49c20a7cd451974e.png{

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gifif(logger.isWarnEnabled())9b8a8a44dd1c74ae49c20a7cd451974e.png{

d18c02628675d0a2c816449d98bda930.png                            logger.warn("Could not load properties from"+location+":"d18c02628675d0a2c816449d98bda930.png+ex.getMessage());

ecedf933ec37d714bd4c2545da43add2.png                        }97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gif                    }else9b8a8a44dd1c74ae49c20a7cd451974e.png{

d18c02628675d0a2c816449d98bda930.pngthrowex;

ecedf933ec37d714bd4c2545da43add2.png                    }97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gif                }finally9b8a8a44dd1c74ae49c20a7cd451974e.png{

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gifif(is!=null)9b8a8a44dd1c74ae49c20a7cd451974e.png{

d18c02628675d0a2c816449d98bda930.png                        is.close();

ecedf933ec37d714bd4c2545da43add2.png                    }ecedf933ec37d714bd4c2545da43add2.png                }ecedf933ec37d714bd4c2545da43add2.png            }ecedf933ec37d714bd4c2545da43add2.png        }ecedf933ec37d714bd4c2545da43add2.png    }8f1ba5b45633e9678d1db480c16cae3f.png}

DecryptPropertiesPersister.java

4f1150b881333f12a311ae9ef34da474.pngimportjava.io.BufferedReader;

4f1150b881333f12a311ae9ef34da474.pngimportjava.io.IOException;

4f1150b881333f12a311ae9ef34da474.pngimportjava.io.Reader;

4f1150b881333f12a311ae9ef34da474.pngimportjava.util.Properties;

4f1150b881333f12a311ae9ef34da474.png

4f1150b881333f12a311ae9ef34da474.pngimportorg.springframework.util.DefaultPropertiesPersister;

4f1150b881333f12a311ae9ef34da474.pngimportorg.springframework.util.StringUtils;

4f1150b881333f12a311ae9ef34da474.png

1fa987a29c6482f53d401256f96355eb.png

ca75c07623e1b494fee67e8f316fc310.gifpublicclassDecryptPropertiesPersisterextendsDefaultPropertiesPersister9b8a8a44dd1c74ae49c20a7cd451974e.png{

d18c02628675d0a2c816449d98bda930.png    @Override

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gifprotectedvoiddoLoad(Properties props, Reader reader)throwsIOException9b8a8a44dd1c74ae49c20a7cd451974e.png{

d18c02628675d0a2c816449d98bda930.png        BufferedReader in=newBufferedReader(reader);

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gifwhile(true)9b8a8a44dd1c74ae49c20a7cd451974e.png{

d18c02628675d0a2c816449d98bda930.png            String line=in.readLine();

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gifif(line==null)9b8a8a44dd1c74ae49c20a7cd451974e.png{

d18c02628675d0a2c816449d98bda930.pngreturn;

ecedf933ec37d714bd4c2545da43add2.png            }d18c02628675d0a2c816449d98bda930.png            line=StringUtils.trimLeadingWhitespace(line);

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gifif(line.length()==0)9b8a8a44dd1c74ae49c20a7cd451974e.png{

d18c02628675d0a2c816449d98bda930.pngcontinue;

ecedf933ec37d714bd4c2545da43add2.png            }d18c02628675d0a2c816449d98bda930.pngcharfirstChar=line.charAt(0);

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gifif(firstChar!='#'&&firstChar!='!')9b8a8a44dd1c74ae49c20a7cd451974e.png{

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gifwhile(endsWithContinuationMarker(line))9b8a8a44dd1c74ae49c20a7cd451974e.png{

d18c02628675d0a2c816449d98bda930.png                    String nextLine=in.readLine();

d18c02628675d0a2c816449d98bda930.png                    line=line.substring(0, line.length()-1);

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gifif(nextLine!=null)9b8a8a44dd1c74ae49c20a7cd451974e.png{

d18c02628675d0a2c816449d98bda930.png                        line+=StringUtils.trimLeadingWhitespace(nextLine);

ecedf933ec37d714bd4c2545da43add2.png                    }ecedf933ec37d714bd4c2545da43add2.png                }d18c02628675d0a2c816449d98bda930.pngintseparatorIndex=line.indexOf("=");

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gifif(separatorIndex==-1)9b8a8a44dd1c74ae49c20a7cd451974e.png{

d18c02628675d0a2c816449d98bda930.png                    separatorIndex=line.indexOf(":");

ecedf933ec37d714bd4c2545da43add2.png                }d18c02628675d0a2c816449d98bda930.png                String key=(separatorIndex!=-1?line.substring(0, separatorIndex) : line);

d18c02628675d0a2c816449d98bda930.png                String value=(separatorIndex!=-1)?line.substring(separatorIndex+1) :"";

d18c02628675d0a2c816449d98bda930.png                key=StringUtils.trimTrailingWhitespace(key);

d18c02628675d0a2c816449d98bda930.png

d18c02628675d0a2c816449d98bda930.png//从这里开始,我们要关注了。d18c02628675d0a2c816449d98bda930.pngvalue=StringUtils.trimLeadingWhitespace(value);

d18c02628675d0a2c816449d98bda930.png//对加密的属性进行3DES解密d18c02628675d0a2c816449d98bda930.pngvalue=decrypt("key", value);//解密方法略 密钥配置的方法略d18c02628675d0a2c816449d98bda930.pngprops.put(unescape(key), unescape(value));

ecedf933ec37d714bd4c2545da43add2.png            }ecedf933ec37d714bd4c2545da43add2.png        }ecedf933ec37d714bd4c2545da43add2.png    }d18c02628675d0a2c816449d98bda930.png    

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gifprivateString decrypt(String key, String str)9b8a8a44dd1c74ae49c20a7cd451974e.png{

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gifif(org.apache.commons.lang.StringUtils.isEmpty(str))9b8a8a44dd1c74ae49c20a7cd451974e.png{

d18c02628675d0a2c816449d98bda930.pngreturn"";

ecedf933ec37d714bd4c2545da43add2.png        }d18c02628675d0a2c816449d98bda930.png//解密方法97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gifif(key.startsWith("{3DES}"))9b8a8a44dd1c74ae49c20a7cd451974e.png{

d18c02628675d0a2c816449d98bda930.png//解密 略ecedf933ec37d714bd4c2545da43add2.png}d18c02628675d0a2c816449d98bda930.pngreturnstr;

ecedf933ec37d714bd4c2545da43add2.png    }8f1ba5b45633e9678d1db480c16cae3f.png}

修改applicationContext.xml文件如下:

4f1150b881333f12a311ae9ef34da474.pngclass="com.jn.spring.DecryptPropertyPlaceholderConfigurer">4f1150b881333f12a311ae9ef34da474.png4f1150b881333f12a311ae9ef34da474.png4f1150b881333f12a311ae9ef34da474.pngclasspath:jdbc.properties4f1150b881333f12a311ae9ef34da474.png4f1150b881333f12a311ae9ef34da474.png4f1150b881333f12a311ae9ef34da474.png4f1150b881333f12a311ae9ef34da474.png4f1150b881333f12a311ae9ef34da474.png4f1150b881333f12a311ae9ef34da474.png4f1150b881333f12a311ae9ef34da474.png4f1150b881333f12a311ae9ef34da474.png4f1150b881333f12a311ae9ef34da474.png4f1150b881333f12a311ae9ef34da474.png

这样就完成了。在Spring进行加载的时候,debug看看是否解析对了就OK了。

注:由于这里主要讲解的是如果通过扩展Spring而实现对外部属性文件的属性值进行加密,而不是介绍加密解密方法,所以关于加密解密方法略。

google一下到处都是。

本文为原创,欢迎转载,转载请注明出处BlogJava。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值