+ * /** + * 使用公匙解密 + * + * @param publicKey :公匙解密 + * @param data + */ + private static String publicKeyUnEncrypt(RSAPublicKey publicKey, String data) { + try { + Cipher cipher = Cipher.getInstance(KeyPairsUtils.ALGORITHM); + cipher.init(Cipher.DECRYPT_MODE, publicKey); + //解密时 分段解密 + byte[] bytes = spiltencript(cipher, Cipher.DECRYPT_MODE, data.getBytes(), publicKey.getModulus().bitLength()); + return new String(Base64Utils.decode(bytes)); + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException e) { + e.printStackTrace(); + LOGGER.info("****************使用公匙进行解密时出现异常****************"); + } + return null; + } + + /** + * javax.crypto.IllegalBlockSizeException: Data must not be longer than 128 bytes + * 针对以上 长度大于128位的问题 要采取分段加密的方法 + * + * @param cipher :加密对象 + * @param decryptMode :Cipher.DECRYPT_MODE 或者 Cipher.ENCRYPT_MODE + * @param bytes :加密或者解密的数据 + * @param keyModelsSize :获取到的公匙或者私匙的模数 + * @return :返回分段后组成的数组 + */ + private static byte[] spiltencript(Cipher cipher, int decryptMode, byte[] bytes, int keyModelsSize) { + int maxBlock = 0; //一个阈值 + //根据 decryptMode 判断是 加密还是解密 + if (decryptMode == Cipher.DECRYPT_MODE) { + maxBlock = keyModelsSize / 8; //解密的时候 要求密文长度不超过128字节 + } else { + maxBlock = keyModelsSize / 8 - 11; // 加密的时候 要求不超过117字节 + } + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + try { + int offset = 0; + byte[] buff; + int num = 0; //作为标记 + int length = bytes.length; + while (length > offset) { + if (length - offset > maxBlock) { + buff = cipher.doFinal(bytes, offset, maxBlock); + } else { + buff = cipher.doFinal(bytes, offset, length - offset); + } + outputStream.write(buff, 0, buff.length); + num++; + offset = num * maxBlock; + } + byte[] array = outputStream.toByteArray(); + IOUtils.closeQuietly(outputStream); + return array; + + } catch (IllegalBlockSizeException | BadPaddingException e) { + e.printStackTrace(); + } + return null; + } + + + public static void main(String[] args) { + /* String text = "铭文"; + String keyFromFile = getKeyFromFile(KeyPairsUtils.RSA_FILE_PRIVATE); + LOGGER.debug("私匙:"+keyFromFile); + RSAPrivateKey privateKey = (RSAPrivateKey) encoderByBase64(keyFromFile,8); + //使用私匙进行加密 + System.out.println("加密以后的内容:"+privateEncrypt(privateKey,text));*/ + //相同的铭文 加密以后 不相同 + + //加密以后的内容 + String data = "QbyS/cPCQxu2njNN2oVP8JBluVdrkrlC/rXvP+mhtn/YQfp2JpDzldepdEDpyFG/A/ht5qKg4KzZHuR4aH9sYssCOuAgRg1vfIWLT5zuDz0kfD13k11xiRP5C5BGvANWCVntBXcBzw4eZ0fS/eSk1ExGfpMKMN56tf56/nAO8NM="; + //获取公匙 + String publicKeyFromFile = getKeyFromFile(KeyPairsUtils.RSA_FILE_PUBLIC); + RSAPublicKey publicKey = (RSAPublicKey) encoderByBase64(publicKeyFromFile, 509); + System.out.println("解密以后的内容:" + publicKeyUnEncrypt(publicKey, data)); + + } + + +} diff --git a/test-eureka-web/src/main/resources/static/login.html b/test-eureka-web/src/main/resources/static/login.html new file mode 100644 index 0000000..90fef75 --- /dev/null +++ b/test-eureka-web/src/main/resources/static/login.html @@ -0,0 +1,40 @@ + + + +
+
+ * 注解 解释:
+ * 切面 @Aspect
+ * ======================
+ */
+@Aspect
+@Order(-1) //确保 该切面执行的顺序比 事务要早
+@Component
+public class ChangeDataSourceAop {
+
+
+ private Stack
* ======================
*/
public class MyAbstractroutintDataSource extends AbstractRoutingDataSource {
- private int readDataSourceSize ;
+ private int readDataSourceSize;
+ private AtomicInteger count = new AtomicInteger();
public MyAbstractroutintDataSource(int readDataSourceSize) {
this.readDataSourceSize = readDataSourceSize;
@@ -26,12 +31,18 @@ public MyAbstractroutintDataSource(int readDataSourceSize) {
@Override
protected Object determineCurrentLookupKey() {
- //从当前的线程中 获取 LookUpKey
+ //从当前的线程中 获取 LookUpKey
String lookUpKey = DataSourceLookUpKeyThreadLocal.getDataSourceLookUpKey();
- //当前环境中 读的
-
+ //当前环境中 读库的数量 不为0 并且 LookUpKey 不为空
+ //如果当前线程中 保存的是从库或者读库 数据源会有多个 那个轮询的方式 选择对应的数据源
+ if (readDataSourceSize > 0 && StringUtils.isNotBlank(lookUpKey) && lookUpKey.equalsIgnoreCase(DatasourceEnum.READ.name())) {
+ int num = count.getAndAdd(1);
+ int i = num % readDataSourceSize;
+ return new Integer(i);
+ }
- return null;
+ // 返回 主库huozhe或者 写的数据源
+ return DatasourceEnum.WRITE.name();
}
}
diff --git a/test-eureka-client/src/main/java/com/test/eureka/web/client/config/MyBatisConfigration.java b/test-eureka-client/src/main/java/com/test/eureka/web/client/config/MyBatisConfigration.java
index 86a452b..3a1ace5 100644
--- a/test-eureka-client/src/main/java/com/test/eureka/web/client/config/MyBatisConfigration.java
+++ b/test-eureka-client/src/main/java/com/test/eureka/web/client/config/MyBatisConfigration.java
@@ -1,6 +1,6 @@
package com.test.eureka.web.client.config;
-import com.alibaba.druid.pool.DruidDataSource;
+import org.apache.commons.collections.CollectionUtils;
import org.apache.ibatis.mapping.DatabaseIdProvider;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
@@ -11,20 +11,19 @@
import org.mybatis.spring.boot.autoconfigure.SpringBootVFS;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
-import org.springframework.boot.devtools.autoconfigure.DevToolsDataSourceAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ResourceLoader;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
-import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import javax.sql.DataSource;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
/**
* ======================
@@ -39,14 +38,14 @@ public class MyBatisConfigration extends MybatisAutoConfiguration {
@Autowired
- private MybatisProperties properties ;
+ private MybatisProperties properties;
@Autowired
- private ResourceLoader resourceLoader ;
+ private ResourceLoader resourceLoader;
@Resource(name = "dataSource")
- private DataSource writeDataSource ;
+ private DataSource writeDataSource;
@Resource(name = "readDataSource")
private List