├── settings.gradle
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── README.md
├── src
├── main
│ ├── resources
│ │ ├── mybatis
│ │ │ ├── mybatis-config.xml
│ │ │ └── mapper
│ │ │ │ └── TUserMapper.xml
│ │ ├── application.properties
│ │ ├── jdbc.properties
│ │ └── log4j2.xml
│ └── java
│ │ └── git
│ │ └── yampery
│ │ └── cryptic
│ │ ├── cryptic
│ │ ├── ADESInterface.java
│ │ ├── CryptPojo.java
│ │ ├── ADESUtils.java
│ │ └── CryptPojoUtils.java
│ │ ├── Application.java
│ │ ├── dao
│ │ └── UserDao.java
│ │ ├── annotation
│ │ ├── DecryptField.java
│ │ └── EncryptField.java
│ │ ├── service
│ │ ├── UserService.java
│ │ └── impl
│ │ │ └── UserServiceImpl.java
│ │ ├── pojo
│ │ └── TUser.java
│ │ ├── common
│ │ ├── SysException.java
│ │ └── QueryParams.java
│ │ ├── config
│ │ └── DruidConfig.java
│ │ └── interceptor
│ │ └── DBInterceptor.java
└── test
│ └── java
│ └── git
│ └── yampery
│ └── cryptic
│ └── ApplicationTests.java
├── .gitignore
├── database
└── CRYPTIC_DATA.sql
├── gradlew.bat
└── gradlew
/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'cryptic-data'
2 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yampery/cryptic-data/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Tue Feb 06 12:27:20 CET 2018
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.5.1-bin.zip
7 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # cryptic-data
2 | 基于Spring-mybatis项目,以AES的方式对指定数据(注解)进行加解密
3 | # 说明
4 | - 更改jdbc连接 jdbc.properties
5 | - 生成128位秘钥
6 | - 运行测试文件
7 |
8 | **该项目使用springboot+mybatis+gradle构建,对于传统spring+maven项目,只需要更改配置即可**
9 | **具体问题访问博客: https://blog.csdn.net/wizard_rp/article/details/79821671**
10 |
--------------------------------------------------------------------------------
/src/main/resources/mybatis/mybatis-config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/main/java/git/yampery/cryptic/cryptic/ADESInterface.java:
--------------------------------------------------------------------------------
1 | package git.yampery.cryptic.cryptic;
2 |
3 | /**
4 | * @decription ADESInterface
5 | *
自加解密接口
6 | * @author Yampery
7 | * @date 2017/10/24 13:15
8 | */
9 | public interface ADESInterface {
10 | public T encryptSelf();
11 | public T decryptSelf();
12 | }
13 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .gradle
2 | /build/
3 | !gradle/wrapper/gradle-wrapper.jar
4 |
5 | ### STS ###
6 | .apt_generated
7 | .classpath
8 | .factorypath
9 | .project
10 | .settings
11 | .springBeans
12 | .sts4-cache
13 |
14 | ### IntelliJ IDEA ###
15 | .idea
16 | *.iws
17 | *.iml
18 | *.ipr
19 |
20 | ### NetBeans ###
21 | nbproject/private/
22 | build/
23 | nbbuild/
24 | dist/
25 | nbdist/
26 | .nb-gradle/
--------------------------------------------------------------------------------
/src/main/java/git/yampery/cryptic/Application.java:
--------------------------------------------------------------------------------
1 | package git.yampery.cryptic;
2 |
3 | import org.mybatis.spring.annotation.MapperScan;
4 | import org.springframework.boot.SpringApplication;
5 | import org.springframework.boot.autoconfigure.SpringBootApplication;
6 |
7 | @SpringBootApplication
8 | @MapperScan("git.yampery.cryptic.dao")
9 | public class Application {
10 |
11 | public static void main(String[] args) {
12 | SpringApplication.run(Application.class, args);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/git/yampery/cryptic/dao/UserDao.java:
--------------------------------------------------------------------------------
1 | package git.yampery.cryptic.dao;
2 |
3 | import git.yampery.cryptic.pojo.TUser;
4 |
5 | import java.util.List;
6 | import java.util.Map;
7 |
8 | /**
9 | * @decription UserDao
10 | * 用户数据库表访问
11 | * @author Yampery
12 | * @date 2018/4/4 13:54
13 | */
14 | public interface UserDao {
15 |
16 | int insert(TUser record);
17 |
18 | int insertSelective(TUser record);
19 |
20 | List queryList(Map map);
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/git/yampery/cryptic/annotation/DecryptField.java:
--------------------------------------------------------------------------------
1 | package git.yampery.cryptic.annotation;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * @decription DecryptField
10 | * 字段解密注解
11 | * @author Yampery
12 | * @date 2017/10/24 13:05
13 | */
14 | @Target(ElementType.FIELD)
15 | @Retention(RetentionPolicy.RUNTIME)
16 | public @interface DecryptField {
17 | String value() default "";
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/git/yampery/cryptic/annotation/EncryptField.java:
--------------------------------------------------------------------------------
1 | package git.yampery.cryptic.annotation;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * @decription EncryptField
10 | * 字段加密注解
11 | * @author Yampery
12 | * @date 2017/10/24 13:01
13 | */
14 | @Target(ElementType.FIELD)
15 | @Retention(RetentionPolicy.RUNTIME)
16 | public @interface EncryptField {
17 | String value() default "";
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/git/yampery/cryptic/service/UserService.java:
--------------------------------------------------------------------------------
1 | package git.yampery.cryptic.service;
2 |
3 | import git.yampery.cryptic.pojo.TUser;
4 |
5 | import java.util.List;
6 | import java.util.Map;
7 |
8 | /**
9 | * @decription UserService
10 | * 用户服务
11 | * @author Yampery
12 | * @date 2018/4/4 14:48
13 | */
14 | public interface UserService {
15 |
16 | /**
17 | * 查询
18 | * @param map
19 | */
20 | List queryList(Map map);
21 |
22 | /**
23 | * 写入数据
24 | * @param user
25 | */
26 | void insert(TUser user);
27 | }
28 |
--------------------------------------------------------------------------------
/database/CRYPTIC_DATA.sql:
--------------------------------------------------------------------------------
1 | /*
2 | Navicat MySQL Data Transfer
3 |
4 | Source Server : docker_mysql
5 | Source Server Version : 50720
6 | Source Host : localhost:3306
7 | Source Database : CRYPTIC_DATA
8 |
9 | Target Server Type : MYSQL
10 | Target Server Version : 50720
11 | File Encoding : 65001
12 |
13 | Date: 2018-04-04 13:50:51
14 | */
15 |
16 | SET FOREIGN_KEY_CHECKS=0;
17 |
18 | -- ----------------------------
19 | -- Table structure for T_USER
20 | -- ----------------------------
21 | DROP TABLE IF EXISTS `T_USER`;
22 | CREATE TABLE `T_USER` (
23 | `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id自增主键',
24 | `user_name` varchar(20) DEFAULT NULL COMMENT '用户名',
25 | `phone` varchar(32) DEFAULT NULL,
26 | PRIMARY KEY (`id`)
27 | ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
28 |
--------------------------------------------------------------------------------
/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | ################################ 系统配置 #############################
2 | # 设置内置端口
3 | # server.port =8090
4 | # 配置协议为http(如果网站使用了证书,删除掉配置即可)
5 | # server.tomcat.protocol-header-https-value =http
6 |
7 | # log4j2
8 | # log4j.config-locations =classpath:log4j2.xml
9 |
10 | # Mybatis
11 | mybatis.config-location =classpath:mybatis/mybatis-config.xml
12 | mybatis.mapper-locations =classpath:mybatis/mapper/*.xml
13 | mybatis.type-aliases-package =git.yampery.cryptic.pojo
14 |
15 | # 开启debug模式可以在控制台查看springboot加载流程
16 | # debug =true
17 |
18 | # 密盐(使用工具ADESUtils生成)
19 | sys.aes.salt =4BB90812C2B9B0882A6FA7C203E4717F
20 | # 加解密开关(1:开启加解密;0:关闭加解密)
21 | sys.aes.switch =1
--------------------------------------------------------------------------------
/src/main/resources/jdbc.properties:
--------------------------------------------------------------------------------
1 | jdbc.driver =com.mysql.cj.jdbc.Driver
2 | jdbc.url =jdbc:mysql://localhost:3306/CRYPTIC_DATA?allowMultiQueries=true&useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
3 | jdbc.username =root
4 | jdbc.password =1
5 | #定义初始连接数
6 | jdbc.pool.initialSize =10
7 | #定义最大连接数
8 | jdbc.pool.maxActive =100
9 | #定义最大空闲
10 | jdbc.pool.maxIdle =0
11 | #定义最小空闲
12 | jdbc.pool.minIdle =10
13 | #定义最长等待时间
14 | jdbc.pool.maxWait =60000
15 | #连接检测
16 | jdbc.pool.timeBetweenEvictionRunsMillis =60000
17 | jdbc.pool.minEvictableIdleTimeMillis =300000
18 | jdbc.pool.maxPoolPreparedStatementPerConnectionSize =100
--------------------------------------------------------------------------------
/src/main/java/git/yampery/cryptic/service/impl/UserServiceImpl.java:
--------------------------------------------------------------------------------
1 | package git.yampery.cryptic.service.impl;
2 |
3 | import git.yampery.cryptic.common.SysException;
4 | import git.yampery.cryptic.dao.UserDao;
5 | import git.yampery.cryptic.pojo.TUser;
6 | import git.yampery.cryptic.service.UserService;
7 | import org.springframework.stereotype.Service;
8 |
9 | import javax.annotation.Resource;
10 | import java.util.List;
11 | import java.util.Map;
12 |
13 | /**
14 | * @decription UserServiceImpl
15 | *
16 | * @author Yampery
17 | * @date 2018/4/4 14:50
18 | */
19 | @Service
20 | public class UserServiceImpl implements UserService {
21 |
22 | @Resource private UserDao userDao;
23 |
24 | @Override
25 | public List queryList(Map map) {
26 | try {
27 | return userDao.queryList(map);
28 | } catch (Exception e) {
29 | throw new SysException("获取用户列表出错", e);
30 | }
31 | }
32 |
33 | @Override
34 | public void insert(TUser user) {
35 | try {
36 | userDao.insert(user);
37 | } catch (Exception e) {
38 | throw new SysException("写入用户列表出错", e);
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/git/yampery/cryptic/pojo/TUser.java:
--------------------------------------------------------------------------------
1 | package git.yampery.cryptic.pojo;
2 |
3 | import git.yampery.cryptic.annotation.DecryptField;
4 | import git.yampery.cryptic.annotation.EncryptField;
5 |
6 | /**
7 | * @decription TUser
8 | * 用户pojo
9 | * @author Yampery
10 | * @date 2018/4/4 14:00
11 | */
12 | public class TUser {
13 | private Integer id;
14 |
15 | private String userName;
16 |
17 | @EncryptField
18 | @DecryptField
19 | private String phone;
20 |
21 | public Integer getId() {
22 | return id;
23 | }
24 |
25 | public void setId(Integer id) {
26 | this.id = id;
27 | }
28 |
29 | public String getUserName() {
30 | return userName;
31 | }
32 |
33 | public void setUserName(String userName) {
34 | this.userName = userName;
35 | }
36 |
37 | public String getPhone() {
38 | return phone;
39 | }
40 |
41 | public void setPhone(String phone) {
42 | this.phone = phone;
43 | }
44 |
45 | @Override
46 | public String toString() {
47 | return "TUser{" +
48 | "userName='" + userName + '\'' +
49 | ", phone='" + phone + '\'' +
50 | '}';
51 | }
52 | }
--------------------------------------------------------------------------------
/src/main/java/git/yampery/cryptic/common/SysException.java:
--------------------------------------------------------------------------------
1 | package git.yampery.cryptic.common;
2 |
3 | /**
4 | * @decription SysException
5 | * 系统自定义异常
6 | * 说明:在可能存在运行时异常的地方进行捕获,获取异常信息,向上层抛出此异常
7 | * 在表现层进行捕获,并使用logger.error()打印日志
8 | *
异常码说明:{ 如果有自定义code,在此注明 }
9 | * 500:服务器内部错误,可能是系统自行抛出被捕获,也可能是明确的个人抛出的系统异常
10 | *
11 | *
12 | * @author Yampery
13 | * @date 2018/4/4 17:15
14 | */
15 | public class SysException extends RuntimeException {
16 |
17 | private static final long serialVersionUID = 1L;
18 |
19 | private String msg;
20 | private int code = 500;
21 |
22 | public SysException(String msg) {
23 | super(msg);
24 | this.msg = msg;
25 | }
26 |
27 | public SysException(String msg, Throwable e) {
28 | super(msg, e);
29 | this.msg = msg;
30 | }
31 |
32 | public SysException(String msg, int code) {
33 | super(msg);
34 | this.msg = msg;
35 | this.code = code;
36 | }
37 |
38 | public SysException(String msg, int code, Throwable e) {
39 | super(msg, e);
40 | this.msg = msg;
41 | this.code = code;
42 | }
43 |
44 | public String getMsg() {
45 | return msg;
46 | }
47 |
48 | public void setMsg(String msg) {
49 | this.msg = msg;
50 | }
51 |
52 | public int getCode() {
53 | return code;
54 | }
55 |
56 | public void setCode(int code) {
57 | this.code = code;
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/main/java/git/yampery/cryptic/common/QueryParams.java:
--------------------------------------------------------------------------------
1 | package git.yampery.cryptic.common;
2 |
3 | import git.yampery.cryptic.cryptic.ADESUtils;
4 |
5 | import java.util.LinkedHashMap;
6 | import java.util.Map;
7 |
8 | /**
9 | * @decription QueryParams
10 | * 封装查询参数
11 | * @author Yampery
12 | * @date 2018/4/4 14:23
13 | */
14 | public class QueryParams extends LinkedHashMap{
15 |
16 | private static final long serialVersionUID = 1L;
17 | private static final String REGIX_PHONE = "^((0\\d{2,3}\\d{7,8})|(1[35784]\\d{9}))$";
18 | //当前页码
19 | private int page;
20 | //每页条数
21 | private int limit;
22 |
23 | public QueryParams(Map params){
24 | // 如果参数是手机号,则加密后查询
25 | if (params.containsKey("phone")) {
26 | String number = params.get("phone").toString();
27 | if (number.matches(REGIX_PHONE)) {
28 | params.put("phone", ADESUtils.getInstance().encrypt(number));
29 | }
30 | }
31 | this.putAll(params);
32 |
33 | //分页参数
34 | if (null != params.get("page")) {
35 | this.page = Integer.parseInt(params.get("page").toString());
36 | this.put("page", page);
37 | }
38 | if (null != params.get("limit")) {
39 | this.limit = Integer.parseInt(params.get("limit").toString());
40 | this.put("limit", limit);
41 | this.put("offset", (page - 1) * limit);
42 | }
43 | }
44 |
45 |
46 | public int getPage() {
47 | return page;
48 | }
49 |
50 | public void setPage(int page) {
51 | this.page = page;
52 | }
53 |
54 | public int getLimit() {
55 | return limit;
56 | }
57 |
58 | public void setLimit(int limit) {
59 | this.limit = limit;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/main/resources/mybatis/mapper/TUserMapper.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | insert into T_USER (user_name, phone
11 | )
12 | values (#{userName,jdbcType=VARCHAR}, #{phone,jdbcType=VARCHAR}
13 | )
14 |
15 |
16 | insert into T_USER
17 |
18 |
19 | id,
20 |
21 |
22 | user_name,
23 |
24 |
25 | phone,
26 |
27 |
28 |
29 |
30 | #{id,jdbcType=INTEGER},
31 |
32 |
33 | #{userName,jdbcType=VARCHAR},
34 |
35 |
36 | #{phone,jdbcType=VARCHAR},
37 |
38 |
39 |
40 |
54 |
--------------------------------------------------------------------------------
/src/test/java/git/yampery/cryptic/ApplicationTests.java:
--------------------------------------------------------------------------------
1 | package git.yampery.cryptic;
2 |
3 | import git.yampery.cryptic.common.QueryParams;
4 | import git.yampery.cryptic.common.SysException;
5 | import git.yampery.cryptic.cryptic.ADESUtils;
6 | import git.yampery.cryptic.pojo.TUser;
7 | import git.yampery.cryptic.service.UserService;
8 | import org.junit.Test;
9 | import org.junit.runner.RunWith;
10 | import org.slf4j.Logger;
11 | import org.slf4j.LoggerFactory;
12 | import org.springframework.boot.test.context.SpringBootTest;
13 | import org.springframework.test.context.junit4.SpringRunner;
14 |
15 | import javax.annotation.Resource;
16 | import java.util.HashMap;
17 | import java.util.List;
18 | import java.util.Map;
19 |
20 | @RunWith(SpringRunner.class)
21 | @SpringBootTest
22 | public class ApplicationTests {
23 |
24 | @Resource private UserService userService;
25 | private static final Logger logger = LoggerFactory.getLogger(ApplicationTests.class);
26 |
27 | @Test
28 | public void contextLoads() {
29 | }
30 |
31 | /**
32 | * 生成AES加密秘钥
33 | */
34 | @Test
35 | public void testGeneratorSalt() throws Exception {
36 | String salt = ADESUtils.generateAESKey();
37 | System.out.println("秘钥: " + salt);
38 | }
39 |
40 | /**
41 | * 测试写入数据
42 | */
43 | @Test
44 | public void testInsert() {
45 | TUser user = new TUser();
46 | user.setPhone("18700000000");
47 | user.setUserName("yampery");
48 | try {
49 | userService.insert(user);
50 | } catch (SysException e) {
51 | System.err.println("insert user error");
52 | e.printStackTrace();
53 | }
54 | }
55 |
56 | /**
57 | * 测试选择数据
58 | */
59 | @Test
60 | public void testSelect() {
61 | try {
62 | List users = userService.queryList(null);
63 | users.forEach(System.out::println);
64 | } catch (SysException e) {
65 | System.err.println("select user error");
66 | e.printStackTrace();
67 | }
68 | }
69 |
70 | /**
71 | * 测试携参查询
72 | */
73 | @Test
74 | public void testSelectByParams() {
75 | try {
76 | Map map = new HashMap<>();
77 | map.put("phone", "18700000000");
78 | // 封装参数
79 | QueryParams params = new QueryParams(map);
80 | List users = userService.queryList(params);
81 | users.forEach(System.out::println);
82 | } catch (SysException e) {
83 | System.err.println("select user error");
84 | e.printStackTrace();
85 | }
86 | }
87 |
88 | }
89 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/src/main/java/git/yampery/cryptic/config/DruidConfig.java:
--------------------------------------------------------------------------------
1 | package git.yampery.cryptic.config;
2 |
3 | import com.alibaba.druid.pool.DruidDataSource;
4 | import com.alibaba.druid.support.http.StatViewServlet;
5 | import com.alibaba.druid.support.http.WebStatFilter;
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 | import org.springframework.beans.factory.annotation.Value;
9 | import org.springframework.boot.web.servlet.FilterRegistrationBean;
10 | import org.springframework.boot.web.servlet.ServletRegistrationBean;
11 | import org.springframework.context.annotation.Bean;
12 | import org.springframework.context.annotation.Configuration;
13 | import org.springframework.context.annotation.Primary;
14 | import org.springframework.context.annotation.PropertySource;
15 |
16 | import javax.sql.DataSource;
17 | import java.sql.SQLException;
18 |
19 | /**
20 | * @decription DruidConfig
21 | * Druid连接池配置
22 | * @author Yampery
23 | * @date 2018/4/4 12:59
24 | */
25 | @Configuration
26 | @PropertySource("classpath:jdbc.properties")
27 | public class DruidConfig {
28 |
29 | // private Logger logger = LoggerFactory.getLogger(getClass());
30 |
31 | /**
32 | * 数据源
33 | * @return
34 | */
35 | @Bean("dataSource")
36 | @Primary
37 | public DataSource druidDataSource() {
38 | DruidDataSource datasource = new DruidDataSource();
39 |
40 | datasource.setUrl(this.dbUrl);
41 | datasource.setUsername(username);
42 | datasource.setPassword(password);
43 | datasource.setDriverClassName(driverClassName);
44 | datasource.setInitialSize(initialSize);
45 | datasource.setMinIdle(minIdle);
46 | datasource.setMaxActive(maxActive);
47 | datasource.setMaxWait(maxWait);
48 | datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
49 | datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
50 | datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
51 | return datasource;
52 | }
53 |
54 |
55 | @Value("${jdbc.url}")
56 | private String dbUrl;
57 | @Value("${jdbc.username}")
58 | private String username;
59 | @Value("${jdbc.password}")
60 | private String password;
61 | @Value("${jdbc.driver}")
62 | private String driverClassName;
63 | @Value("${jdbc.pool.initialSize}")
64 | private int initialSize;
65 | @Value("${jdbc.pool.minIdle}")
66 | private int minIdle;
67 | @Value("${jdbc.pool.maxActive}")
68 | private int maxActive;
69 | @Value("${jdbc.pool.maxWait}")
70 | private int maxWait;
71 | @Value("${jdbc.pool.timeBetweenEvictionRunsMillis}")
72 | private int timeBetweenEvictionRunsMillis;
73 | @Value("${jdbc.pool.minEvictableIdleTimeMillis}")
74 | private int minEvictableIdleTimeMillis;
75 | @Value("${jdbc.pool.maxPoolPreparedStatementPerConnectionSize}")
76 | private int maxPoolPreparedStatementPerConnectionSize;
77 | }
78 |
79 |
--------------------------------------------------------------------------------
/src/main/resources/log4j2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/src/main/java/git/yampery/cryptic/cryptic/CryptPojo.java:
--------------------------------------------------------------------------------
1 | package git.yampery.cryptic.cryptic;
2 |
3 | import git.yampery.cryptic.annotation.DecryptField;
4 | import git.yampery.cryptic.annotation.EncryptField;
5 | import org.apache.commons.lang.StringUtils;
6 |
7 | import java.lang.reflect.Field;
8 |
9 | /**
10 | * @decription CryptPojo
11 | * 该类是加密对象。需要特殊对一个对象处理,可以采用安全克隆加密方法
12 | * 其子类可以通过调用encryptSelf()方法实现自加密,返回子类对象;
13 | * 调用decryptSelf()实现自解密,返回解密后的子类对象;
14 | * 上述加密方法encryptSelf对注解{@link EncryptField}字段有效;
15 | * 上述解密方法decryptSelf对注解{@link DecryptField}字段有效。
16 | * @author Yampery
17 | * @date 2018/4/4 13:36
18 | */
19 | public class CryptPojo implements Cloneable, ADESInterface {
20 |
21 | /**
22 | * 拷贝一个对象,并对新对象进行加密
23 | * 该方法主要用在日志打印上,可防止原对象被加密而影响程序执行
24 | * @param
25 | * @return
26 | */
27 | public T cloneAndEncrypt() {
28 | T cloneT = null;
29 | try {
30 | cloneT = (T) this.clone();
31 | } catch (CloneNotSupportedException e) {
32 | e.printStackTrace();
33 | return null;
34 | }
35 | if(cloneT !=null)
36 | return cloneT.encryptSelf();
37 | throw new RuntimeException("拷贝对象异常");
38 | }
39 | /**
40 | * 重写clone方法
41 | * @return
42 | * @throws CloneNotSupportedException
43 | */
44 | @Override
45 | protected Object clone() throws CloneNotSupportedException {
46 | try {
47 | return super.clone();
48 | } catch (CloneNotSupportedException e) {
49 | e.printStackTrace();
50 | return null;
51 | }
52 | }
53 |
54 | @Override
55 | public T encryptSelf() {
56 | Field[] declaredFields = this.getClass().getDeclaredFields();
57 | try {
58 | if (declaredFields != null && declaredFields.length > 0) {
59 | for (Field field : declaredFields) {
60 | if (field.isAnnotationPresent(EncryptField.class) && field.getType().toString().endsWith("String")) {
61 | field.setAccessible(true);
62 | String fieldValue = (String) field.get(this);
63 | if (StringUtils.isNotEmpty(fieldValue)) {
64 | field.set(this, ADESUtils.getInstance().encrypt(fieldValue));
65 | }
66 | field.setAccessible(false);
67 | }
68 | }
69 | }
70 | } catch (IllegalAccessException e) {
71 | throw new RuntimeException(e);
72 | }
73 | return (T) this;
74 | }
75 |
76 | @Override
77 | public T decryptSelf() {
78 | Field[] declaredFields = this.getClass().getDeclaredFields();
79 | try {
80 | if (declaredFields != null && declaredFields.length > 0) {
81 | for (Field field : declaredFields) {
82 | if (field.isAnnotationPresent(DecryptField.class) && field.getType().toString().endsWith("String")) {
83 | field.setAccessible(true);
84 | String fieldValue = (String)field.get(this);
85 | if(StringUtils.isNotEmpty(fieldValue)) {
86 | field.set(this, ADESUtils.getInstance().decrypt(fieldValue));
87 | }
88 | }
89 | }
90 | }
91 | } catch (IllegalAccessException e) {
92 | throw new RuntimeException(e);
93 | }
94 | return (T) this;
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/src/main/java/git/yampery/cryptic/interceptor/DBInterceptor.java:
--------------------------------------------------------------------------------
1 | package git.yampery.cryptic.interceptor;
2 |
3 | import git.yampery.cryptic.annotation.DecryptField;
4 | import git.yampery.cryptic.cryptic.CryptPojoUtils;
5 | import org.apache.commons.lang.StringUtils;
6 | import org.apache.ibatis.executor.Executor;
7 | import org.apache.ibatis.mapping.BoundSql;
8 | import org.apache.ibatis.mapping.MappedStatement;
9 | import org.apache.ibatis.plugin.*;
10 | import org.apache.ibatis.session.ResultHandler;
11 | import org.apache.ibatis.session.RowBounds;
12 | import org.slf4j.Logger;
13 | import org.slf4j.LoggerFactory;
14 | import org.springframework.beans.factory.annotation.Value;
15 | import org.springframework.stereotype.Component;
16 |
17 | import java.lang.reflect.Field;
18 | import java.util.ArrayList;
19 | import java.util.List;
20 | import java.util.Properties;
21 |
22 | /**
23 | * @decription DBInterceptor
24 | * 实现Mybatis拦截器,用于拦截修改,插入和返回需要加密或者解密的对象
25 | * @author Yampery
26 | * @date 2018/4/4 14:17
27 | */
28 | @Intercepts({
29 | @Signature(type=Executor.class,method="update",args={MappedStatement.class,Object.class}),
30 | @Signature(type=Executor.class,method="query",args={MappedStatement.class,Object.class,RowBounds.class,ResultHandler.class})
31 | })
32 | @Component
33 | public class DBInterceptor implements Interceptor {
34 | private final Logger logger = LoggerFactory.getLogger(DBInterceptor.class);
35 | @Value("${sys.aes.switch}") private String CRYPTIC_SWITCH;
36 | @Override
37 | public Object intercept(Invocation invocation) throws Throwable {
38 | MappedStatement statement = (MappedStatement) invocation.getArgs()[0];
39 | String methodName = invocation.getMethod().getName();
40 | Object parameter = invocation.getArgs()[1];
41 | BoundSql sql = statement.getBoundSql(parameter);
42 | logger.info("sql is: {}", sql.getSql());
43 |
44 | /**
45 | * @TODO 处理查询
46 | */
47 | if (StringUtils.equalsIgnoreCase("query", methodName)) {
48 | /**
49 | * 在这里可以处理查询参数,如传递的参数为明文,要按照密文查询
50 | * 本文选择使用同一参数封装处理方案{@link git.yampery.cryptic.common.QueryParams}
51 | */
52 | }
53 | /**
54 | * 拦截批量插入操作不仅繁琐,而且为了通用逐一通过反射加密不妥
55 | * 如果有批量操作,最好在传递参数之前,向list中添加之前就加密
56 | */
57 | if (!"0".equals(CRYPTIC_SWITCH)) {
58 | if (StringUtils.equalsIgnoreCase("update", methodName)
59 | || StringUtils.equalsIgnoreCase("insert", methodName)) {
60 | CryptPojoUtils.encryptField(parameter);
61 | }
62 | }
63 |
64 | Object returnValue = invocation.proceed();
65 |
66 | try {
67 | if (!"0".equals(CRYPTIC_SWITCH)) {
68 | if (returnValue instanceof ArrayList>) {
69 | List> list = (ArrayList>) returnValue;
70 | if (null == list || 1 > list.size())
71 | return returnValue;
72 | Object obj = list.get(0);
73 | if (null == obj) // 这里虽然list不是空,但是返回字符串等有可能为空
74 | return returnValue;
75 | // 判断第一个对象是否有DecryptField注解
76 | Field[] fields = obj.getClass().getDeclaredFields();
77 | int len;
78 | if (null != fields && 0 < (len = fields.length)) {
79 | // 标记是否有解密注解
80 | boolean isD = false;
81 | for (int i = 0; i < len; i++) {
82 | /**
83 | * 由于返回的是同一种类型列表,因此这里判断出来之后可以保存field的名称
84 | * 之后处理所有对象直接按照field名称查找Field从而改之即可
85 | * 有可能该类存在多个注解字段,所以需要保存到数组(项目中目前最多是2个)
86 | * @TODO 保存带DecryptField注解的字段名称到数组,按照名称获取字段并解密
87 | * */
88 | if (fields[i].isAnnotationPresent(DecryptField.class)) {
89 | isD = true;
90 | break;
91 | }
92 | } /// for end ~
93 | if (isD) // 将含有DecryptField注解的字段解密
94 | list.forEach(l -> CryptPojoUtils.decryptField(l));
95 | } /// if end ~
96 | } /// if end ~
97 | }
98 |
99 | } catch (Exception e) {
100 | logger.info("抛出异常 ==> " + e.getMessage());
101 | e.printStackTrace();
102 | return returnValue;
103 | }
104 | return returnValue;
105 | }
106 |
107 | @Override
108 | public Object plugin(Object target) {
109 | return Plugin.wrap(target, this);
110 | }
111 |
112 | @Override
113 | public void setProperties(Properties properties) {
114 | // TODO Auto-generated method stub
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/src/main/java/git/yampery/cryptic/cryptic/ADESUtils.java:
--------------------------------------------------------------------------------
1 | package git.yampery.cryptic.cryptic;
2 |
3 | import org.apache.commons.codec.binary.Hex;
4 | import org.apache.commons.lang.StringUtils;
5 | import org.springframework.beans.factory.annotation.Value;
6 | import org.springframework.stereotype.Component;
7 |
8 | import javax.crypto.Cipher;
9 | import javax.crypto.KeyGenerator;
10 | import javax.crypto.NoSuchPaddingException;
11 | import javax.crypto.SecretKey;
12 | import javax.crypto.spec.SecretKeySpec;
13 | import java.security.InvalidKeyException;
14 | import java.security.NoSuchAlgorithmException;
15 |
16 | /**
17 | * @decription ADESUtils
18 | * 字段加解密,使用MySql AES算法
19 | * @author Yampery
20 | * @date 2018/4/4 13:10
21 | */
22 | @Component
23 | public class ADESUtils {
24 | private static final String ENCRYPT_TYPE = "AES";
25 | private static final String ENCODING = "UTF-8";
26 |
27 | // 密盐
28 | private static String aesSalt;
29 | private static ADESUtils adesUtils;
30 | private static Cipher encryptCipher; // 加密cipher
31 | private static Cipher decryptChipher; // 解密chipher
32 |
33 | // 加解密开关,从配置获取
34 | private static String CRYPTIC_SWITCH;
35 | /**
36 | * 从配置中获取秘钥
37 | * :默认值填写自己生成的秘钥
38 | * @param key
39 | */
40 | @Value("${sys.aes.salt:0}")
41 | public void setAESSalt(String key){
42 | ADESUtils.aesSalt = key;
43 | }
44 |
45 | /**
46 | * 获取开关
47 | * 默认为不加密
48 | * @param val
49 | */
50 | @Value("${sys.aes.switch:0}")
51 | public void setCrypticSwitch(String val) {
52 | ADESUtils.CRYPTIC_SWITCH = val;
53 | }
54 | /**
55 | * encryptCipher、decryptChipher初始化
56 | */
57 | public static void init(){
58 | try {
59 | encryptCipher = Cipher.getInstance(ENCRYPT_TYPE);
60 | decryptChipher = Cipher.getInstance(ENCRYPT_TYPE);
61 | encryptCipher.init(Cipher.ENCRYPT_MODE, generateMySQLAESKey(aesSalt));
62 | decryptChipher.init(Cipher.DECRYPT_MODE, generateMySQLAESKey(aesSalt));
63 | } catch (InvalidKeyException e) {
64 | throw new RuntimeException(e);
65 | } catch (NoSuchAlgorithmException e) {
66 | throw new RuntimeException(e);
67 | } catch (NoSuchPaddingException e) {
68 | throw new RuntimeException(e);
69 | }
70 | }
71 |
72 | private ADESUtils() { }
73 |
74 | /**
75 | * 获取单例
76 | * @return
77 | */
78 | public static ADESUtils getInstance(){
79 | if(adesUtils == null){
80 | // 当需要创建的时候在加锁
81 | synchronized(ADESUtils.class) {
82 | if (adesUtils == null) {
83 | adesUtils = new ADESUtils();
84 | init();
85 | }
86 | }
87 | }
88 | return adesUtils;
89 | }
90 |
91 | /**
92 | * 对明文加密
93 | * @param pString
94 | * @return
95 | */
96 | public String encrypt(String pString) {
97 |
98 | if (StringUtils.isBlank(pString) || StringUtils.equals("0", CRYPTIC_SWITCH))
99 | return StringUtils.trimToEmpty(pString);
100 | try{
101 | return new String(Hex.encodeHex(encryptCipher.doFinal(pString.getBytes(ENCODING)))).toUpperCase();
102 | } catch (Exception e) {
103 | e.printStackTrace();
104 | return pString;
105 | }
106 | }
107 |
108 | /**
109 | * 对密文解密
110 | * @param eString
111 | * @return
112 | */
113 | public String decrypt(String eString) {
114 | if (StringUtils.isBlank(eString) || StringUtils.equals("0", CRYPTIC_SWITCH))
115 | return StringUtils.trimToEmpty(eString);
116 | try {
117 | return new String(decryptChipher.doFinal(Hex.decodeHex(eString.toCharArray())));
118 | } catch (Exception e) {
119 | e.printStackTrace();
120 | return eString;
121 | }
122 | }
123 | /**
124 | * 产生mysql-aes_encrypt
125 | * @param key 加密的密盐
126 | * @return
127 | */
128 | public static SecretKeySpec generateMySQLAESKey(final String key) {
129 | try {
130 | final byte[] finalKey = new byte[16];
131 | int i = 0;
132 | for(byte b : Hex.decodeHex(key.toCharArray()))
133 | finalKey[i++ % 16] ^= b;
134 | return new SecretKeySpec(finalKey, "AES");
135 | } catch(Exception e) {
136 | throw new RuntimeException(e);
137 | }
138 | }
139 |
140 | /**
141 | * 生成秘钥(128位)
142 | * @return
143 | * @throws Exception
144 | */
145 | public static String generateAESKey() throws Exception{
146 | //实例化
147 | KeyGenerator kgen = KeyGenerator.getInstance("AES");
148 | //设置密钥长度
149 | kgen.init(128);
150 | //生成密钥
151 | SecretKey skey = kgen.generateKey();
152 | // 转为16进制字串
153 | String key = new String(Hex.encodeHex(skey.getEncoded()));
154 | //返回密钥的16进制字串
155 | return key.toUpperCase();
156 | }
157 | }
158 |
--------------------------------------------------------------------------------
/src/main/java/git/yampery/cryptic/cryptic/CryptPojoUtils.java:
--------------------------------------------------------------------------------
1 | package git.yampery.cryptic.cryptic;
2 |
3 | import git.yampery.cryptic.annotation.DecryptField;
4 | import git.yampery.cryptic.annotation.EncryptField;
5 | import org.apache.commons.lang.StringUtils;
6 |
7 | import java.lang.reflect.Field;
8 |
9 | /**
10 | * @decription CryptPojoUtils
11 | * 对象加解密工具
12 | * 通过反射,对参数对象中包含指定注解的字段进行加解密。
13 | * 调用encrypt(T t)方法实现加密,返回加密后的对象;
14 | * 调用decrypt(T t)实现解密,返回解密后的对象;
15 | * encrypt对注解{@link EncryptField}字段有效;
16 | * decrypt对注解{@link DecryptField}字段有效。
17 | * @author Yampery
18 | * @date 2017/10/24 13:36
19 | */
20 | public class CryptPojoUtils {
21 |
22 | /**
23 | * 对对象t加密
24 | * @param t
25 | * @param
26 | * @return
27 | */
28 | public static T encrypt(T t) {
29 | Field[] declaredFields = t.getClass().getDeclaredFields();
30 | try {
31 | if (declaredFields != null && declaredFields.length > 0) {
32 | for (Field field : declaredFields) {
33 | if (field.isAnnotationPresent(EncryptField.class) && field.getType().toString().endsWith("String")) {
34 | field.setAccessible(true);
35 | String fieldValue = (String) field.get(t);
36 | if (StringUtils.isNotEmpty(fieldValue)) {
37 | field.set(t, ADESUtils.getInstance().encrypt(fieldValue));
38 | }
39 | field.setAccessible(false);
40 | }
41 | }
42 | }
43 | } catch (IllegalAccessException e) {
44 | throw new RuntimeException(e);
45 | }
46 | return t;
47 | }
48 |
49 | /**
50 | * 对象解密
51 | * @param t
52 | * @param
53 | * @return
54 | */
55 | public static T decrypt(T t) {
56 | Field[] declaredFields = t.getClass().getDeclaredFields();
57 | try {
58 | if (declaredFields != null && declaredFields.length > 0) {
59 | for (Field field : declaredFields) {
60 | if (field.isAnnotationPresent(DecryptField.class) && field.getType().toString().endsWith("String")) {
61 | field.setAccessible(true);
62 | String fieldValue = (String)field.get(t);
63 | if(StringUtils.isNotEmpty(fieldValue)) {
64 | field.set(t, ADESUtils.getInstance().decrypt(fieldValue));
65 | }
66 | }
67 | }
68 | }
69 | } catch (IllegalAccessException e) {
70 | throw new RuntimeException(e);
71 | }
72 | return t;
73 | }
74 |
75 | /**
76 | * 对含注解字段解密
77 | * @param t
78 | * @param
79 | */
80 | public static void decryptField(T t) {
81 | Field[] declaredFields = t.getClass().getDeclaredFields();
82 | try {
83 | if (declaredFields != null && declaredFields.length > 0) {
84 | for (Field field : declaredFields) {
85 | if (field.isAnnotationPresent(DecryptField.class) && field.getType().toString().endsWith("String")) {
86 | field.setAccessible(true);
87 | String fieldValue = (String)field.get(t);
88 | if(StringUtils.isNotEmpty(fieldValue)) {
89 | field.set(t, ADESUtils.getInstance().decrypt(fieldValue));
90 | }
91 | }
92 | }
93 | }
94 | } catch (IllegalAccessException e) {
95 | throw new RuntimeException(e);
96 | }
97 | // return t;
98 | }
99 |
100 | /**
101 | * 对含注解字段加密
102 | * @param t
103 | * @param
104 | */
105 | public static void encryptField(T t) {
106 | Field[] declaredFields = t.getClass().getDeclaredFields();
107 | try {
108 | if (declaredFields != null && declaredFields.length > 0) {
109 | for (Field field : declaredFields) {
110 | if (field.isAnnotationPresent(EncryptField.class) && field.getType().toString().endsWith("String")) {
111 | field.setAccessible(true);
112 | String fieldValue = (String)field.get(t);
113 | if(StringUtils.isNotEmpty(fieldValue)) {
114 | field.set(t, ADESUtils.getInstance().encrypt(fieldValue));
115 | }
116 | }
117 | }
118 | }
119 | } catch (IllegalAccessException e) {
120 | throw new RuntimeException(e);
121 | }
122 | }
123 |
124 | /**
125 | * 隐藏号码中间4位
126 | * @param t
127 | * @param
128 | */
129 | public static void hidePhone(T t) {
130 | Field[] declaredFields = t.getClass().getDeclaredFields();
131 | try {
132 | if (declaredFields != null && declaredFields.length > 0) {
133 | for (Field field : declaredFields) {
134 | if (field.isAnnotationPresent(DecryptField.class) && field.getType().toString().endsWith("String")) {
135 | field.setAccessible(true);
136 | String fieldValue = (String)field.get(t);
137 | if(StringUtils.isNotEmpty(fieldValue)) {
138 | // 暂时与解密注解共用一个注解,该注解隐藏手机号中间四位
139 | field.set(t, StringUtils.overlay(fieldValue, "****", 3, 7));
140 | }
141 | }
142 | }
143 | }
144 | } catch (IllegalAccessException e) {
145 | throw new RuntimeException(e);
146 | }
147 | }
148 | }
149 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn ( ) {
37 | echo "$*"
38 | }
39 |
40 | die ( ) {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save ( ) {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------