tomcat

配置 JNDI

确保 tomcat 下有相关jar

tomcat 目录下/conf/context.xml中增加配置

1
2
3
4
5
6
7
8
9
10
11
12
<Resource name = "jdbc/mysql"
auth = "Container"
type = "javax.sql.DataSource"
driverClassName = "com.mysql.jdbc.Driver"
url = "jdbc:mysql://localhost:3306/app"
factory="com.li.jndi.EncryptedDataSourceFactory"
username = "root"
password = "xxxx"
maxActive = "200"
maxIdle = "30"
maxWait = "5000"
/>

确保 tomcat 目录下有driverjar

/lib/mysql-connector-java-8.0.16.jar

factory标签是指定BasicDataSourceFactory工厂类,可以用来解密password密文。需要如下依赖

1
2
3
4
5
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.2.2</version>
</dependency>

EncryptedDataSourceFactory代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
package com.li.jndi;

import org.apache.commons.dbcp.BasicDataSourceFactory;
import org.apache.naming.ResourceRef;

import javax.naming.*;
import java.util.Enumeration;
import java.util.Hashtable;

public class EncryptedDataSourceFactory extends BasicDataSourceFactory {

@Override
public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable environment) throws Exception {
if (obj instanceof ResourceRef) {
decode("password", (Reference) obj);
}
return super.getObjectInstance(obj, name, nameCtx, environment);
}

private String decode(String old) throws Exception {
return "root";
}

private int find(String addrType, Reference ref) throws Exception {
Enumeration enu = ref.getAll();
for (int i = 0; enu.hasMoreElements(); i++) {
RefAddr addr = (RefAddr) enu.nextElement();
if (addr.getType().compareTo(addrType) == 0) {
return i;
}
}
throw new Exception("The \"" + addrType
+ "\" name/value pair was not found"
+ " in the Reference object. The reference Object is" + " "
+ ref.toString());
}

private void decode(String refType, Reference ref) throws Exception {
int index = find(refType, ref);
RefAddr refAddr = ref.get(index);
Object content = refAddr.getContent();
if (content instanceof String) {
ref.remove(index);
ref.add(index, new StringRefAddr(refType, decode((String) content)));
}
}

}

使用jndi服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.li.jndi;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

public class DBConn {

private static DataSource dataSource;

static {
try {
Context context = new InitialContext();
dataSource = (DataSource)context.lookup("java:comp/env/jdbc/mysql");
}
catch (NamingException e) {
e.printStackTrace();
}
}
}

tomcat 类加载顺序

tomcat 优先加载应用内的 jar 包,然后在加载共享 lib 目录下的 jar 包