REM:
1. 初始化工程,添加phoenix脚手架框架
2. 添加迪普UMC平台SOAP接口
This commit is contained in:
huangxin 2020-03-17 09:31:15 +08:00
parent 21f988ceec
commit bdfd8abda1
85 changed files with 251478 additions and 0 deletions

112
README.md Normal file
View File

@ -0,0 +1,112 @@
> phoenix基础工程脚手架
>> package分层
>>> UserController OrderController PayController
>>>> 该层有统一的RequestBody和ResponseBody的切面操作主要用于请求报文解密和响应报文加密
>>> UserService MemeberService GoodsService StockService
>>> GlobalManagerCache,ExternalSystem Interface
>>> Manager层编写规范
>>>> 增
>>>>> saveXXX,返回int,标明该方法影响的行数;传参对象实体或List
>>>> 删
>>>>> deleteXXX,返回int,标明该方法影响的行数;传参具体条件
>>>> 改
>>>>> updateXXX,返回int,标明该方法影响的函数;传参对象实体
>>>> 查
>>>>> findXXX,返回对象实体或List;传参具体条件
>>>> 按照上述规范的方法可以加缓存注解进行统一缓存处理List暂不做缓存处理不满足上述规范的方法未必可行
>>> 缓存统一处理逻辑参照MyCacheInterceptor
>>>> Manager层收口也是为了后续数据层服务化提前做好准备
>>>> 可单独打包出数据层服务源码jar使用data-install.sh脚本
>>> UserDAO GoodsDAO OrderDAO BillDAO
>>>> MYSQL DAO层使用了tk.mybatis,常用语句封装完善只需要自定义复杂SQL即可, 具体参照com.cmcc.hy.phoenix.mapper.UserMappTest
>> 接口层参数校验
>>> 参照com.cmcc.hy.phoenix.controller.DemoController
>> 多个线程池
>>> 参照com.cmcc.hy.phoenix.thread.ThreadPoolConfig的多个线程池定义
>> 轻量级定时任务
>>> 参照com.cmcc.hy.phoenix.task.MyTask
>> 异步调用
>>> 参照com.cmcc.hy.phoenix.service.impl.AsyncServiceImpl
>> AOP自定义切面
>>> 参照com.cmcc.hy.phoenix.aop.MyInterceptor
>> 前后端交互统一数据格式
>>> 参照com.cmcc.hy.phoenix.vo.MyResp,com.cmcc.hy.phoenix.vo.Resp
>> 自定义配置加载
>>> 参照com.cmcc.hy.phoenix.config.MyConfig
>> 基于redis的分布式锁
>>> 参照com.cmcc.hy.phoenix.task.MyTask
>> MOCK单元测试
>>> 参照test package
>> Swagger API
>>> 参照com.cmcc.hy.phoenix.controller.TestController.postTest()
> 常用工具
>> 哈希加解密(AesCBC,AesECB,Des,3Des,Hmac,Md5,RsaECB,Sha1,Sha256,Sha512),具体用法见源码
>> 正则表达式,常用正则
>>> 参照com.cmcc.hy.phoenix.common.PatternUtil
>> 日期操作
>>> 参照com.cmcc.hy.phoenix.common.DateUtil
>>> hutool依赖各种常用工具
>日志管理
>>logback参照config/logback.xml
> 工程打包
>> 通过pom+assembly打出tgz解压后的目录参照开源软件常规目录形式
>>> xxx.tgz
>>>> bin 工程启停脚本
>>>> config 工程应用配置,日志配置
>>>> lib 工程依赖
>>>> xxx.jar 工程执行jar包
>>>> banner.txt 自定义启动字符画
> 运维标准目录
>> 按照公司运维标准把tgz包放到/apprun根目录下解压后运行即可
未完待续...

44
assembly.xml Normal file
View File

@ -0,0 +1,44 @@
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>assembly</id>
<formats>
<format>tgz</format>
</formats>
<fileSets>
<fileSet>
<directory>${project.build.directory}</directory>
<outputDirectory>${file.separator}</outputDirectory>
<includes>
<include>phoenix-boot.jar</include>
</includes>
</fileSet>
<fileSet>
<directory>config</directory>
<outputDirectory>${file.separator}config</outputDirectory>
</fileSet>
<fileSet>
<directory>bin</directory>
<outputDirectory>${file.separator}bin</outputDirectory>
</fileSet>
<fileSet>
<directory>src/main/resources/</directory>
<includes>
<include>
banner.txt
</include>
</includes>
<outputDirectory>${file.separator}</outputDirectory>
</fileSet>
</fileSets>
<dependencySets>
<dependencySet>
<outputDirectory>lib</outputDirectory>
<scope>compile</scope>
<excludes>
<exclude>${groupId}:${artifactId}</exclude>
</excludes>
</dependencySet>
</dependencySets>
</assembly>

3
bin/log_clean.sh Normal file
View File

@ -0,0 +1,3 @@
# 把下面语句编辑到crontab里定时清理日志每天凌晨1点清理日志保留7天日志
0 1 * * * find /apprun/phoenix-boot/logs -mtime +7 -name "*.log.*" -exec rm -rf {} \;

26
bin/processor_check.sh Normal file
View File

@ -0,0 +1,26 @@
# crontab里加上进程自动拉起任务做个简单的监控
# */1 * * * * source /etc/profile;sh /apprun/${YOUR_APP_NAME}/bin/processor_check.sh
# processor_check.sh脚本内容如下
#!/bin/bash
APP_NAME=phoenix-boot.jar
WORK_PATH=$(cd `dirname $0`; pwd)
pids=`ps -ef | grep $APP_NAME | grep -v grep | wc -l`
if [ "$pids" -le 0 ]
then
echo "start $APP_NAME processor ......"
cd $WORK_PATH
cd ..
nohup sh bin/start.sh >/dev/null 2>&1 &
sleep 5
pids=`ps -ef | grep $APP_NAME | grep -v grep | wc -l`
if [ "$pids" -gt 0 ]
then
echo "$APP_NAME processor started"
else
echo "Failed to start $APP_NAME processor"
fi
else
echo "$APP_NAME processor is running ......"
fi

8
bin/start.sh Normal file
View File

@ -0,0 +1,8 @@
#!/bin/bash
JAVA_DEBUG_OPTS=" -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,address=8001,server=y,suspend=n "
JAVA_JMX_OPTS=" -Dcom.sun.management.jmxremote.port=9999 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false "
JAVA_OPTS="-Djava.security.egd=file:/dev/./urandom -server -Xms512M -Xmx512M -Xss256K -XX:MetaspaceSize=16M -XX:MaxMetaspaceSize=128M -XX:MaxDirectMemorySize=1g -XX:SurvivorRatio=8 -XX:+UseG1GC -XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/heapdump.hprof"
WORK_PATH=$(cd `dirname $0`; pwd)
cd $WORK_PATH
cd ..
$JAVA_HOME/bin/java $JAVA_DEBUG_OPTS $JAVA_JMX_OPTS $JAVA_OPTS -jar phoenix-boot.jar

15
bin/stop.sh Normal file
View File

@ -0,0 +1,15 @@
#!/bin/bash
APP_NAME=phoenix-boot.jar
pids=`ps -ef | grep $APP_NAME | grep -v grep | awk '{print $2}'`
for pid in $pids
do
echo stop $APP_NAME java process: $pid
kill -9 $pid
done
nr_pids=`ps -ef | grep $APP_NAME | grep -v grep | wc -l`
while [ $nr_pids -gt 0 ]
do
nr_pids=`ps -ef | grep $APP_NAME | grep -v grep | wc -l`
done

View File

@ -0,0 +1,58 @@
server.port=9276
# 根据自身环境修改
server.tomcat.basedir=./basedir
# 多个项目放在nginx下同个端口通过该配置区分
server.servlet.context-path=/phoenix
# 配置数据源
spring.datasource.url=jdbc:mysql://172.28.72.118:33061/phoenix_local?serverTimezone=Asia/Shanghai&zeroDateTimeBehavior=convertToNull&useUnicode=true
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=phoenix
spring.datasource.password=Hy@rfph32
# 配置连接池
spring.datasource.type=org.apache.commons.dbcp2.BasicDataSource
spring.datasource.dbcp2.max-total=128
spring.datasource.dbcp2.max-wait-millis=10000
spring.datasource.dbcp2.max-idle=32
spring.datasource.dbcp2.min-idle=8
spring.datasource.dbcp2.initial-size=8
spring.datasource.dbcp2.validation-query=SELECT 1
spring.datasource.dbcp2.test-while-idle=true
spring.datasource.dbcp2.connection-properties=characterEncoding=utf8
#mybatis 配置
# 下划线转驼峰 将带有下划线的表字段映射为驼峰格式的实体类属性
#mybatis.configuration.map-underscore-to-camel-case: true
mybatis.mapper-locations=classpath*:mappers/*.xml
mybatis.type-aliases-package=com.cmcc.hy.phoenix.entity
#config log
logging.config=file:config/logback.xml
#config tomcat
server.tomcat.max-threads=128
#====custom config,begin with phoenix====
#test
phoenix.system-name=phoenix framework
#config the swagger api switch true:可访问;false:不可访问
phoenix.swagger-switch=true
#config which client to use in redis,jedis or redisson
phoenix.redis.type=redisson
#config redis info
#jedis config example>redis://:dfu56li_jdo8pd@172.28.72.111:7379/0,多个用逗号分隔
#redisson sentinel config example>redis://172.28.72.104:28379,redis://172.28.72.124:28380,redis://172.28.72.124:28381
phoenix.redis-server=redis://172.28.72.104:28379,redis://172.28.72.124:28380,redis://172.28.72.124:28381
#redis://172.28.72.113:7379/2
phoenix.redis-redisson-sentinel-master-name=mymaster
phoenix.redis-redisson-pwd=cmcc2019
#config request dec switch,true=dec,false=plain do nothing
phoenix.request-dec-switch=false
#config response enc switch,true=enc,false=plain do nothing
phoenix.response-enc-switch=false
#config aes 128 key,用于上述body的加解密
phoenix.aes-key=Wt4EJu6Rrq5udd/42bNpCQ==
#====custom config,begin with phoenix====

View File

@ -0,0 +1,58 @@
server.port=9276
# 根据自身环境修改
server.tomcat.basedir=./basedir
# 多个项目放在nginx下同个端口通过该配置区分
server.servlet.context-path=/phoenix
# 配置数据源
spring.datasource.url=jdbc:mysql://172.28.72.118:33061/phoenix_local?serverTimezone=Asia/Shanghai&zeroDateTimeBehavior=convertToNull&useUnicode=true
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=phoenix
spring.datasource.password=Hy@rfph32
# 配置连接池
spring.datasource.type=org.apache.commons.dbcp2.BasicDataSource
spring.datasource.dbcp2.max-total=128
spring.datasource.dbcp2.max-wait-millis=10000
spring.datasource.dbcp2.max-idle=32
spring.datasource.dbcp2.min-idle=8
spring.datasource.dbcp2.initial-size=8
spring.datasource.dbcp2.validation-query=SELECT 1
spring.datasource.dbcp2.test-while-idle=true
spring.datasource.dbcp2.connection-properties=characterEncoding=utf8
#mybatis 配置
# 下划线转驼峰 将带有下划线的表字段映射为驼峰格式的实体类属性
#mybatis.configuration.map-underscore-to-camel-case: true
mybatis.mapper-locations=classpath*:mappers/*.xml
mybatis.type-aliases-package=com.cmcc.hy.phoenix.entity
#config log
logging.config=file:config/logback.xml
#config tomcat
server.tomcat.max-threads=128
#====custom config,begin with phoenix====
#test
phoenix.system-name=phoenix framework
#config the swagger api switch true:可访问;false:不可访问
phoenix.swagger-switch=true
#config which client to use in redis,jedis or redisson
phoenix.redis.type=redisson
#config redis info
#jedis config example>redis://:dfu56li_jdo8pd@172.28.72.111:7379/0,多个用逗号分隔
#redisson sentinel config example>redis://172.28.72.104:28379,redis://172.28.72.124:28380,redis://172.28.72.124:28381
phoenix.redis-server=redis://172.28.72.104:28379,redis://172.28.72.124:28380,redis://172.28.72.124:28381
#redis://172.28.72.113:7379/2
phoenix.redis-redisson-sentinel-master-name=mymaster
phoenix.redis-redisson-pwd=cmcc2019
#config request dec switch,true=dec,false=plain do nothing
phoenix.request-dec-switch=false
#config response enc switch,true=enc,false=plain do nothing
phoenix.response-enc-switch=false
#config aes 128 key,用于上述body的加解密
phoenix.aes-key=Wt4EJu6Rrq5udd/42bNpCQ==
#====custom config,begin with phoenix====

View File

@ -0,0 +1,58 @@
server.port=9276
# 根据自身环境修改
server.tomcat.basedir=./basedir
# 多个项目放在nginx下同个端口通过该配置区分
server.servlet.context-path=/phoenix
# 配置数据源
spring.datasource.url=jdbc:mysql://172.28.72.118:33061/phoenix_local?serverTimezone=Asia/Shanghai&zeroDateTimeBehavior=convertToNull&useUnicode=true
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=phoenix
spring.datasource.password=Hy@rfph32
# 配置连接池
spring.datasource.type=org.apache.commons.dbcp2.BasicDataSource
spring.datasource.dbcp2.max-total=128
spring.datasource.dbcp2.max-wait-millis=10000
spring.datasource.dbcp2.max-idle=32
spring.datasource.dbcp2.min-idle=8
spring.datasource.dbcp2.initial-size=8
spring.datasource.dbcp2.validation-query=SELECT 1
spring.datasource.dbcp2.test-while-idle=true
spring.datasource.dbcp2.connection-properties=characterEncoding=utf8
#mybatis 配置
# 下划线转驼峰 将带有下划线的表字段映射为驼峰格式的实体类属性
#mybatis.configuration.map-underscore-to-camel-case: true
mybatis.mapper-locations=classpath*:mappers/*.xml
mybatis.type-aliases-package=com.cmcc.hy.phoenix.entity
#config log
logging.config=file:config/logback.xml
#config tomcat
server.tomcat.max-threads=128
#====custom config,begin with phoenix====
#test
phoenix.system-name=phoenix framework
#config the swagger api switch true:可访问;false:不可访问
phoenix.swagger-switch=true
#config which client to use in redis,jedis or redisson
phoenix.redis.type=redisson
#config redis info
#jedis config example>redis://:dfu56li_jdo8pd@172.28.72.111:7379/0,多个用逗号分隔
#redisson sentinel config example>redis://172.28.72.104:28379,redis://172.28.72.124:28380,redis://172.28.72.124:28381
phoenix.redis-server=redis://172.28.72.104:28379,redis://172.28.72.124:28380,redis://172.28.72.124:28381
#redis://172.28.72.113:7379/2
phoenix.redis-redisson-sentinel-master-name=mymaster
phoenix.redis-redisson-pwd=cmcc2019
#config request dec switch,true=dec,false=plain do nothing
phoenix.request-dec-switch=false
#config response enc switch,true=enc,false=plain do nothing
phoenix.response-enc-switch=false
#config aes 128 key,用于上述body的加解密
phoenix.aes-key=Wt4EJu6Rrq5udd/42bNpCQ==
#====custom config,begin with phoenix====

View File

@ -0,0 +1,58 @@
server.port=9276
# 根据自身环境修改
server.tomcat.basedir=./basedir
# 多个项目放在nginx下同个端口通过该配置区分
server.servlet.context-path=/phoenix
# 配置数据源
spring.datasource.url=jdbc:mysql://172.28.72.118:33061/phoenix_local?serverTimezone=Asia/Shanghai&zeroDateTimeBehavior=convertToNull&useUnicode=true
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=phoenix
spring.datasource.password=Hy@rfph32
# 配置连接池
spring.datasource.type=org.apache.commons.dbcp2.BasicDataSource
spring.datasource.dbcp2.max-total=128
spring.datasource.dbcp2.max-wait-millis=10000
spring.datasource.dbcp2.max-idle=32
spring.datasource.dbcp2.min-idle=8
spring.datasource.dbcp2.initial-size=8
spring.datasource.dbcp2.validation-query=SELECT 1
spring.datasource.dbcp2.test-while-idle=true
spring.datasource.dbcp2.connection-properties=characterEncoding=utf8
#mybatis 配置
# 下划线转驼峰 将带有下划线的表字段映射为驼峰格式的实体类属性
#mybatis.configuration.map-underscore-to-camel-case: true
mybatis.mapper-locations=classpath*:mappers/*.xml
mybatis.type-aliases-package=com.cmcc.hy.phoenix.entity
#config log
logging.config=file:config/logback.xml
#config tomcat
server.tomcat.max-threads=128
#====custom config,begin with phoenix====
#test
phoenix.system-name=phoenix framework
#config the swagger api switch true:可访问;false:不可访问
phoenix.swagger-switch=true
#config which client to use in redis,jedis or redisson
phoenix.redis.type=redisson
#config redis info
#jedis config example>redis://:dfu56li_jdo8pd@172.28.72.111:7379/0,多个用逗号分隔
#redisson sentinel config example>redis://172.28.72.104:28379,redis://172.28.72.124:28380,redis://172.28.72.124:28381
phoenix.redis-server=redis://172.28.72.104:28379,redis://172.28.72.124:28380,redis://172.28.72.124:28381
#redis://172.28.72.113:7379/2
phoenix.redis-redisson-sentinel-master-name=mymaster
phoenix.redis-redisson-pwd=cmcc2019
#config request dec switch,true=dec,false=plain do nothing
phoenix.request-dec-switch=false
#config response enc switch,true=enc,false=plain do nothing
phoenix.response-enc-switch=false
#config aes 128 key,用于上述body的加解密
phoenix.aes-key=Wt4EJu6Rrq5udd/42bNpCQ==
#====custom config,begin with phoenix====

View File

@ -0,0 +1 @@
spring.profiles.active=local

101
config/logback.xml Normal file
View File

@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8" ?>
<configuration scan="true">
<property name="LOG_PATH" value="./logs" />
<property name="LOG_LEVEL" value="info" />
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder charset="UTF-8">
<pattern>[%d{yy-MM-dd HH:mm:ss:SSS}][%-5p][%c][%t]%m%n</pattern>
</encoder>
</appender>
<appender name="BIZ"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/biz.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/biz.log.%d{yyyyMMdd}
</fileNamePattern>
</rollingPolicy>
<encoder charset="UTF-8">
<pattern>[%d{yy-MM-dd HH:mm:ss:SSS}][%-5p][%c][%t]%m%n</pattern>
</encoder>
</appender>
<appender name="SYSTEM-LOG-FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/system.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/system.log.%d{yyyyMMdd}
</fileNamePattern>
</rollingPolicy>
<encoder charset="UTF-8">
<pattern>[%d{yy-MM-dd HH:mm:ss:SSS}][%-5p][%c][%t]%m%n</pattern>
</encoder>
</appender>
<appender name="DATA"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/data.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/data.log.%d{yyyyMMdd}
</fileNamePattern>
</rollingPolicy>
<encoder charset="UTF-8">
<pattern>[%d{yy-MM-dd HH:mm:ss:SSS}][%-5p][%c][%t]%m%n</pattern>
</encoder>
</appender>
<logger name="com.cmcc.hy.phoenix" level="${LOG_LEVEL}" additivity="false">
<appender-ref ref="BIZ" />
<appender-ref ref="CONSOLE" />
</logger>
<logger name="com.cmcc.hy.phoenix.mapper" level="${LOG_LEVEL}"
additivity="false">
<appender-ref ref="DATA" />
<appender-ref ref="CONSOLE" />
</logger>
<logger name="org.mybatis" level="${LOG_LEVEL}" additivity="false">
<appender-ref ref="DATA" />
<appender-ref ref="CONSOLE" />
</logger>
<logger name="org.apache.ibatis" level="${LOG_LEVEL}"
additivity="false">
<appender-ref ref="DATA" />
</logger>
<logger name="org.mybatis.spring" level="${LOG_LEVEL}"
additivity="false">
<appender-ref ref="DATA" />
</logger>
<logger name="org.springframework.jdbc" level="${LOG_LEVEL}"
additivity="false">
<appender-ref ref="DATA" />
<appender-ref ref="CONSOLE" />
</logger>
<logger name="org.springframework.orm" level="${LOG_LEVEL}"
additivity="false">
<appender-ref ref="DATA" />
</logger>
<logger name="com.mysql" level="${LOG_LEVEL}" additivity="false">
<appender-ref ref="DATA" />
<appender-ref ref="CONSOLE" />
</logger>
<logger name="java.sql" level="${LOG_LEVEL}" additivity="false">
<appender-ref ref="DATA" />
<appender-ref ref="CONSOLE" />
</logger>
<logger name="javax.sql" level="${LOG_LEVEL}" additivity="false">
<appender-ref ref="DATA" />
</logger>
<root level="${LOG_LEVEL}">
<appender-ref ref="SYSTEM-LOG-FILE" />
<appender-ref ref="CONSOLE" />
</root>
</configuration>

1
data-install.sh Normal file
View File

@ -0,0 +1 @@
mvn clean package -Dmaven.test.skip -f data-pom.xml

259
data-pom.xml Normal file
View File

@ -0,0 +1,259 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.cmcc.hy</groupId>
<artifactId>phoenix-boot</artifactId>
<version>0.0.3</version>
<relativePath />
</parent>
<groupId>com.cmcc.hy.aq</groupId>
<artifactId>phoenix-data</artifactId>
<version>1.0.0</version>
<name>phoenix-data</name>
<description>Demo project for Spring Boot</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-annotations-api</artifactId>
</exclusion>
</exclusions>
<version>9.0.31</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
</dependency>
<!--mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--mybatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
<dependency>
<groupId>oro</groupId>
<artifactId>oro</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
<!-- 通用Mapper -->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
</dependency>
<!-- 分页助手 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.cmcc</groupId>
<artifactId>enc.dec</artifactId>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<dependency>
<groupId>org.objenesis</groupId>
<artifactId>objenesis</artifactId>
</dependency>
<dependency>
<groupId>io.protostuff</groupId>
<artifactId>protostuff-core</artifactId>
</dependency>
<dependency>
<groupId>io.protostuff</groupId>
<artifactId>protostuff-runtime</artifactId>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito2</artifactId>
<version>2.0.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>2.0.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.12.1</version>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>javax.el</artifactId>
<version>2.2.4</version>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-adb</artifactId>
<version>1.7.9</version>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-transport-local</artifactId>
<version>1.7.9</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-transport-http</artifactId>
<version>1.7.9</version>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<finalName>phoenix-data</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<!-- 单独将dao打出jar包供其它组件使用 -->
<includes>
<include>com/cmcc/hy/phoenix/mapper/*</include>
<include>com/cmcc/hy/phoenix/pojo/entity/*</include>
<include>com/cmcc/hy/phoenix/manager/*</include>
<include>com/cmcc/hy/phoenix/redis/*</include>
<include>mappers/*</include>
</includes>
</configuration>
</plugin>
<plugin>
<artifactId>maven-source-plugin</artifactId>
<configuration>
<attach>true</attach>
</configuration>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>

1
install.sh Normal file
View File

@ -0,0 +1 @@
mvn clean install -Dmaven.test.skip

218
phoenix-data.iml Normal file
View File

@ -0,0 +1,218 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="Spring" name="Spring">
<configuration />
</facet>
<facet type="web" name="Web">
<configuration>
<webroots />
<sourceRoots>
<root url="file://$MODULE_DIR$/src/main/java" />
<root url="file://$MODULE_DIR$/src/main/resources" />
</sourceRoots>
</configuration>
</facet>
</component>
<component name="MavenCustomPomFilePath">
<option name="mavenPomFileUrl" value="file://$MODULE_DIR$/data-pom.xml" />
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$/src/main/java">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
</content>
<content url="file://$MODULE_DIR$/src/main/resources">
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
</content>
<content url="file://$MODULE_DIR$/src/test/java">
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" scope="RUNTIME" name="Maven: org.springframework.boot:spring-boot-starter-actuator:2.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.2.3" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.2.3" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-to-slf4j:2.12.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.12.1" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.30" level="project" />
<orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:1.3.5" level="project" />
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.25" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: org.springframework.boot:spring-boot-actuator-autoconfigure:2.2.4.RELEASE" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: org.springframework.boot:spring-boot-actuator:2.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.2.3.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.10.2" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: io.micrometer:micrometer-core:1.3.2" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: org.hdrhistogram:HdrHistogram:2.1.11" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: org.latencyutils:LatencyUtils:2.0.3" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-web:2.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-json:2.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.10.2" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.module:jackson-module-parameter-names:2.10.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-validation:2.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: jakarta.validation:jakarta.validation-api:2.0.2" level="project" />
<orderEntry type="library" name="Maven: org.hibernate.validator:hibernate-validator:6.0.18.Final" level="project" />
<orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.4.1.Final" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-web:5.2.3.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.2.3.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-webmvc:5.2.3.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.2.3.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-core:9.0.31" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-aop:2.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-aop:5.2.3.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.aspectj:aspectjweaver:1.9.5" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: org.springframework.boot:spring-boot-devtools:2.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-configuration-processor:2.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-swagger2:2.9.2" level="project" />
<orderEntry type="library" name="Maven: io.swagger:swagger-annotations:1.5.20" level="project" />
<orderEntry type="library" name="Maven: io.swagger:swagger-models:1.5.20" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.10.2" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-spi:2.9.2" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-core:2.9.2" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-schema:2.9.2" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-swagger-common:2.9.2" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-spring-web:2.9.2" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml:classmate:1.5.1" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.30" level="project" />
<orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-core:1.2.0.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-metadata:1.2.0.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.mapstruct:mapstruct:1.2.0.Final" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-swagger-ui:2.9.2" level="project" />
<orderEntry type="library" name="Maven: mysql:mysql-connector-java:8.0.19" level="project" />
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-starter:2.1.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.zaxxer:HikariCP:3.4.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jdbc:5.2.3.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-tx:5.2.3.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-autoconfigure:2.1.0" level="project" />
<orderEntry type="library" name="Maven: org.mybatis:mybatis:3.5.2" level="project" />
<orderEntry type="library" name="Maven: org.mybatis:mybatis-spring:2.0.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-dbcp2:2.7.0" level="project" />
<orderEntry type="library" name="Maven: org.projectlombok:lombok:1.18.10" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-starter-test:2.2.4.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-test:2.2.4.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-test-autoconfigure:2.2.4.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: com.jayway.jsonpath:json-path:2.4.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: net.minidev:json-smart:2.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: net.minidev:accessors-smart:1.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.ow2.asm:asm:5.0.4" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: jakarta.xml.bind:jakarta.xml.bind-api:2.3.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: jakarta.activation:jakarta.activation-api:1.2.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter:5.5.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter-api:5.5.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.opentest4j:opentest4j:1.2.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.junit.platform:junit-platform-commons:1.5.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter-params:5.5.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter-engine:5.5.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.junit.vintage:junit-vintage-engine:5.5.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.apiguardian:apiguardian-api:1.1.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.junit.platform:junit-platform-engine:1.5.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-junit-jupiter:3.1.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.assertj:assertj-core:3.13.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest:2.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-core:3.1.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: net.bytebuddy:byte-buddy-agent:1.10.6" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.skyscreamer:jsonassert:1.5.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: com.vaadin.external.google:android-json:0.0.20131108.vaadin1" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-core:5.2.3.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.2.3.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework:spring-test:5.2.3.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.xmlunit:xmlunit-core:2.6.3" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.9" level="project" />
<orderEntry type="library" name="Maven: commons-io:commons-io:2.6" level="project" />
<orderEntry type="library" name="Maven: oro:oro:2.0.8" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:guava:28.2-jre" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:failureaccess:1.0.1" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava" level="project" />
<orderEntry type="library" name="Maven: com.google.code.findbugs:jsr305:3.0.2" level="project" />
<orderEntry type="library" name="Maven: org.checkerframework:checker-qual:2.10.0" level="project" />
<orderEntry type="library" name="Maven: com.google.errorprone:error_prone_annotations:2.3.4" level="project" />
<orderEntry type="library" name="Maven: com.google.j2objc:j2objc-annotations:1.3" level="project" />
<orderEntry type="library" name="Maven: joda-time:joda-time:2.10.5" level="project" />
<orderEntry type="library" name="Maven: cn.hutool:hutool-all:5.0.0" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-spring-boot-starter:2.0.4" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-core:1.0.5" level="project" />
<orderEntry type="library" name="Maven: javax.persistence:persistence-api:1.0" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-base:1.0.5" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-weekend:1.1.4.1" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-spring:1.0.5" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-extra:1.0.5" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-spring-boot-autoconfigure:2.0.4" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-starter:1.2.9" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-autoconfigure:1.2.9" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper:5.1.7" level="project" />
<orderEntry type="library" name="Maven: com.github.jsqlparser:jsqlparser:1.2" level="project" />
<orderEntry type="library" name="Maven: com.cmcc:enc.dec:1.3.1" level="project" />
<orderEntry type="library" name="Maven: commons-codec:commons-codec:1.13" level="project" />
<orderEntry type="library" name="Maven: redis.clients:jedis:3.1.0" level="project" />
<orderEntry type="library" name="Maven: org.objenesis:objenesis:2.6" level="project" />
<orderEntry type="library" name="Maven: io.protostuff:protostuff-core:1.4.4" level="project" />
<orderEntry type="library" name="Maven: io.protostuff:protostuff-api:1.4.4" level="project" />
<orderEntry type="library" name="Maven: io.protostuff:protostuff-runtime:1.4.4" level="project" />
<orderEntry type="library" name="Maven: io.protostuff:protostuff-collectionschema:1.4.4" level="project" />
<orderEntry type="library" name="Maven: com.google.protobuf:protobuf-java:3.1.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-pool2:2.7.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.powermock:powermock-api-mockito2:2.0.5" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.powermock:powermock-api-support:2.0.5" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.powermock:powermock-reflect:2.0.5" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.powermock:powermock-core:2.0.5" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.powermock:powermock-module-junit4:2.0.5" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.powermock:powermock-module-junit4-common:2.0.5" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:2.1" level="project" />
<orderEntry type="library" name="Maven: org.redisson:redisson:3.12.1" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-common:4.1.45.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-codec:4.1.45.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-buffer:4.1.45.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-transport:4.1.45.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-resolver:4.1.45.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-resolver-dns:4.1.45.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-codec-dns:4.1.45.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-handler:4.1.45.Final" level="project" />
<orderEntry type="library" name="Maven: javax.cache:cache-api:1.1.1" level="project" />
<orderEntry type="library" name="Maven: io.projectreactor:reactor-core:3.3.2.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.reactivestreams:reactive-streams:1.0.3" level="project" />
<orderEntry type="library" name="Maven: io.reactivex.rxjava2:rxjava:2.2.17" level="project" />
<orderEntry type="library" name="Maven: de.ruedigermoeller:fst:2.57" level="project" />
<orderEntry type="library" name="Maven: org.javassist:javassist:3.21.0-GA" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.10.2" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.10.2" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.10.2" level="project" />
<orderEntry type="library" name="Maven: net.bytebuddy:byte-buddy:1.10.6" level="project" />
<orderEntry type="library" name="Maven: org.jodd:jodd-bean:5.0.13" level="project" />
<orderEntry type="library" name="Maven: org.jodd:jodd-core:5.0.13" level="project" />
<orderEntry type="library" name="Maven: javax.el:javax.el-api:3.0.0" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.web:javax.el:2.2.4" level="project" />
<orderEntry type="library" name="Maven: org.apache.axis2:axis2-adb:1.7.9" level="project" />
<orderEntry type="library" name="Maven: org.apache.axis2:axis2-kernel:1.7.9" level="project" />
<orderEntry type="library" name="Maven: org.apache.ws.commons.axiom:axiom-api:1.2.21" level="project" />
<orderEntry type="library" name="Maven: jaxen:jaxen:1.2.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.geronimo.specs:geronimo-stax-api_1.0_spec:1.0.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.james:apache-mime4j-core:0.7.2" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: org.apache.ws.commons.axiom:axiom-impl:1.2.21" level="project" />
<orderEntry type="library" name="Maven: org.apache.geronimo.specs:geronimo-ws-metadata_2.0_spec:1.1.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.geronimo.specs:geronimo-jta_1.1_spec:1.1" level="project" />
<orderEntry type="library" name="Maven: javax.servlet:servlet-api:2.3" level="project" />
<orderEntry type="library" name="Maven: commons-fileupload:commons-fileupload:1.3.3" level="project" />
<orderEntry type="library" name="Maven: wsdl4j:wsdl4j:1.6.3" level="project" />
<orderEntry type="library" name="Maven: org.apache.ws.xmlschema:xmlschema-core:2.2.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.neethi:neethi:3.0.3" level="project" />
<orderEntry type="library" name="Maven: org.apache.woden:woden-core:1.0M10" level="project" />
<orderEntry type="library" name="Maven: commons-logging:commons-logging:1.1.1" level="project" />
<orderEntry type="library" name="Maven: javax.ws.rs:jsr311-api:1.1.1" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: org.apache.ws.commons.axiom:axiom-dom:1.2.21" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: org.codehaus.woodstox:woodstox-core-asl:4.2.0" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: org.codehaus.woodstox:stax2-api:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.geronimo.specs:geronimo-activation_1.1_spec:1.0.2" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: org.apache.axis2:axis2-transport-local:1.7.9" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: org.apache.axis2:axis2-transport-http:1.7.9" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: org.apache.httpcomponents:httpclient:4.5.10" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: org.apache.httpcomponents:httpcore:4.4.13" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: commons-httpclient:commons-httpclient:3.1" level="project" />
</component>
</module>

294
pom.xml Normal file
View File

@ -0,0 +1,294 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.cmcc.hy</groupId>
<artifactId>phoenix-boot</artifactId>
<version>0.0.3</version>
<relativePath />
</parent>
<groupId>com.cmcc.hy.aq</groupId>
<artifactId>phoenix-boot</artifactId>
<version>1.0.0</version>
<name>phoenix-boot</name>
<description>Demo project for Spring Boot</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-annotations-api</artifactId>
</exclusion>
</exclusions>
<version>9.0.31</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
</dependency>
<!--mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--mybatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
<dependency>
<groupId>oro</groupId>
<artifactId>oro</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
<!-- 通用Mapper -->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
</dependency>
<!-- 分页助手 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.cmcc</groupId>
<artifactId>enc.dec</artifactId>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<dependency>
<groupId>org.objenesis</groupId>
<artifactId>objenesis</artifactId>
</dependency>
<dependency>
<groupId>io.protostuff</groupId>
<artifactId>protostuff-core</artifactId>
</dependency>
<dependency>
<groupId>io.protostuff</groupId>
<artifactId>protostuff-runtime</artifactId>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito2</artifactId>
<version>2.0.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>2.0.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.12.1</version>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>javax.el</artifactId>
<version>2.2.4</version>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-adb</artifactId>
<version>1.7.9</version>
</dependency>
</dependencies>
<build>
<finalName>phoenix-boot</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>com.cmcc.hy.phoenix.PhoenixBootApplication</mainClass>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
</manifest>
<manifestEntries>
<Class-Path>./</Class-Path>
</manifestEntries>
</archive>
<excludes>
<exclude>config/**</exclude>
<exclude>templates/**</exclude>
<exclude>static/**</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<configuration>
<excludes>
</excludes>
</configuration>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>prepare-package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<appendAssemblyId>true</appendAssemblyId>
<descriptors>
<descriptor>assembly.xml</descriptor>
</descriptors>
</configuration>
</plugin>
<plugin>
<groupId>pl.project13.maven</groupId>
<artifactId>git-commit-id-plugin</artifactId>
<version>4.0.0</version>
<executions>
<execution>
<id>get-the-git-infos</id>
<goals>
<goal>revision</goal>
</goals>
<phase>initialize</phase>
</execution>
</executions>
<configuration>
<failOnNoGitDirectory>false</failOnNoGitDirectory>
<verbose>true</verbose>
<dateFormat>yyyy-MM-dd'T'HH:mm:ssZ</dateFormat>
<generateGitPropertiesFile>true</generateGitPropertiesFile>
<generateGitPropertiesFilename>${project.basedir}/src/main/resources/git.properties</generateGitPropertiesFilename>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,34 @@
package com.cmcc.hy.phoenix;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import lombok.extern.slf4j.Slf4j;
import tk.mybatis.spring.annotation.MapperScan;
/**
* 系统启动入口
*
* @author phoenix
* @date 2020年2月4日
*/
@SpringBootApplication
@EnableAsync
@EnableScheduling
@EnableAspectJAutoProxy
@MapperScan(basePackages = { "com.cmcc.hy.phoenix.mapper" })
@Slf4j
public class PhoenixBootApplication {
public static void main(String[] args) {
SpringApplication.run(PhoenixBootApplication.class, args);
log.info("\n----------------------------------------------------------\n\t"
+ "Phoenix Application is running! Access URLs:\n\t"
+ "swagger-ui: \thttp://ip:port/${context-path}/swagger-ui.html\n\t" + "If you set the api switch true! \n\t"
+ "----------------------------------------------------------");
}
}

View File

@ -0,0 +1,34 @@
package com.cmcc.hy.phoenix.annotation;
import com.cmcc.hy.phoenix.annotation.validator.UserIdValidator;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
*
*
* @author phoenix
* @date 2020年2月8日
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD, ElementType.ANNOTATION_TYPE })
//指定注解的处理类
@Constraint(validatedBy = { UserIdValidator.class })
public @interface UserId {
String value() default "";
String message() default "用户 ID 不存在";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}

View File

@ -0,0 +1,19 @@
package com.cmcc.hy.phoenix.annotation.bodyencdec;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
*
*
* @author phoenix
* @date 2020年2月10日
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ReqDec {
}

View File

@ -0,0 +1,19 @@
package com.cmcc.hy.phoenix.annotation.bodyencdec;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
*
*
* @author phoenix
* @date 2020年2月10日
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface RespEnc {
}

View File

@ -0,0 +1,37 @@
package com.cmcc.hy.phoenix.annotation.validator;
import com.cmcc.hy.phoenix.annotation.UserId;
import com.google.common.collect.Sets;
import java.util.Set;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
/**
*
*
* @author phoenix
* @date 2020年2月8日
*/
public class UserIdValidator implements ConstraintValidator<UserId, Long> {
/**
* 快速失败模式下这里无法注入依赖 参数校验的数据源相关校验放到controller里 方法抽象到下层service中
*/
@Override
public boolean isValid(Long aLong, ConstraintValidatorContext constraintValidatorContext) {
if (aLong == null) {
return false;
}
return existsById(aLong);
}
private Set<Long> idSet = Sets.newHashSet(1L, 2L);
private boolean existsById(long aId) {
return idSet.contains(aId);
}
}

View File

@ -0,0 +1,59 @@
package com.cmcc.hy.phoenix.aop;
import java.lang.reflect.Method;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import lombok.extern.slf4j.Slf4j;
/**
* AOP切面
*
* @author phoenix
* @date 2020年2月4日
*/
@Aspect
@Component
@Slf4j
public class MyInterceptor {
public static final String EXEC = "execution(* com.cmcc.hy.phoenix.controller.*.*(..))"
+ "&& !execution(* com.cmcc.hy.phoenix.controller.*.get*(..))"
+ "&& !execution(* com.cmcc.hy.phoenix.controller.*.set*(..))";
/**
*
*/
@Pointcut(EXEC)
public void interceptor() {
}
/**
*
* @param point
* @return
* @throws Throwable
*/
@SuppressWarnings("unused")
@Around("interceptor()")
public Object doAround(ProceedingJoinPoint point) throws Throwable {
Method method = ((MethodSignature) point.getSignature()).getMethod();
log.info("方法:" + method.getName());
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
.getRequest();
HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
.getResponse();
return point.proceed();
}
}

View File

@ -0,0 +1,110 @@
package com.cmcc.hy.phoenix.aop;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import javax.annotation.Resource;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice;
import com.cmcc.aqb.enc.dec.AesECB;
import com.cmcc.hy.phoenix.annotation.bodyencdec.ReqDec;
import com.cmcc.hy.phoenix.config.MyConfig;
import lombok.extern.slf4j.Slf4j;
/**
*
*
* @author phoenix
* @date 2020年2月10日
*/
@Slf4j
@ControllerAdvice(basePackages = { "com.cmcc.hy.phoenix.controller" })
public class MyRequestBodyAdvice implements RequestBodyAdvice {
@Resource
private MyConfig myConfig;
@Override
public boolean supports(MethodParameter methodParameter, Type targetType,
Class<? extends HttpMessageConverter<?>> converterType) {
// TODO Auto-generated method stub
return Boolean.parseBoolean(myConfig.getRequestDecSwitch());
}
@Override
public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType,
Class<? extends HttpMessageConverter<?>> converterType) throws IOException {
// TODO Auto-generated method stub
if (parameter.hasMethodAnnotation(ReqDec.class)) {
try {
return decBody(inputMessage);
} catch (Exception e) {
log.error("报文解密异常", e);
throw new RuntimeException(e);
}
}
return inputMessage;
}
private HttpInputMessage decBody(HttpInputMessage inputMessage) throws Exception {
String enc = IOUtils.toString(inputMessage.getBody(), StandardCharsets.UTF_8);
log.info("接收密文: {}", enc);
String plain = new String(AesECB.decByAes(Base64.decodeBase64(enc), myConfig.getAesKey()));
log.info("解密明文: {}", plain);
InputStream is = IOUtils.toInputStream(plain, "UTF-8");
return new MyHttpInputMessage(inputMessage.getHeaders(), is);
}
@Override
public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType,
Class<? extends HttpMessageConverter<?>> converterType) {
// TODO Auto-generated method stub
log.info("RequestBodyAdvice afterBodyRead body {}", body);
return body;
}
@Override
public Object handleEmptyBody(Object body, HttpInputMessage inputMessage, MethodParameter parameter,
Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
// TODO Auto-generated method stub
log.info("RequestBodyAdvice handleEmptyBody body {}", body);
return body;
}
}
class MyHttpInputMessage implements HttpInputMessage {
private HttpHeaders headers;
private InputStream body;
public MyHttpInputMessage(HttpHeaders headers, InputStream body) throws Exception {
this.headers = headers;
this.body = body;
}
@Override
public HttpHeaders getHeaders() {
// TODO Auto-generated method stub
return headers;
}
@Override
public InputStream getBody() throws IOException {
// TODO Auto-generated method stub
return body;
}
}

View File

@ -0,0 +1,71 @@
package com.cmcc.hy.phoenix.aop;
import java.nio.charset.StandardCharsets;
import javax.annotation.Resource;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import com.cmcc.aqb.enc.dec.AesECB;
import com.cmcc.hy.phoenix.annotation.bodyencdec.RespEnc;
import com.cmcc.hy.phoenix.config.MyConfig;
import com.cmcc.hy.phoenix.vo.MyResp;
import com.cmcc.hy.phoenix.vo.Resp;
import lombok.extern.slf4j.Slf4j;
/**
*
*
* @author phoenix
* @date 2020年2月10日
*/
@Slf4j
@ControllerAdvice(basePackages = { "com.cmcc.hy.phoenix.controller" })
public class MyResponseBodyAdvice implements ResponseBodyAdvice<Object> {
@Resource
private MyConfig myConfig;
@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
// TODO Auto-generated method stub
return returnType.hasMethodAnnotation(RespEnc.class) && Boolean.parseBoolean(myConfig.getResponseEncSwitch());
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request,
ServerHttpResponse response) {
// TODO Auto-generated method stub
if (body != null) {
try {
MyResp resp = (MyResp) body;
String data = (String) resp.getData();
if (StringUtils.isNotEmpty(data)) {
String newData = Base64.encodeBase64String(
AesECB.encByAes(data.getBytes(StandardCharsets.UTF_8), myConfig.getAesKey()));
resp.setData(newData);
return resp;
} else {
if (Resp.SUCCESS.getCode() != resp.getCode()) {
return resp;
}
}
} catch (Exception e) {
log.error("response数据加密异常", e);
return MyResp.result(Resp.ERROR);
}
}
return body;
}
}

View File

@ -0,0 +1,38 @@
package com.cmcc.hy.phoenix.aop.cache;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
*
* 在数据更新删除情况下先删除缓存
*
* @author phoenix
* @date 2020年2月25日
*/
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface CacheDel {
/**
* 什么对象
*
* @Description: TODO(这里用一句话描述这个方法的作用)
* @return
*/
Class<?> clazz();
/**
*
* @Description: TODO(这里用一句话描述这个方法的作用)
* @return
*/
String[] key() default {};
}

View File

@ -0,0 +1,47 @@
package com.cmcc.hy.phoenix.aop.cache;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
*
* 先从缓存读取读不到走数据层读取并存入缓存
*
* @author phoenix
* @date 2020年2月25日
*/
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface CacheGet {
/**
* 缓存的有效期默认300秒
*
* @Description:
* @return
*/
int ttl() default 300;
/**
*
* @Description: TODO(这里用一句话描述这个方法的作用)
* @return
*/
String[] key();
/**
* 是否缓存空值防止缓存穿透使用
* 慎用
* 如果使用了空缓存而不使用CachePut则数据影响周期就是ttl时间
* @Description: TODO(这里用一句话描述这个方法的作用)
* @return
*/
boolean cacheNull() default false;
}

View File

@ -0,0 +1,38 @@
package com.cmcc.hy.phoenix.aop.cache;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
*
* 新增数据直接设置缓存目的适合缓存穿透结合使用
* 减少空缓存影响时间
* @author phoenix
* @date 2020年2月25日
*/
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface CachePut {
/**
* 缓存的有效期默认300秒
*
* @Description:
* @return
*/
int ttl() default 300;
/**
*
* @Description: TODO(这里用一句话描述这个方法的作用)
* @return
*/
String[] key() default {};
}

View File

@ -0,0 +1,28 @@
package com.cmcc.hy.phoenix.aop.cache;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 某些方法需要组合注解的用这个注解标注
*
* @author phoenix
* @date 2020年3月4日
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface MyCache {
CachePut[] put() default {};//保存数据同时设置多个key缓存
//CacheGet[] get() default {};
CacheDel[] del() default {};//删除对象需要删除该对象的所有缓存数据
}

View File

@ -0,0 +1,221 @@
package com.cmcc.hy.phoenix.aop.cache;
import java.io.Serializable;
import java.lang.reflect.Method;
import javax.annotation.Resource;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;
import com.cmcc.hy.phoenix.common.Utils;
import com.cmcc.hy.phoenix.redis.RedisClient;
import lombok.extern.slf4j.Slf4j;
/**
* 自定义封装manager缓存统一管理 TODO 未完待续
*
* @author phoenix
* @date 2020年2月10日
*/
@Aspect
@Component
@Slf4j
public class MyCacheInterceptor {
public static final String EXEC = "execution(* com.cmcc.hy.phoenix.manager.*.* (..))";
// + "&& !execution(* com.cmcc.hy.phoenix.manager.impl.*.get*(..))"
// + "&& !execution(* com.cmcc.hy.phoenix.manager.impl.*.set*(..))";
/**
* 缓存key分隔符
*/
public static final String SPILIT = "#";
/**
* 系统统一缓存key前缀
*/
public static final String CACHE_PREFIX = "PHOENIX_IC" + SPILIT;
private static ExpressionParser parser = new SpelExpressionParser();
// SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
public static final String CACHE_NULL = "NULL";
@Resource
private RedisClient redisClient;
/**
*
*/
@Pointcut(EXEC)
public void cache() {
}
/**
* 切记这三个缓存注解不可同时在一个方法上使用 如果出现一定是你的业务设计有问题
*
* @数据操作可归结为 CRUD 操作增加读取更新删除
* @组合操作 MyCache
* @增加可能需要CachePut
* @读取可能需要CacheGet
* @更新可能需要CacheDel 这里不要加CachePut简化操作简单就是高效
* @删除可能需要CacheDel
*
* @param point
* @return
* @throws Throwable
*/
@Around("cache()")
public Object doAround(ProceedingJoinPoint point) throws Throwable {
Method method = ((MethodSignature) point.getSignature()).getMethod();
log.info("CACHE拦截方法" + point.getSignature().getName());
MyCache mc = method.getAnnotation(MyCache.class);
if (mc != null) {
Object obj = point.proceed();
if((int)obj > 0) {
//说明增删改操作有实际数据生效
log.info("方法 {} 检查到注解 @MyCache",method.getName());
CachePut[] puts = mc.put();
if (ArrayUtils.isNotEmpty(puts)) {
log.info("方法 {} 检查到组合注解 @CachePut",method.getName());
for (int i = 0; i < puts.length; i++) {
putHandle(point, puts[i]);
}
}
CacheDel[] dels = mc.del();
if (ArrayUtils.isNotEmpty(dels)) {
log.info("方法 {} 检查到组合注解 @CacheDel",method.getName());
for (int i = 0; i < dels.length; i++) {
delHandle(point, dels[i]);
}
}
return obj;
}else {
log.info("方法 {} 未实际产生数据影响",method.getName());
}
} else {
CacheGet get = method.getAnnotation(CacheGet.class);
if (get != null) {
log.info("方法 {} 检查到独立注解 @CacheGet",method.getName());
return getHandle(point, get);
}
Object obj = point.proceed();
CachePut put = method.getAnnotation(CachePut.class);
if (put != null) {
log.info("方法 {} 检查到独立注解 @CachePut",method.getName());
if((int)obj > 0) {
putHandle(point, put);
}
}
CacheDel del = method.getAnnotation(CacheDel.class);
if (del != null) {
log.info("方法 {} 检查到独立注解 @CacheDel",method.getName());
if((int)obj > 0) {
delHandle(point, del);
}
}
return obj;
}
return point.proceed();
}
@SuppressWarnings("unchecked")
private void putHandle(ProceedingJoinPoint point, CachePut put) throws Throwable {
log.info("CachePut操作");
Method method = ((MethodSignature) point.getSignature()).getMethod();
Class<? extends Serializable>[] clazz = (Class<? extends Serializable>[]) method.getParameterTypes();
String[] keys = put.key();
String key = genKey(point, clazz[0], keys);
log.info("key = " + key);
Object[] obj = point.getArgs();
if (ObjectUtils.isEmpty(obj[0])) {
log.warn("参数为NULL不要使用CachePut注解");
} else {
redisClient.put(key, clazz[0].cast(obj[0]), Utils.randomTTL(put.ttl()));
log.info("设置缓存 {}", key);
}
}
private void delHandle(ProceedingJoinPoint point, CacheDel del) throws Throwable {
// 说明要删除缓存
log.info("CacheDel操作");
String[] keys = del.key();
String key = genKey(point, del.clazz(), keys);
log.info("key = " + key);
redisClient.del(key);
log.info("缓存清空 {}", key);
// point.proceed();
}
@SuppressWarnings("unchecked")
private Object getHandle(ProceedingJoinPoint point, CacheGet get) throws Throwable {
// 说明是读数据操作优先读取缓存
log.info("CacheGet操作");
Method method = ((MethodSignature) point.getSignature()).getMethod();
Class<? extends Serializable> clazz = (Class<? extends Serializable>) method.getReturnType();
String key = genKey(point, clazz, get.key());
log.info("key = " + key);
int ttl = Utils.randomTTL(get.ttl());
Object obj = redisClient.get(key, clazz);
if (ObjectUtils.isEmpty(obj)) {
log.info("缓存查询为空");
obj = point.proceed();
if (ObjectUtils.isNotEmpty(obj)) {
log.info("数据库查询到数据 {}", obj);
redisClient.put(key, clazz.cast(obj), ttl);
log.info("成功将数据存入缓存");
} else {
log.info("数据库查询依然为空");
// 开启防缓存穿透设置空缓存
if (get.cacheNull()) {
redisClient.put(key, CACHE_NULL, ttl);
log.info("设置空缓存,防缓存穿透");
}
}
} else if (CACHE_NULL.equals(obj)) {
// 缓存查询对象不为空,判断是否是空缓存
obj = null;
}
return obj;
}
private String genKey(ProceedingJoinPoint point, Class<?> clazz, String[] keys) {
StringBuilder sb = new StringBuilder();
String clazzName = clazz.getSimpleName();
sb.append(CACHE_PREFIX).append(clazzName);
EvaluationContext context = getContext(point.getArgs(), point);
for (int i = 0; i < keys.length; i++) {
sb.append(SPILIT).append(getValue(context, keys[i], String.class));
}
return sb.toString();
}
private <T> T getValue(EvaluationContext context, String key, Class<T> clazz) {
Expression expression = parser.parseExpression(key);
return expression.getValue(context, clazz);
}
private EvaluationContext getContext(Object[] arguments, ProceedingJoinPoint point) {
String[] parameterNames = new LocalVariableTableParameterNameDiscoverer()
.getParameterNames(((MethodSignature) point.getSignature()).getMethod());
if (parameterNames == null) {
throw new RuntimeException("参数列表不能为null");
}
EvaluationContext context = new StandardEvaluationContext();
for (int i = 0; i < arguments.length; i++) {
context.setVariable(parameterNames[i], arguments[i]);
}
return context;
}
}

View File

@ -0,0 +1,152 @@
package com.cmcc.hy.phoenix.common;
import org.joda.time.DateTime;
import org.joda.time.Period;
import org.joda.time.format.DateTimeFormat;
import java.util.Calendar;
import java.util.Date;
/**
* 日期常用工具方法
*
* @author phoenix
* @date 2020年2月4日
*/
public class DateUtil {
public final static String YYYYMMWITHSYMBOL = "yyyy-MM";
public final static String YYYYMMDDWITHSYMBOL = "yyyy-MM-dd";
public final static String MMDD = "MM-dd";
public final static String MMDDHHMMSS = "MMddhhmmss";
public final static String YYYYMMDDHHMMSSSSS = "yyyyMMddHHmmssSSS";
public final static String YYYYMMDDHHMMSSWITHSYMBOL = "yyyy-MM-dd HH:mm:ss";
public final static String YYYYMMDDHHMMSSSSSWITHSYMBOL = "yyyy-MM-dd HH:mm:ss:SSS";
public final static String YYYYMMDDHHMMWITHSYMBOL = "yyyy-MM-dd HH:mm";
public final static String MMDDYYYYHHMMSSWITHSYMBOL = "MM/dd/yyyy hh:mm:ss a";
private static Calendar calendar = Calendar.getInstance();
/**
*
* @param strTime
* @param pattern
* @return
*/
public static Date s2d(String strTime, String pattern) {
DateTime d = DateTimeFormat.forPattern(pattern).parseDateTime(strTime);
return d.toDate();
}
/**
*
* @param date
* @param pattern
* @return
*/
public static String d2s(Date date, String pattern) {
DateTime time = new DateTime(date);
return time.toString(pattern);
}
/**
*
* @return
*/
public static Date getCurrentTime() {
return new Date();
}
/**
*
* @return
*/
public static Date getCurrentDate() {
calendar.setTime(getCurrentTime());
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
return calendar.getTime();
}
/**
*
* @param date
* @param x
* @return
*/
public static Date addXDay(Date date, int x) {
return new DateTime(date).plus(Period.days(x)).toDate();
}
/**
*
* @param date
* @param x
* @return
*/
public static Date addXMonth(Date date, int x) {
return new DateTime(date).plus(Period.months(x)).toDate();
}
/**
*
* @param date
* @param x
* @return
*/
public static Date addXHour(Date date, int x) {
return new DateTime(date).plus(Period.hours(x)).toDate();
}
/**
*
* @param date
* @param x
* @return
*/
public static Date addXMin(Date date, int x) {
return new DateTime(date).plus(Period.minutes(x)).toDate();
}
/**
*
* @param date
* @param x
* @return
*/
public static Date addXSeconds(Date date, int x) {
return new DateTime(date).plus(Period.seconds(x)).toDate();
}
/**
*
* @param now
* @param old
* @param interval
* @return
*/
public static boolean isExpire(Date now, Date old, int interval) {
return addXSeconds(old, interval).before(now);
}
/**
*
* @param begin
* @param end
* @return
*/
public static long getSecondsInterval(Date begin, Date end) {
return (end.getTime() - begin.getTime()) / 1000;
}
}

View File

@ -0,0 +1,279 @@
package com.cmcc.hy.phoenix.common;
import org.apache.oro.text.regex.MalformedPatternException;
import org.apache.oro.text.regex.Pattern;
import org.apache.oro.text.regex.PatternCompiler;
import org.apache.oro.text.regex.PatternMatcher;
import org.apache.oro.text.regex.PatternMatcherInput;
import org.apache.oro.text.regex.Perl5Compiler;
import org.apache.oro.text.regex.Perl5Matcher;
/**
* 常用正则工具
*
* @author phoenix
* @date 2020年2月4日
*/
public class PatternUtil {
private static PatternCompiler compiler = new Perl5Compiler();
private static Pattern urlPattern = null;
private static Pattern ipv6UrlPattern = null;
private static Pattern noProtocolPattern = null;
private static Pattern ipv6NoProtocolPattern = null;
private static Pattern internalIpPattern = null;
private static Pattern ipPattern = null;
private static Pattern portPattern = null;
private static Pattern ipPortPattern = null;
private static Pattern internalIpPortPattern = null;
private static Pattern inputPwdPattern = null;
private static Pattern usernamePattern = null;
private static Pattern msisdnPattern = null;
private static Pattern domainPattern = null;
private static Pattern emailPattern = null;
static {
try {
// [a-zA-Z0-9][-a-zA-Z0-9]{0,62}(.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+.?
// 域名
domainPattern = compiler
.compile("^(?=^.{3,255}$)[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+$");
// http https url
// (http|https)://[A-Za-z0-9_.#:/?&]+$
// (https|http)://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]
// (https?|ftp|file)://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]
// https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)
// 不支持IP地址
// ^(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]
// ^(https|http)://([A-Za-z0-9]{1,}[-A-Za-z0-9+&@#/%?=~_|!:,.]{1,}[A-Za-z0-9]{1,})
// https?:\/\/[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+$ 有协议的
urlPattern = compiler
.compile("https?:\\/\\/[\\w.-]+(?:\\.[\\w\\.-]+)+[\\w\\-\\._~:/?#[\\]!%\\$&'\\(\\)\\*\\+,;=.]+$");
// http url
ipv6UrlPattern = compiler
.compile("https?:\\/\\/\\[([A-Za-z0-9.:]+)\\][\\w\\-\\._~:/?#[\\]!%\\$&'\\(\\)\\*\\+,;=.]*$");
// [-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)
// ^[A-Za-z0-9]{1,}[-A-Za-z0-9+&@#/%?=~_|!:,.]{1,}^.*?(?!://|:/).*?[A-Za-z0-9]{1,}$
// [\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+$
noProtocolPattern = compiler
.compile("[\\w.-]+(?:\\.[\\w\\.-]+)+[\\w\\-\\._~:/?#[\\]@!%\\$&'\\(\\)\\*\\+,;=.]+$");
// ipv6+port
ipv6NoProtocolPattern = compiler
.compile("\\[([A-Za-z0-9.:]+)\\][\\w\\-\\._~:/?#[\\]!%\\$&'\\(\\)\\*\\+,;=.]*$");
// ip
ipPattern = compiler.compile(
"^(25[0-5]|2[0-4][0-9]|1[0-9]{1,2}|[1-9]{1,2}|[1-9][0-9]|0)\\.(25[0-5]|2[0-4][0-9]|1[0-9]{1,2}|[1-9]{1,2}|[1-9][0-9]|0)"
+ "\\.(25[0-5]|2[0-4][0-9]|1[0-9]{1,2}|[1-9]{1,2}|[1-9][0-9]|0)\\.(25[0-5]|2[0-4][0-9]|1[0-9]{1,2}|[1-9]{1,2}|[1-9][0-9]|0)$");
// 内网IP
internalIpPattern = compiler.compile(
"((10\\.(25[0-5]|2[0-4][0-9]|1[0-9]{1,2}|[1-9]{1,2}|[1-9][0-9]|0)\\.(25[0-5]|2[0-4][0-9]|1[0-9]{1,2}|[1-9]{1,2}|[1-9][0-9]|0)"
+ "\\.(25[0-5]|2[0-4][0-9]|1[0-9]{1,2}|[1-9]{1,2}|[1-9][0-9]|0))|(172"
+ "\\.(1[6-9]|2[0-9]|3[0-1])\\.(25[0-5]|2[0-4][0-9]|1[0-9]{1,2}|[1-9]{1,2}|[1-9][0-9]|0)"
+ "\\.(25[0-5]|2[0-4][0-9]|1[0-9]{1,2}|[1-9]{1,2}|[1-9][0-9]|0))|(192"
+ "\\.168\\.(25[0-5]|2[0-4][0-9]|1[0-9]{1,2}|[1-9]{1,2}|[1-9][0-9]|0)"
+ "\\.(25[0-5]|2[0-4][0-9]|1[0-9]{1,2}|[1-9]{1,2}|[1-9][0-9]|0)))");
// 端口 port 1024-65535
portPattern = compiler.compile(
"^(102[4-9]|10[3-9][0-9]|1[1-9][0-9]{2}|[2-9][0-9]{3}|[1-5][0-9]{4}|6[0-4]{4}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$");
// ip port
ipPortPattern = compiler.compile(
"^(25[0-5]|2[0-4][0-9]|1[0-9]{1,2}|[1-9]{1,2}|[1-9][0-9]|0)\\.(25[0-5]|2[0-4][0-9]|1[0-9]{1,2}|[1-9]{1,2}|[1-9][0-9]|0)"
+ "\\.(25[0-5]|2[0-4][0-9]|1[0-9]{1,2}|[1-9]{1,2}|[1-9][0-9]|0)\\.(25[0-5]|2[0-4][0-9]|1[0-9]{1,2}|[1-9]{1,2}|[1-9][0-9]|0)"
+ ":([0-9]{1,4}|[1-5][0-9]{4}|6[0-4]{4}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$");
// 内网 ip port
internalIpPortPattern = compiler.compile(
"^((10\\.(25[0-5]|2[0-4][0-9]|1[0-9]{1,2}|[1-9]{1,2}|[1-9][0-9]|0)\\.(25[0-5]|2[0-4][0-9]|1[0-9]{1,2}|[1-9]{1,2}|[1-9][0-9]|0)"
+ "\\.(25[0-5]|2[0-4][0-9]|1[0-9]{1,2}|[1-9]{1,2}|[1-9][0-9]|0))|(172"
+ "\\.(1[6-9]|2[0-9]|3[0-1])\\.(25[0-5]|2[0-4][0-9]|1[0-9]{1,2}|[1-9]{1,2}|[1-9][0-9]|0)"
+ "\\.(25[0-5]|2[0-4][0-9]|1[0-9]{1,2}|[1-9]{1,2}|[1-9][0-9]|0))|(192"
+ "\\.168\\.(25[0-5]|2[0-4][0-9]|1[0-9]{1,2}|[1-9]{1,2}|[1-9][0-9]|0)"
+ "\\.(25[0-5]|2[0-4][0-9]|1[0-9]{1,2}|[1-9]{1,2}|[1-9][0-9]|0)))"
+ ":([0-9]{1,4}|[1-5][0-9]{4}|6[0-4]{4}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$");
inputPwdPattern = compiler
.compile("^(?![0-9]+$)(?![a-zA-Z]+$)(?![~!@#$%^&*()_+]+$)[0-9a-zA-Z~!@#$%^&*()_+]{8,16}$");
// 用户名正则
usernamePattern = compiler.compile("^[0-9a-zA-Z_]{4,16}$");
// 手机号正则
msisdnPattern = compiler.compile("^1[3,4,5,6,7,8,9][0-9]{9}$");
// 邮箱格式
emailPattern = compiler.compile("^[A-Za-z0-9\\u4e00-\\u9fa5_.]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$");
} catch (MalformedPatternException e) {
throw new RuntimeException("正则加载失败", e);
}
}
/**
* 手机号正则校验
*
* @param str
* @return
*/
public static boolean isMsisdn(String str) {
PatternMatcher matcher = new Perl5Matcher();
return matcher.matches(new PatternMatcherInput(str), msisdnPattern);
}
/**
* 邮箱格式正则校验
*
* @param str
* @return
*/
public static boolean isEmail(String str) {
PatternMatcher matcher = new Perl5Matcher();
return matcher.matches(new PatternMatcherInput(str), emailPattern);
}
/**
* 用户名正则
*
* @param str
* @return
*/
public static boolean isUsername(String str) {
PatternMatcher matcher = new Perl5Matcher();
return matcher.matches(new PatternMatcherInput(str), usernamePattern);
}
/**
* url正则判断http https
*
* @param url
* @return
*/
public static boolean isUrl(String url) {
PatternMatcher matcher = new Perl5Matcher();
return matcher.matches(new PatternMatcherInput(url), urlPattern);
}
/**
* ipv6 url
*
* @param url
* @return
*/
public static boolean isIpv6Url(String url) {
PatternMatcher matcher = new Perl5Matcher();
return matcher.matches(new PatternMatcherInput(url), ipv6UrlPattern);
}
/**
* 无协议url正则判断
*
* @param url
* @return
*/
public static boolean isNoProtocolUrl(String url) {
PatternMatcher matcher = new Perl5Matcher();
return matcher.matches(new PatternMatcherInput(url), noProtocolPattern);
}
/**
* 无协议url正则判断
*
* @param url
* @return
*/
public static boolean isIpv6NoProtocolUrl(String url) {
PatternMatcher matcher = new Perl5Matcher();
return matcher.matches(new PatternMatcherInput(url), ipv6NoProtocolPattern);
}
/**
* 域名正则判断http https
*
* @param domainName
* @return
*/
public static boolean idDomainUrl(String domainName) {
PatternMatcher matcher = new Perl5Matcher();
return matcher.matches(new PatternMatcherInput(domainName), domainPattern);
}
/**
* ip正则判断
*
* @param ip
* @return
*/
public static boolean isIp(String ip) {
PatternMatcher matcher = new Perl5Matcher();
return matcher.matches(new PatternMatcherInput(ip), ipPattern);
}
/**
* 私有IP正则
*
* @param ip
* @return
*/
public static boolean isInternalIp(String ip) {
PatternMatcher matcher = new Perl5Matcher();
return matcher.matches(new PatternMatcherInput(ip), internalIpPattern);
}
/**
* 外网IP正则判断
*
* @param ip
* @return
*/
public static boolean isExternalIp(String ip) {
return isIp(ip) && !isInternalIp(ip);
}
/**
* 端口判断1024开始
*
* @param port
* @return
*/
public static boolean isPort(String port) {
PatternMatcher matcher = new Perl5Matcher();
return matcher.matches(new PatternMatcherInput(port), portPattern);
}
/**
* ip端口整体正则判断
*
* @param ipPort
* @return
*/
public static boolean isIpPort(String ipPort) {
PatternMatcher matcher = new Perl5Matcher();
return matcher.matches(new PatternMatcherInput(ipPort), ipPortPattern);
}
/**
* 私有ip端口正则判断
*
* @param internalIpPort
* @return
*/
public static boolean isInternalIpPort(String internalIpPort) {
PatternMatcher matcher = new Perl5Matcher();
return matcher.matches(new PatternMatcherInput(internalIpPort), internalIpPortPattern);
}
/**
* 外网ip端口正则判断
*
* @param externalIpPort
* @return
*/
public static boolean isExternalIpPort(String externalIpPort) {
return isIpPort(externalIpPort) && !isInternalIpPort(externalIpPort);
}
/**
* @param pwd
* @return
*/
public static boolean isPwd(String pwd) {
PatternMatcher matcher = new Perl5Matcher();
return matcher.matches(new PatternMatcherInput(pwd), inputPwdPattern);
}
}

View File

@ -0,0 +1,367 @@
package com.cmcc.hy.phoenix.common;
import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.UUID;
/**
* ClassName:Utils <br/>
* Function: TODO ADD FUNCTION. <br/>
* Reason: TODO ADD REASON. <br/>
* Date: 2016年11月15日 下午2:42:45 <br/>
*
* @author chiwei
* @see
* @since JDK 1.6
*/
@Slf4j
public class Utils {
private static Logger logger = LoggerFactory.getLogger(Utils.class);
private static Random r = new SecureRandom();
/**
* genPwd:(). <br/>
* <p>
* 生成随机密码
*
* @author chiwei
* @param len
* @return
* @since JDK 1.6
*/
private static String letter = "0123456789abcdefjhijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static String base = "ABCDEFGHKMNPRWX2345689defhijkmnpqwxyz";
/**
* @param url
* @return
*/
public static String getHostByUrl(String url) {
try {
URL myUrl = new URL(url);
URI uri = new URI(null, null, myUrl.getHost(), myUrl.getPort(), null, null, null);
return uri.getHost();
} catch (Exception e) {
log.error(url + " 获取domain异常", e);
return null;
}
}
/**
* @param url
* @return
*/
public static String getSchemaHostByUrl(String url) {
try {
URL myUrl = new URL(url);
URI uri = new URI(myUrl.getProtocol(), myUrl.getUserInfo(), myUrl.getHost(), myUrl.getPort(), null, null,
null);
return uri.toString();
} catch (Exception e) {
logger.error(url + " 获取schema host异常", e);
return "";
}
}
/**
* @param domain
* @return
*/
public static List<String> getIpByDomain(String domain) {
List<String> ipList = Lists.newArrayList();
try {
InetAddress[] addresses = InetAddress.getAllByName(domain);
for (int i = 0; i < addresses.length; i++) {
ipList.add(addresses[i].getHostAddress());
}
} catch (Exception e) {
log.error("域名解析IP异常", e);
}
return ipList;
}
/**
* readReqMsg:(). <br/>
*
* @param request
* @return
* @author chiwei
* @since JDK 1.6
*/
public static String readReqMsg(HttpServletRequest request) {
StringBuffer reqMsg = new StringBuffer();
BufferedReader reader;
try {
reader = request.getReader();
String str = "";
while ((str = reader.readLine()) != null) {
reqMsg.append(str);
}
return reqMsg.toString();
} catch (Exception e) {
throw new RuntimeException("请求信息读取有误");
}
}
/**
* filterStr:(). <br/>
* <p>
* 过滤字符串前后空格以及空赋值
*
* @param str
* @return
* @author chiwei
* @since JDK 1.6
*/
public static String filterStr(String str) {
return str = (str == null ? "" : str.trim());
}
/**
* lenOk:(). <br/>
*
* @param str
* @param minLen
* @param maxLen
* @return
* @author chiwei
* @since JDK 1.6
*/
public static boolean lenOk(String str, int minLen, int maxLen) {
return str.length() >= minLen && str.length() <= maxLen;
}
/**
* splitStr2List:(). <br/>
*
* @param str
* @param seperator
* @return
* @author chiwei
* @since JDK 1.6
*/
public static List<String> splitStr2List(String str, String seperator) {
Iterator<String> iter = Splitter.on(seperator).trimResults().omitEmptyStrings().split(str).iterator();
List<String> list = new ArrayList<String>();
while (iter.hasNext()) {
list.add(iter.next());
}
return list;
}
/**
* genRandomNum:(). <br/>
* <p>
* 生成指定长度的随机数字
*
* @param len
* @return
* @author chiwei
* @since JDK 1.6
*/
public static String genRandomNum(int len) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < len; i++) {
sb.append(r.nextInt(10));
}
return sb.toString();
}
/**
* @param len
* @return
*/
public static String genRandomStr(int len) {
StringBuffer sb = new StringBuffer();
int letterLen = letter.length();
for (int i = 0; i < len; i++) {
sb.append(letter.charAt(r.nextInt(letterLen)));
}
return sb.toString();
}
/**
* uuid:(). <br/>
*
* @param len
* @return
* @author chiwei
* @since JDK 1.6
*/
public static String uuid() {
return UUID.randomUUID().toString().replaceAll("-", "");
}
/**
* genRandomHexString:().<br/>
* <p>
* 获取16进制随机数
*
* @param len
* @return
* @author whb
* @since JDK 1.8
*/
public static String genRandomHexString(int len) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < len; i++) {
sb.append(Integer.toHexString(r.nextInt(16)));
}
return sb.toString().toUpperCase();
}
/**
* randomNum:(). <br/>
*
* @param begin
* @param end
* @return
* @author chiwei
* @since JDK 1.6
*/
public static int randomNum(int begin, int end) {
return r.nextInt(end - begin) + begin;
}
/**
* genCode:(). <br/>
* <p>
* 图形验证码
*
* @param len
* @return
*/
public static String genCode(int len) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < len; i++) {
sb.append(base.charAt(r.nextInt(base.length() - 1)));
}
return sb.toString();
}
/**
* code:(). <br/>
*
* @param content
* @param out
* @throws Exception
* @author chiwei
* @since JDK 1.6
*/
public static void code(String content, OutputStream out) throws Exception {
int width = 80;
int height = 30;
// 干扰颜色
Color[] interColor = new Color[] { new Color(176, 196, 222), new Color(245, 222, 179), new Color(255, 228, 225),
new Color(192, 192, 192) };
// 字符颜色
Color[] wordColor = new Color[] { new Color(47, 79, 79), new Color(0, 128, 128), new Color(95, 158, 160),
new Color(70, 130, 180), new Color(105, 105, 105) };
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics g = image.getGraphics();
// 背景画图
g.setColor(Color.WHITE);
g.fillRect(0, 0, width, height);
// 边框画图
g.setColor(Color.WHITE);
g.drawRect(1, 1, width - 2, height - 2);
// 干扰画图
for (int i = 0; i < 20; i++) {
int x1 = r.nextInt(width);
int y1 = r.nextInt(height);
int x2 = r.nextInt(width);
int y2 = r.nextInt(height);
g.setColor(interColor[r.nextInt(interColor.length - 1)]);
g.drawLine(x1, y1, x2, y2);
}
Graphics2D g2 = (Graphics2D) g;
Font[] fonts = new Font[] { new Font("宋体", Font.BOLD, 30), new Font("黑体", Font.PLAIN, 30),
new Font("楷体", Font.ITALIC, 30), };
int x = 5;
for (int i = 0; i < content.length(); i++) {
g.setFont(fonts[r.nextInt(fonts.length - 1)]);
g.setColor(wordColor[r.nextInt(wordColor.length - 1)]);
int degree = r.nextInt() % 30;
String ch = String.valueOf(content.charAt(i));
// 设置旋转角度
g2.rotate(degree * Math.PI / 180, x, 5);
g2.drawString(ch, x, randomNum(20, 30));
// 旋转回来
g2.rotate(-degree * Math.PI / 180, x, 5);
x += randomNum(15, 20);
}
ImageIO.write(image, "jpg", out);
out.flush();
out.close();
}
/**
* @param str
* @return
*/
private static boolean urlIsReachable(String str) {
URL url = null;
try {
url = new URL(str);
URLConnection co = url.openConnection();
co.setConnectTimeout(1000);
co.connect();
return true;
} catch (Exception e) {
logger.error("URL " + str + " 不可达", e);
return false;
}
}
/**
* @param url url
* @return urlIsReachable
*/
public static boolean checkFgUrl(String url) {
if (!urlIsReachable(url)) {
return urlIsReachable(url);
}
return true;
}
/**
* 防止缓存雪崩随机过期时间
* @Description: TODO(这里用一句话描述这个方法的作用)
* @param ttl
* @return
*/
public static int randomTTL(int ttl) {
return ttl+randomNum(0, ttl);
}
public static void main(String[] args) {
for (int i = 0; i < 1; i++) {
System.out.println(genRandomStr(64));
}
}
}

View File

@ -0,0 +1,28 @@
package com.cmcc.hy.phoenix.common;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import org.hibernate.validator.HibernateValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
*
*
* @author phoenix
* @date 2020年2月8日
*/
@Configuration
public class ValidationConfig {
@Bean
public Validator validator() {
ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class).configure().failFast(true)
.buildValidatorFactory();
Validator validator = validatorFactory.getValidator();
return validator;
}
}

View File

@ -0,0 +1,30 @@
package com.cmcc.hy.phoenix.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import lombok.Getter;
import lombok.Setter;
/**
* 自定义配置
*
* @author phoenix
* @date 2020年2月8日
*/
@Getter
@Setter
@Component
@ConfigurationProperties(prefix = "phoenix")
public class MyConfig {
private String systemName;
private String swaggerSwitch;
private String redisServer;
private String requestDecSwitch;
private String responseEncSwitch;
private String aesKey;
private String redisRedissonSentinelMasterName;
private String redisRedissonPwd;
}

View File

@ -0,0 +1,35 @@
package com.cmcc.hy.phoenix.controller;
import com.cmcc.hy.phoenix.pojo.Save;
import com.cmcc.hy.phoenix.pojo.Update;
import com.cmcc.hy.phoenix.pojo.dto.DemoDTO;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
/**
*
*
* @author phoenix
* @date 2020年2月8日
*/
@RestController
public class DemoController {
/**
* @Validated中group定义验证边界Save说明只验证DemoDTO中的username和age
* @see com.cmcc.hy.phoenix.controller.IDemoController#save(com.cmcc.hy.phoenix.pojo.dto.DemoDTO)
*/
@PostMapping("/demo")
public DemoDTO save(@RequestBody @Validated({ Save.class }) DemoDTO demoDTO) {
return demoDTO;
}
@PutMapping("/demo")
public DemoDTO update(@RequestBody @Validated({ Update.class }) DemoDTO demoDTO) {
return demoDTO;
}
}

View File

@ -0,0 +1,87 @@
package com.cmcc.hy.phoenix.controller;
import javax.annotation.Resource;
import com.cmcc.hy.phoenix.help.GitInformation;
import com.cmcc.hy.phoenix.pojo.dto.ProtocolDTO;
import com.cmcc.hy.phoenix.vo.GetVersion;
import com.cmcc.hy.phoenix.vo.ProtocolResp;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Builder;
import org.apache.axis2.databinding.utils.BeanUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import com.cmcc.hy.phoenix.annotation.bodyencdec.ReqDec;
import com.cmcc.hy.phoenix.service.AsyncService;
import com.cmcc.hy.phoenix.service.UserService;
import com.cmcc.hy.phoenix.vo.Resp;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
/**
* 通信协议控制器定义
*/
@Controller
@RequestMapping(value = "/dispose")
@Slf4j
@Api(value = "抗DDoS处置平台接口", tags = "抗DDoS处置平台接口")
@Component
@PropertySource("classpath:git.properties")
public class ProtocolController {
@Resource
private AsyncService asyncService;
@Resource
private UserService userService;
@Resource
private ObjectMapper objectMapper;
@Resource
private GitInformation gitInfo;
/**
*
* @return
*/
@PostMapping("/version")
@ResponseBody
@ApiOperation("获取版本信息")
@ReqDec
@Builder
public ProtocolResp GetVersion(@RequestBody(required = true) ProtocolDTO mr) {
String msgCtx;
log.info("请求参数 {}", mr);
if(mr == null) {
return ProtocolResp.result(Resp.PARAM_ERROR);
}
try {
GetVersion ver = GetVersion.builder().commit_id(gitInfo.getCommit_id())
.commit_describe(gitInfo.getCommit_describe())
.commit_time(gitInfo.getCommit_time())
.tag_name(gitInfo.getTag_name())
.tags(gitInfo.getTags())
.build();
msgCtx = objectMapper.writeValueAsString(ver);
} catch (JsonProcessingException ex) {
log.error(ex.getMessage());
return ProtocolResp.result(Resp.SYSTEM_ERROR);
}
return ProtocolResp.builder().cmdId(mr.getCmdId())
.ver(mr.getVer())
.cryptoType(mr.getCryptoType())
.timeStamp(System.currentTimeMillis())
.code(Resp.SUCCESS.getCode())
.msgContent(new String[] {msgCtx}).build();
}
}

View File

@ -0,0 +1,92 @@
package com.cmcc.hy.phoenix.controller;
import javax.annotation.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.cmcc.hy.phoenix.annotation.bodyencdec.ReqDec;
import com.cmcc.hy.phoenix.annotation.bodyencdec.RespEnc;
import com.cmcc.hy.phoenix.pojo.dto.MyReqDTO;
import com.cmcc.hy.phoenix.service.AsyncService;
import com.cmcc.hy.phoenix.service.UserService;
import com.cmcc.hy.phoenix.vo.MyResp;
import com.cmcc.hy.phoenix.vo.Resp;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
/**
* 对外服务定义
*
* @author phoenix
* @date 2020年2月4日
*/
@Controller
@RequestMapping(value = "/test")
@Slf4j
@Api(value = "测试控制器", tags = "测试控制器接口说明")
public class TestController {
@Resource
private AsyncService asyncService;
@Resource
private UserService userService;
/**
*
* @return
*/
@PostMapping("/post")
@ResponseBody
@ApiOperation("postTest测试实体参数请求接口")
@ReqDec
public MyResp postTest(@RequestBody(required = false) MyReqDTO mr) {
log.info("请求参数 {}", mr);
if(mr == null) {
return MyResp.result(Resp.PARAM_ERROR);
}
return MyResp.result(Resp.SUCCESS);
}
/**
*
* @return
*/
@GetMapping("/ok/{id}")
@ResponseBody
@RespEnc
public MyResp okTest(@PathVariable long id) {
return MyResp.builder().data(userService.testService(id)).code(Resp.SUCCESS.getCode()).msg(Resp.SUCCESS.getMsg())
.build();
}
/**
*
* @return
*/
@GetMapping("/mail")
@ResponseBody
public MyResp sendMail() {
asyncService.sendMail("这是邮件内容");
log.info("记住我的线程名 {},和实际发送的线程名不一样", Thread.currentThread().getName());
return MyResp.result(Resp.SUCCESS);
}
/**
*
* @return
*/
@GetMapping("/exception")
public MyResp exception() {
throw new RuntimeException("抛出异常");
}
}

View File

@ -0,0 +1,64 @@
package com.cmcc.hy.phoenix.exception;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingPathVariableException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import com.cmcc.hy.phoenix.vo.MyResp;
import com.cmcc.hy.phoenix.vo.Resp;
import lombok.extern.slf4j.Slf4j;
/**
* 全局异常处理
*
* @author phoenix
* @date 2020年2月5日
*/
@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
@ExceptionHandler(Throwable.class)
@ResponseBody
public MyResp handleException(HttpServletRequest request, Throwable e) {
log.error("进入全局异常处理", e);
Map<String, Object> map = new HashMap<>(2);
map.put("url", request.getRequestURL().toString());
map.put("exception", ExceptionUtils.getMessage(e));
return MyResp.builder().code(Resp.ERROR.getCode()).msg(Resp.ERROR.getMsg()).data(map).build();
}
@ExceptionHandler(Exception.class)
@ResponseBody
public MyResp paramException(HttpServletRequest request, Exception e) {
log.error("进入参数校验异常处理", e);
StringBuffer errorMsg = new StringBuffer();
if (e instanceof ConstraintViolationException) {
Set<ConstraintViolation<?>> cves = ((ConstraintViolationException) e).getConstraintViolations();
cves.forEach(ex -> errorMsg.append(ex.getMessage()));
} else if (e instanceof MissingPathVariableException) {
errorMsg.append("请检查参数 " + ((MissingPathVariableException) e).getVariableName());
} else if (e instanceof MethodArgumentNotValidException) {
errorMsg.append(
((MethodArgumentNotValidException) e).getBindingResult().getAllErrors().get(0).getDefaultMessage());
} else {
log.error("请求异常", e);
errorMsg.append("参数异常");
}
return MyResp.builder().code(Resp.PARAM_ERROR.getCode()).msg(errorMsg.toString()).build();
}
}

View File

@ -0,0 +1,24 @@
package com.cmcc.hy.phoenix.help;
import lombok.Getter;
import lombok.Setter;
import org.springframework.context.annotation.PropertySource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Getter
@Setter
@Component
@PropertySource("classpath:git.properties")
public class GitInformation {
@Value("${git.commit.id}")
private String commit_id;
@Value("${git.commit.id.describe}")
private String commit_describe;
@Value("${git.commit.time}")
private String commit_time;
@Value("${git.closest.tag.name}")
private String tag_name;
@Value("${git.tags}")
private String tags;
}

View File

@ -0,0 +1,63 @@
package com.cmcc.hy.phoenix.manager;
import com.cmcc.hy.phoenix.pojo.entity.InfoCollection;
import com.cmcc.hy.phoenix.pojo.entity.User;
/**
* 系统在15张数据表规模以下的建议整个工程就一个manager 项目主程负责编写这个接口掌握整个系统的数据逻辑操作
*
* @author phoenix
* @date 2020年2月8日
*/
public interface GlobalManager {
/**
*
* @Description: 整个工程会有多个service需要这个方法
* @param id
* @return
*/
public User findUserById(long id);
/**
*
* @Description: TODO(这里用一句话描述这个方法的作用)
* @param phone
* @param productType
* @return
*/
public int deleteIcByPhoneAndPt(String phone, String productType);
/**
*
* @Description: TODO(这里用一句话描述这个方法的作用)
* @return
*/
public int deleteAllIc();
/**
*
* @Description: TODO(这里用一句话描述这个方法的作用)
* @param ic
* @return
*/
public int saveInfoCollection(InfoCollection ic);
/**
*
* @Description: TODO(这里用一句话描述这个方法的作用)
* @param phone
* @param productType
* @return
*/
public InfoCollection findIcByPhoneAndProductType(String phone, String productType);
/**
*
* @Description: TODO(这里用一句话描述这个方法的作用)
* @param id
* @return
*/
public InfoCollection findIcById(long id);
}

View File

@ -0,0 +1,108 @@
package com.cmcc.hy.phoenix.manager.impl;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.stereotype.Component;
import com.cmcc.hy.phoenix.aop.cache.CacheDel;
import com.cmcc.hy.phoenix.aop.cache.CacheGet;
import com.cmcc.hy.phoenix.aop.cache.CachePut;
import com.cmcc.hy.phoenix.aop.cache.MyCache;
import com.cmcc.hy.phoenix.manager.GlobalManager;
import com.cmcc.hy.phoenix.mapper.InfoCollectionMapper;
import com.cmcc.hy.phoenix.mapper.UserMapper;
import com.cmcc.hy.phoenix.pojo.entity.InfoCollection;
import com.cmcc.hy.phoenix.pojo.entity.User;
import com.cmcc.hy.phoenix.redis.RedisClient;
import cn.hutool.core.collection.CollectionUtil;
import lombok.extern.slf4j.Slf4j;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.entity.Example.Criteria;
/**
* 此类依赖所有DAO以及redisClient 数据缓存也在这里外部系统调用也在这里
*
* @author phoenix
* @date 2020年2月8日
*/
@Component
@Slf4j
public class GlobalManagerImpl implements GlobalManager {
@Resource
private UserMapper userMapper;
@Resource
private InfoCollectionMapper infoCollectionMapper;
@Resource
private RedisClient redisClient;
@Override
public User findUserById(long id) {
// TODO Auto-generated method stub
// 封装DAO
User user = userMapper.selectByPrimaryKey(id);
log.info("manager层出查询出用户信息 {}", user);
redisClient.put("test", "mocktest", 100);
return user;
}
@CacheDel(clazz = InfoCollection.class, key = { "#phone", "#productType" })
@Override
public int deleteIcByPhoneAndPt(String phone, String productType) {
// TODO Auto-generated method stub
Example example = new Example(InfoCollection.class);
Criteria c = example.createCriteria();
c.andEqualTo("phoneNumber", phone);
c.andEqualTo("productType", productType);
return infoCollectionMapper.deleteByExample(example);
}
@Override
public int deleteAllIc() {
// TODO Auto-generated method stub
List<InfoCollection> list = infoCollectionMapper.selectAll();
list.forEach((ic)->infoCollectionMapper.delete(ic));
return list.size();
}
/**
* 这里key的设置需要查看该对象的查询方法的key设置保持key全覆盖
*
* @see com.cmcc.hy.phoenix.manager.GlobalManager#saveInfoCollection(com.cmcc.hy.phoenix.pojo.entity.InfoCollection)
*/
@MyCache(put = { @CachePut(key = "#ic.id"), @CachePut(key = { "#ic.phoneNumber", "#ic.productType" }) })
@Override
public int saveInfoCollection(InfoCollection ic) {
// TODO Auto-generated method stub
return infoCollectionMapper.insert(ic);
}
@CacheGet(key = {"#phone","#productType"})
@Override
public InfoCollection findIcByPhoneAndProductType(String phone, String productType) {
// TODO Auto-generated method stub
log.info("根据手机号,产品类型查询用户信息");
Example example = new Example(InfoCollection.class);
Criteria c = example.createCriteria();
c.andEqualTo("phoneNumber", phone);
c.andEqualTo("productType", productType);
List<InfoCollection> list = infoCollectionMapper.selectByExample(example);
if (CollectionUtil.isNotEmpty(list)) {
return list.get(0);
}
return null;
}
@CacheGet(key = "#id")
@Override
public InfoCollection findIcById(long id) {
log.info("根据ID查询用户信息");
return infoCollectionMapper.selectByPrimaryKey(id);
}
}

View File

@ -0,0 +1,10 @@
package com.cmcc.hy.phoenix.mapper;
import com.cmcc.hy.phoenix.pojo.entity.InfoCollection;
import tk.mybatis.mapper.common.Mapper;
import tk.mybatis.mapper.common.MySqlMapper;
public interface InfoCollectionMapper extends Mapper<InfoCollection>, MySqlMapper<InfoCollection> {
}

View File

@ -0,0 +1,28 @@
package com.cmcc.hy.phoenix.mapper;
import com.cmcc.hy.phoenix.pojo.entity.User;
import tk.mybatis.mapper.common.IdsMapper;
import tk.mybatis.mapper.common.Mapper;
import tk.mybatis.mapper.common.MySqlMapper;
/**
* <p>
* User Mapper
* </p>
*
* @description: User Mapper
* @author phoenix
* @date 2020年2月8日
*/
public interface UserMapper extends Mapper<User>,IdsMapper<User>,MySqlMapper<User> {
/**
* 根据用户名统计假设它是一个很复杂的SQL
*
* @param name 用户名
* @return 统计结果
*/
int countByName(String name);
}

View File

@ -0,0 +1,10 @@
package com.cmcc.hy.phoenix.pojo;
/**
*
*
* @author phoenix
* @date 2020年2月8日
*/
public interface Save {
}

View File

@ -0,0 +1,10 @@
package com.cmcc.hy.phoenix.pojo;
/**
*
*
* @author phoenix
* @date 2020年2月8日
*/
public interface Update {
}

View File

@ -0,0 +1,42 @@
package com.cmcc.hy.phoenix.pojo.dto;
import com.cmcc.hy.phoenix.annotation.UserId;
import com.cmcc.hy.phoenix.pojo.Save;
import com.cmcc.hy.phoenix.pojo.Update;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
/**
*
*
* @author phoenix
* @date 2020年2月8日
*/
@Getter
@Setter
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class DemoDTO {
@UserId(groups = { Update.class })
private Long id;
@NotBlank(message = "username 不能为空", groups = { Save.class, Update.class })
private String username;
@Min(value = 0, message = "age 在必须 0 - 150 之间", groups = { Save.class, Update.class })
@Max(value = 150, message = "age 在必须 0 - 150 之间", groups = { Save.class, Update.class })
private Integer age;
}

View File

@ -0,0 +1,30 @@
package com.cmcc.hy.phoenix.pojo.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
/**
* 请求参数实体
*
* @author phoenix
* @date 2020年2月4日
*/
@Getter
@Setter
@ToString
@Builder
@ApiModel("MyReq请求参数实体")
public class MyReqDTO {
@ApiModelProperty("MyReq的id参数")
private Long id;
@ApiModelProperty("MyReq的type参数")
private Integer type;
@ApiModelProperty("MyReq的msg参数")
private String msg;
}

View File

@ -0,0 +1,52 @@
package com.cmcc.hy.phoenix.pojo.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
/**
* 通信协议定义
*/
@Getter
@Setter
@ToString
@Builder
@ApiModel("通信协议实体")
public class ProtocolDTO {
@ApiModelProperty(value="命令编号(必要字段): \n" +
"0-9999范围为请求命令\n" +
"10000-19999 范围为对应请求的响应命令\n" +
"响应命令值为10000+请求命令值\n", required = true,
allowableValues = "rang[0, 19999]",
example = "1")
private int cmdId;
@ApiModelProperty(value="协议版本号", required = true, example = "1")
private int ver;
@ApiModelProperty(value="msgContent字段内容编码格式\n" +
"0无编码格式普通字符串\n" +
"1base64编码格式\n" +
"2采用AES加密后的base64编码格式\n", required = true,
allowableValues = "0, 1, 2",
example = "0")
private int cryptoType;
@ApiModelProperty(value="当前UTC时间戳", required = true, example = "1526625689000")
private Long timeStamp;
@ApiModelProperty(value="协议详细内容Json字符串格式。\n" +
"保存该cmdId命令相关的详细内容\n" +
"具体每个cmdId命令的详细内容参看对应的命令协议定义", required = false,
example = "{}")
private String msgContent;
@ApiModelProperty(value="服务器返回状态码", required = false,
example = "200")
private int code;
}

View File

@ -0,0 +1,42 @@
package com.cmcc.hy.phoenix.pojo.entity;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Id;
import javax.persistence.Table;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import tk.mybatis.mapper.annotation.KeySql;
@Getter
@Setter
@ToString
@Builder
@Table(name = "info_collection")
public class InfoCollection implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@KeySql(useGeneratedKeys = true)
private Long id;
private String username;
private String organization;
private String provinceCode;
private String province;
private String city;
private String district;
private String address;
private String email;
private String phoneNumber;
private String comment;
private String productType;
private Integer syncStatus;
private Date createTime;
private Date updateTime;
}

View File

@ -0,0 +1,86 @@
package com.cmcc.hy.phoenix.pojo.entity;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import tk.mybatis.mapper.annotation.KeySql;
import javax.persistence.Id;
import javax.persistence.Table;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
* 用户实体类
* </p>
*
* @description: 用户实体类
* @author phoenix
* @date 2020年2月8日
*/
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Table(name = "phoenix_user")
public class User implements Serializable {
private static final long serialVersionUID = -1840831686851699943L;
/**
* 主键
*/
@Id
@KeySql(useGeneratedKeys = true)
private Long id;
/**
* 用户名
*/
private String name;
/**
* 加密后的密码
*/
private String password;
/**
* 加密使用的盐
*/
private String salt;
/**
* 邮箱
*/
private String email;
/**
* 手机号码
*/
private String phoneNumber;
/**
* 状态-1逻辑删除0禁用1启用
*/
private Integer status;
/**
* 创建时间
*/
private Date createTime;
/**
* 上次登录时间
*/
private Date lastLoginTime;
/**
* 上次更新时间
*/
private Date lastUpdateTime;
}

View File

@ -0,0 +1,28 @@
package com.cmcc.hy.phoenix.pojo.vo;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
/**
* 前后端交互统一数据格式
*
* @author phoenix
* @date 2020年2月4日
*/
@Getter
@Setter
@ToString
@Builder
public class MyResp {
private int code;
private Object data;
private String msg;
public static MyResp result(Resp resp) {
return MyResp.builder().code(resp.getCode()).msg(resp.getMsg()).build();
}
}

View File

@ -0,0 +1,40 @@
package com.cmcc.hy.phoenix.pojo.vo;
/**
* 后端返回码定义
*
* @author phoenix
* @date 2020年2月4日
*/
public enum Resp {
// 成功返回码
SUCCESS(200, "SUCCESS"),
// 3XX
PARAM_ERROR(300, "自定义参数错误"),
// 4XX
SYSTEM_ERROR(400, "系统内部自定义错误"),
// 5XX
ERROR(500, "服务端系统错误"),
;
private int code;
private String msg;
Resp(int code, String msg) {
this.code = code;
this.msg = msg;
}
public int getCode() {
return code;
}
public String getMsg() {
return msg;
}
}

View File

@ -0,0 +1,84 @@
package com.cmcc.hy.phoenix.redis;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Resource;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.cmcc.hy.phoenix.common.Utils;
import com.cmcc.hy.phoenix.config.MyConfig;
import lombok.extern.slf4j.Slf4j;
import redis.clients.jedis.JedisShardInfo;
import redis.clients.jedis.ShardedJedisPool;
import redis.clients.jedis.util.Hashing;
import redis.clients.jedis.util.Sharded;
/**
*
*
* @author phoenix
* @date 2020年3月10日
*/
@Configuration
@Slf4j
public class MyRedisConfiguration {
@Resource
private MyConfig myConfig;
@SuppressWarnings("rawtypes")
@ConditionalOnProperty(prefix = "phoenix",name = "redis.type",havingValue = "jedis")
@Bean
public ShardedJedisPool shardedJedisPool() {
GenericObjectPoolConfig config = new GenericObjectPoolConfig();
// 连接数配置也可放到外部配置文件去
config.setMaxTotal(128);
config.setMaxIdle(16);
config.setMinIdle(4);
config.setMaxWaitMillis(1000L);
config.setTestWhileIdle(true);
config.setTimeBetweenEvictionRunsMillis(30000L);
config.setMinEvictableIdleTimeMillis(600000L);
config.setNumTestsPerEvictionRun(-1);
config.setJmxEnabled(false);
List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
String[] serverList = myConfig.getRedisServer().split(",", 0);
for (String server : serverList) {
JedisShardInfo jsi = new JedisShardInfo(server);
jsi.setConnectionTimeout(5000);
jsi.setSoTimeout(5000);
shards.add(jsi);
}
log.info("Redis Type = jedis ,initialized success");
return new ShardedJedisPool(config, shards, Hashing.MURMUR_HASH, Sharded.DEFAULT_KEY_TAG_PATTERN);
}
/**
*
* @Description: Redisson哨兵模式实例 具体API操作参照Redisson Github对照表
* https://github.com/redisson/redisson/wiki/11.-Redis%E5%91%BD%E4%BB%A4%E5%92%8CRedisson%E5%AF%B9%E8%B1%A1%E5%8C%B9%E9%85%8D%E5%88%97%E8%A1%A8
* @blog https://blog.csdn.net/unclecoco/article/details/99412915
* @return
*/
@ConditionalOnProperty(prefix = "phoenix",name = "redis.type",havingValue = "redisson")
@Bean
public RedissonClient redisson() {
List<String> servers = Utils.splitStr2List(myConfig.getRedisServer(),",");
Config config = new Config();
String masterName = myConfig.getRedisRedissonSentinelMasterName();
config.useSentinelServers().setMasterName(masterName).setPassword(myConfig.getRedisRedissonPwd())
.addSentinelAddress(servers.toArray(new String[0]));
log.info("Redis Type = redisson ,initialized success");
return Redisson.create(config);
}
}

View File

@ -0,0 +1,104 @@
package com.cmcc.hy.phoenix.redis;
import io.protostuff.LinkedBuffer;
import io.protostuff.ProtostuffIOUtil;
import io.protostuff.Schema;
import io.protostuff.runtime.RuntimeSchema;
import org.objenesis.Objenesis;
import org.objenesis.ObjenesisStd;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
*
*
* @author phoenix
* @date 2020年2月8日
*/
public class ProtobufSerializer {
private static Map<Class<?>, Schema<?>> cachedSchema = new ConcurrentHashMap<Class<?>, Schema<?>>();
private static Objenesis objenesis = new ObjenesisStd(true);
static {
cachedSchema.put(Boolean.class, RuntimeSchema.createFrom(Boolean.class));
cachedSchema.put(Byte.class, RuntimeSchema.createFrom(Byte.class));
cachedSchema.put(Short.class, RuntimeSchema.createFrom(Short.class));
cachedSchema.put(Integer.class, RuntimeSchema.createFrom(Integer.class));
cachedSchema.put(Long.class, RuntimeSchema.createFrom(Long.class));
cachedSchema.put(Float.class, RuntimeSchema.createFrom(Float.class));
cachedSchema.put(Double.class, RuntimeSchema.createFrom(Double.class));
cachedSchema.put(Character.class, RuntimeSchema.createFrom(Character.class));
cachedSchema.put(String.class, RuntimeSchema.createFrom(String.class));
cachedSchema.put(BigInteger.class, RuntimeSchema.createFrom(BigInteger.class));
cachedSchema.put(BigDecimal.class, RuntimeSchema.createFrom(BigDecimal.class));
}
@SuppressWarnings("unchecked")
private static <T> Schema<T> getSchema(Class<T> cls) {
Schema<T> schema = (Schema<T>) cachedSchema.get(cls);
if (schema == null) {
schema = RuntimeSchema.createFrom(cls);
if (schema != null) {
cachedSchema.put(cls, schema);
}
}
return schema;
}
/**
* @param obj
* @return
*/
@SuppressWarnings("unchecked")
public static <T> byte[] serialize(T obj) {
Class<T> cls = (Class<T>) obj.getClass();
LinkedBuffer buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE);
try {
Schema<T> schema = getSchema(cls);
return ProtostuffIOUtil.toByteArray(obj, schema, buffer);
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
buffer.clear();
}
}
/**
* @param bytes
* @return
*/
public static <T> T deserialize(byte[] bytes) {
throw new UnsupportedOperationException();
}
/**
* @param bytes
* @param cls
* @return
*/
public static <T> T deserialize(byte[] bytes, Class<T> cls) {
try {
T message = objenesis.newInstance(cls);
Schema<T> schema = getSchema(cls);
ProtostuffIOUtil.mergeFrom(bytes, message, schema);
return message;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
/**
* Revision history
* -------------------------------------------------------------------------
* <p>
* Date Author Note
* -------------------------------------------------------------------------
* 2016年6月6日 chiwei create
*/

View File

@ -0,0 +1,97 @@
package com.cmcc.hy.phoenix.redis;
import java.io.Serializable;
/**
*
*
* @author phoenix
* @date 2020年2月8日
*/
public interface RedisClient {
/**
* @param k
* @param v
* @param seconds
*/
void put(String k, String v, int seconds);
/**
* 序列化
*
* @param k
* @param v
* @param seconds
*/
<T extends Serializable> void put(String key, T v, int seconds);
/**
*
* @Description: TODO(这里用一句话描述这个方法的作用)
* @param key
* @return
*/
boolean setLock(String key);
/**
*
* @Description: TODO(这里用一句话描述这个方法的作用)
* @param key
*/
public void delLock(String key);
/**
* @param key
* @return
*/
String get(String key);
/**
* @param key
* @param cls
* @return
*/
<T extends Serializable> T get(String key, Class<T> cls);
/**
* @param key
*/
void del(String key);
/**
* llen:(). <br/>
*
* @param key
* @return
* @author chiwei
* @since JDK 1.6
*/
long llen(String key);
/**
* @param key
* @param seconds
*/
void expire(String key, int seconds);
/**
* @param key
* @param value
*/
void lpush(String key, String value);
/**
* @param key
* @return
*/
String rpop(String key);
/**
* @param key
* @param timeout seconds ;0 means hold until get data
* @return
*/
String brpop(String key, int timeout);
}

View File

@ -0,0 +1,217 @@
package com.cmcc.hy.phoenix.redis.jedis;
import java.io.Serializable;
import java.nio.charset.StandardCharsets;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.stereotype.Component;
import com.cmcc.hy.phoenix.redis.ProtobufSerializer;
import com.cmcc.hy.phoenix.redis.RedisClient;
import lombok.extern.slf4j.Slf4j;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPool;
import redis.clients.jedis.params.SetParams;
/**
*
*
* @author phoenix
* @date 2020年2月8日
*/
@ConditionalOnBean(ShardedJedisPool.class)
@Component
@Slf4j
public class RedisClientJedisImpl implements RedisClient {
@Resource
private ShardedJedisPool shardedJedisPool;
@Override
public void put(String k, String v, int seconds) {
// TODO Auto-generated method stub
ShardedJedis sj = null;
try {
sj = shardedJedisPool.getResource();
sj.setex(k, seconds, v);
} catch (Exception e) {
log.error("KV存储异常", e);
} finally {
sj.close();
}
}
@Override
public boolean setLock(String key) {
// TODO Auto-generated method stub
ShardedJedis sj = null;
try {
sj = shardedJedisPool.getResource();
// nx 不存在setex秒
String res = sj.set(key, key, SetParams.setParams().nx().ex(60));
return "OK".equals(res);
} catch (Exception e) {
log.error("锁异常", e);
sj.del(key);
} finally {
sj.close();
}
return false;
}
@Override
public String get(String key) {
// TODO Auto-generated method stub
ShardedJedis sj = null;
try {
sj = shardedJedisPool.getResource();
return sj.get(key);
} catch (Exception e) {
log.error("获取数据异常", e);
} finally {
sj.close();
}
return null;
}
@Override
public void del(String key) {
// TODO Auto-generated method stub
ShardedJedis sj = null;
try {
sj = shardedJedisPool.getResource();
sj.del(key);
} catch (Exception e) {
log.error("key删除异常", e);
} finally {
sj.close();
}
}
@Override
public <T extends Serializable> void put(String key, T v, int seconds) {
// TODO Auto-generated method stub
ShardedJedis sj = null;
try {
sj = shardedJedisPool.getResource();
sj.setex(key.getBytes(StandardCharsets.UTF_8), seconds, ProtobufSerializer.serialize(v));
} catch (Exception e) {
log.error("数据序列化存入异常", e);
} finally {
sj.close();
}
}
@Override
public <T extends Serializable> T get(String key, Class<T> cls) {
// TODO Auto-generated method stub
ShardedJedis sj = null;
try {
sj = shardedJedisPool.getResource();
byte[] ret = sj.get(key.getBytes(StandardCharsets.UTF_8));
return ret == null ? null : ProtobufSerializer.deserialize(ret, cls);
} catch (Exception e) {
log.error("数据序列化取出异常", e);
} finally {
sj.close();
}
return null;
}
@Override
public void expire(String key, int seconds) {
// TODO Auto-generated method stub
ShardedJedis sj = null;
try {
sj = shardedJedisPool.getResource();
sj.expire(key, seconds);
} catch (Exception e) {
log.error("key设置有效期异常", e);
} finally {
sj.close();
}
}
@Override
public String rpop(String key) {
// TODO Auto-generated method stub
ShardedJedis sj = null;
try {
sj = shardedJedisPool.getResource();
return sj.rpop(key);
} catch (Exception e) {
log.error("队列取数据异常", e);
} finally {
sj.close();
}
return null;
}
@Override
public void lpush(String key, String value) {
// TODO Auto-generated method stub
ShardedJedis sj = null;
try {
sj = shardedJedisPool.getResource();
sj.lpush(key, value);
} catch (Exception e) {
log.error("数据存入队列异常", e);
} finally {
sj.close();
}
}
@Override
public long llen(String key) {
// TODO Auto-generated method stub
ShardedJedis sj = null;
try {
sj = shardedJedisPool.getResource();
return sj.llen(key);
} catch (Exception e) {
log.error("获取队列长度异常", e);
return 0;
} finally {
sj.close();
}
}
@Override
public String brpop(String key, int timeout) {
// TODO Auto-generated method stub
Jedis jedis = null;
try {
jedis = shardedJedisPool.getResource().getShard(key);
List<String> ret = jedis.brpop(timeout, key);
return ret == null ? null : ret.get(1);
} catch (Exception e) {
log.error("数据取出队列异常", e);
} finally {
jedis.close();
}
return null;
}
@Override
public void delLock(String key) {
// TODO Auto-generated method stub
//网上很多方法解锁通过LUA脚本判断value去解锁
//这里大家可以把加锁的key细化不同业务用不同的key即可
//不要整个系统用一个key再通过value去细分不同业务的锁
ShardedJedis sj = null;
try {
sj = shardedJedisPool.getResource();
sj.del(key);
} catch (Exception e) {
log.error("解锁异常", e);
} finally {
sj.close();
}
}
}

View File

@ -0,0 +1,138 @@
package com.cmcc.hy.phoenix.redis.redisson;
import java.io.Serializable;
import java.util.concurrent.TimeUnit;
import javax.annotation.Resource;
import org.redisson.api.RBlockingDeque;
import org.redisson.api.RBucket;
import org.redisson.api.RDeque;
import org.redisson.api.RKeys;
import org.redisson.api.RList;
import org.redisson.api.RLock;
import org.redisson.api.RMap;
import org.redisson.api.RedissonClient;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.stereotype.Component;
import com.cmcc.hy.phoenix.redis.ProtobufSerializer;
import com.cmcc.hy.phoenix.redis.RedisClient;
import lombok.extern.slf4j.Slf4j;
/**
*
*
* @author phoenix
* @date 2020年3月10日
*/
@ConditionalOnBean(RedissonClient.class)
@Slf4j
@Component
public class RedisClientRedissonImpl implements RedisClient {
@Resource
private RedissonClient redissonClient;
@Override
public void put(String k, String v, int seconds) {
// TODO Auto-generated method stub
RBucket<String> cache = redissonClient.getBucket(k);
cache.set(v, seconds, TimeUnit.SECONDS);
}
@Override
public <T extends Serializable> void put(String key, T v, int seconds) {
// TODO Auto-generated method stub
RBucket<Object> cache = redissonClient.getBucket(key);
cache.set(ProtobufSerializer.serialize(v), seconds, TimeUnit.SECONDS);
}
@Override
public boolean setLock(String key) {
// TODO Auto-generated method stub
//抢占式上锁
RLock lock = redissonClient.getLock(key);
//公平锁按照线程的优先顺序
//redissonClient.getFairLock(key);
// waitTime 超时时间
// leaseTime 有效期过期自动失效
try {
return lock.tryLock(5, 600, TimeUnit.SECONDS);
} catch (Exception e) {
log.error("Redisson 加锁异常", e);
return false;
}
}
public void delLock(String key) {
// TODO Auto-generated method stub
RLock lock = redissonClient.getLock(key);
//lock.forceUnlock();
lock.unlock();
//lock.forceUnlockAsync();
}
@Override
public String get(String key) {
// TODO Auto-generated method stub
RBucket<String> cache = redissonClient.getBucket(key);
return cache.get();
}
@Override
public <T extends Serializable> T get(String key, Class<T> cls) {
// TODO Auto-generated method stub
RBucket<byte[]> cache = redissonClient.getBucket(key);
return ProtobufSerializer.deserialize(cache.get(), cls);
}
@Override
public void del(String key) {
// TODO Auto-generated method stub
RKeys k = redissonClient.getKeys();
k.delete(key);
}
@Override
public long llen(String key) {
// TODO Auto-generated method stub
RList<Object> list = redissonClient.getList(key);
return list.size();
}
@Override
public void expire(String key, int seconds) {
// TODO Auto-generated method stub
RMap<Object, Object> map = redissonClient.getMap(key);
map.expire(seconds, TimeUnit.SECONDS);
}
@Override
public void lpush(String key, String value) {
// TODO Auto-generated method stub
RDeque<String> list = redissonClient.getDeque(key);
list.addFirst(value);// lpush
}
@Override
public String rpop(String key) {
// TODO Auto-generated method stub
RDeque<String> list = redissonClient.getDeque(key);
return list.pollLast();
}
@Override
public String brpop(String key, int timeout) {
// TODO Auto-generated method stub
RBlockingDeque<String> list = redissonClient.getBlockingDeque(key);
try {
return list.pollLast(timeout, TimeUnit.SECONDS);
} catch (InterruptedException e) {
log.error("BRPOP异常",e);
return null;
}
}
}

View File

@ -0,0 +1,24 @@
package com.cmcc.hy.phoenix.repository;
import com.google.common.collect.Sets;
import org.springframework.web.bind.annotation.RestController;
import java.util.Set;
/**
* 模拟DAO
*
* @author phoenix
* @date 2020年2月8日
*/
@RestController
public class IUserInfoRepository {
private Set<Long> idSet = Sets.newHashSet(1L, 2L);
public boolean existsById(long aId) {
return idSet.contains(aId);
}
}

View File

@ -0,0 +1,18 @@
package com.cmcc.hy.phoenix.service;
/**
*
*
* @author phoenix
* @date 2020年2月7日
*/
public interface AsyncService {
/**
*
* @Description: 发邮件测试
* @param cont
*/
public void sendMail(String cont);
}

View File

@ -0,0 +1,19 @@
package com.cmcc.hy.phoenix.service;
/**
* 接口定义
*
* @author phoenix
* @date 2020年2月5日
*/
public interface UserService {
/**
*
* @Description: 服务测试方法
* @param id
* @return
*/
public String testService(long id);
}

View File

@ -0,0 +1,37 @@
package com.cmcc.hy.phoenix.service.impl;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import com.cmcc.hy.phoenix.service.AsyncService;
import lombok.extern.slf4j.Slf4j;
/**
*
*
* @author phoenix
* @date 2020年2月5日
*/
@Service
@Slf4j
public class AsyncServiceImpl implements AsyncService {
/**
* Async(xx) 表明用哪个线程池来完成异步任务对应ThreadPoolConfig中的线程池定义
*
* @see com.cmcc.hy.phoenix.service.AsyncService#sendMail(java.lang.String)
*/
@Async("bizExecutor")
@Override
public void sendMail(String cont) {
// TODO Auto-generated method stub
try {
Thread.sleep(5000);
log.info("异步发送邮件,邮件内容 " + cont);
} catch (Throwable e) {
log.error("发送邮件异常", e);
}
}
}

View File

@ -0,0 +1,44 @@
package com.cmcc.hy.phoenix.service.impl;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import com.cmcc.hy.phoenix.config.MyConfig;
import com.cmcc.hy.phoenix.manager.GlobalManager;
import com.cmcc.hy.phoenix.pojo.entity.User;
import com.cmcc.hy.phoenix.service.UserService;
import lombok.extern.slf4j.Slf4j;
/**
*
*
* @author phoenix
* @date 2020年2月5日
*/
@Service
@Slf4j
public class UserServiceImpl implements UserService {
@Resource
private MyConfig myConfig;
@Resource
private GlobalManager globalManager;
@Override
public String testService(long id) {
// TODO Auto-generated method stub
log.info("进入service方法");
User user = globalManager.findUserById(id);
if(user == null ) {
return "user is null";
}
log.info("service层查出用户信息 {}", user);
log.info("自定义配置获取 {}", myConfig.getSystemName());
// 返回用户名
return user.getName();
}
}

View File

@ -0,0 +1,130 @@
package com.cmcc.hy.phoenix.session;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
*
*
* @author phoenix
* @date 2020年2月24日
*/
public class MyCookie {
private HttpServletRequest request;
private HttpServletResponse response;
public MyCookie(HttpServletRequest req, HttpServletResponse res) {
request = req;
response = res;
}
public String getRemoteIp() {
String ip = request.getHeader("X-Forwarded-For");
if (isEffective(ip) && ip.indexOf(",") > -1) {
String[] array = ip.split(",");
for (String str : array) {
if (isEffective(str)) {
ip = str;
break;
}
}
}
if (!isEffective(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (!isEffective(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (!isEffective(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (!isEffective(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (!isEffective(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}
private boolean isEffective(String remoteAddr) {
return (null != remoteAddr) && (!"".equals(remoteAddr.trim()))
&& (!"unknown".equalsIgnoreCase(remoteAddr.trim()));
}
/**
* 设置cookie
*
* @param name
* @param value
* @param domain
* @param expire
*/
public void setCookie(String name, String value, String domain, int expire) {
Cookie cookie = new Cookie(name, value);
cookie.setDomain(domain);
cookie.setPath("/");
if (expire >= 0) {
cookie.setMaxAge(expire);
}
cookie.setHttpOnly(true);
response.addCookie(cookie);
}
/**
* 获取某个cookie值
*
* @param name
* @return
*/
public String getCookieValue(String name) {
Cookie[] cookies = request.getCookies();
if (cookies == null) {
return null;
}
Cookie cookie = null;
for (int i = 0; i < cookies.length; i++) {
cookie = cookies[i];
if (cookie.getName().equalsIgnoreCase(name)) {
return cookie.getValue();
}
}
return null;
}
/**
* setCookie:(). <br/>
*
* @param name
* @param value
* @param domain
* @author chiwei
* @since JDK 1.6
*/
public void setCookie(String name, String value, String domain) {
// maxage=-1表示关闭浏览器则cookie失效
setCookie(name, value, domain, -1);
}
/**
* @param name
* @param domain
*/
public void clearCookie(String name, String domain) {
setCookie(name, "", domain, 0);
}
/**
* clearSession:(). <br/>
*
* @param name
* @return
* @author chiwei
* @since JDK 1.6
*/
public void clearSession(String name) {
request.getSession().removeAttribute(name);
}
}

View File

@ -0,0 +1,50 @@
package com.cmcc.hy.phoenix.swagger;
import java.util.Collections;
import javax.annotation.Resource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.cmcc.hy.phoenix.config.MyConfig;
import com.google.common.base.Predicates;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
*
*
* @author phoenix
* @date 2020年2月10日
*/
@Configuration
@EnableSwagger2
public class Swagger2Config {
@Resource
private MyConfig myConfig;
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2).enable(Boolean.parseBoolean(myConfig.getSwaggerSwitch()))
.select().apis(RequestHandlerSelectors.any()).paths(PathSelectors.any())
.paths(Predicates.not(PathSelectors.regex("/error.*")))// 错误路径不监控
.paths(PathSelectors.regex("/.*")) // 对根下所有路径进行监控
.build().apiInfo(apiInfo());
}
private ApiInfo apiInfo() {
return new ApiInfo(
"phoenix脚手架工程API示例", "展示所有API信息方便测试", "API V1.0", "xxx", new Contact("phoenix",
"http://git.komect.net/WLFHCZ/phoenix_share_framework.git", "phoenix@cmhi.chinamobile.com"),
"CMCC.HY", "", Collections.emptyList());
}
}

View File

@ -0,0 +1,68 @@
package com.cmcc.hy.phoenix.task;
import javax.annotation.Resource;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import com.cmcc.hy.phoenix.common.DateUtil;
import com.cmcc.hy.phoenix.redis.RedisClient;
import lombok.extern.slf4j.Slf4j;
/**
* 轻量级定时任务
*
* @author phoenix
* @date 2020年2月4日
*/
@Component
@Slf4j
public class MyTask {
@Resource
private RedisClient redisClient;
/**
* 测试任务 小时 日期 月份 星期 每10秒执行
*/
@Scheduled(cron = "0/10 * * * * ?")
public void task() {
log.info("Now is " + DateUtil.d2s(DateUtil.getCurrentTime(), DateUtil.YYYYMMDDHHMMSSSSSWITHSYMBOL));
}
/**
* 分布式锁场景
*/
//@Scheduled(cron = "0/10 * * * * ?")
public void lockTask() {
String lockName = "myLock";
boolean lock = false;
try {
lock = redisClient.setLock(lockName);
if (lock) {
log.info("获取锁 {} 成功", lockName);
// 做自己的业务
} else {
log.info("拿锁 {} 失败", lockName);
}
} catch (Exception e) {
log.error("XXX异常", e);
} finally {
if (lock) {
redisClient.del(lockName);
}
}
}
/**
* 使用自定义线程池执行的定时任务
*/
@Async("logExecutor")
@Scheduled(cron = "0/5 * * * * ?")
public void threadPoolTask() {
log.info("我是自定义线程池执行的");
}
}

View File

@ -0,0 +1,36 @@
package com.cmcc.hy.phoenix.thread;
import java.util.concurrent.Executor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
/**
*
*
* @author phoenix
* @date 2020年2月5日
*/
@Configuration
public class ThreadPoolConfig {
@Bean
public Executor logExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setThreadNamePrefix("myLog-");
executor.setMaxPoolSize(Runtime.getRuntime().availableProcessors() << 1 + 1);
executor.setCorePoolSize(Runtime.getRuntime().availableProcessors());
return executor;
}
@Bean
public Executor bizExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setThreadNamePrefix("myBiz-");
executor.setMaxPoolSize(Runtime.getRuntime().availableProcessors() << 1 + 1);
executor.setCorePoolSize(Runtime.getRuntime().availableProcessors());
return executor;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,22 @@
package com.cmcc.hy.phoenix.vo;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import lombok.Builder;
@Getter
@Setter
@ToString
@Builder
public class GetVersion {
private String commit_id;
private String commit_describe;
private String commit_time;
private String tag_name;
private String tags;
public static GetVersion result(String commit){
return GetVersion.builder().commit_id(commit).build();
}
}

View File

@ -0,0 +1,28 @@
package com.cmcc.hy.phoenix.vo;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
/**
* 前后端交互统一数据格式
*
* @author phoenix
* @date 2020年2月4日
*/
@Getter
@Setter
@ToString
@Builder
public class MyResp {
private int code;
private Object data;
private String msg;
public static MyResp result(Resp resp) {
return MyResp.builder().code(resp.getCode()).msg(resp.getMsg()).build();
}
}

View File

@ -0,0 +1,56 @@
package com.cmcc.hy.phoenix.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
/**
* 服务器响应请求通信协议
*/
@Getter
@Setter
@ToString
@Builder
public class ProtocolResp {
@ApiModelProperty(value="命令编号(必要字段): \n" +
"0-9999范围为请求命令\n" +
"10000-19999 范围为对应请求的响应命令\n" +
"响应命令值为10000+请求命令值\n", required = true,
allowableValues = "rang[0, 19999]",
example = "1")
private int cmdId;
@ApiModelProperty(value="协议版本号", required = true, example = "1")
private int ver;
@ApiModelProperty(value="msgContent字段内容编码格式\n" +
"0无编码格式普通字符串\n" +
"1base64编码格式\n" +
"2采用AES加密后的base64编码格式\n", required = true,
allowableValues = "0, 1, 2",
example = "0")
private int cryptoType;
@ApiModelProperty(value="当前UTC时间戳", required = true, example = "1526625689000")
private Long timeStamp;
@ApiModelProperty(value="协议详细内容Json字符串格式。\n" +
"保存该cmdId命令相关的详细内容\n" +
"具体每个cmdId命令的详细内容参看对应的命令协议定义", required = false,
example = "{}")
private String[] msgContent;
@ApiModelProperty(value="服务器返回状态码", required = false,
example = "200")
private int code;
public static ProtocolResp result(Resp resp) {
return ProtocolResp.builder().code(resp.getCode()).msgContent(new String[] {resp.getMsg()}).build();
}
public static ProtocolResp result(Resp resp, ProtocolResp obj) {
return ProtocolResp.builder().cmdId(obj.cmdId).code(Resp.SUCCESS.getCode()).msgContent(obj.msgContent).build();
}
}

View File

@ -0,0 +1,40 @@
package com.cmcc.hy.phoenix.vo;
/**
* 后端返回码定义
*
* @author phoenix
* @date 2020年2月4日
*/
public enum Resp {
// 成功返回码
SUCCESS(200, "SUCCESS"),
// 3XX
PARAM_ERROR(300, "自定义参数错误"),
// 4XX
SYSTEM_ERROR(400, "系统内部自定义错误"),
// 5XX
ERROR(500, "服务端系统错误"),
;
private int code;
private String msg;
Resp(int code, String msg) {
this.code = code;
this.msg = msg;
}
public int getCode() {
return code;
}
public String getMsg() {
return msg;
}
}

View File

@ -0,0 +1,14 @@
${AnsiColor.BRIGHT_GREEN}
######## ## ## ####### ######## ## ## #### ## ##
## ## ## ## ## ## ## ### ## ## ## ##
## ## ## ## ## ## ## #### ## ## ## ##
######## ######### ## ## ###### ## ## ## ## ###
## ## ## ## ## ## ## #### ## ## ##
## ## ## ## ## ## ## ### ## ## ##
## ## ## ####### ######## ## ## #### ## ##
${AnsiColor.BRIGHT_RED}
Application Version: ${application.version}${application.formatted-version}
Spring Boot Version: ${spring-boot.version}${spring-boot.formatted-version}

View File

@ -0,0 +1,2 @@
-- INSERT INTO `phoenix_user`(`id`,`name`,`password`,`salt`,`email`,`phone_number`) VALUES (1, 'user_1', 'ff342e862e7c3285cdc07e56d6b8973b', '412365a109674b2dbb1981ed561a4c70', 'user1@cmhi.chinamobile.com', '17300000001');
-- INSERT INTO `phoenix_user`(`id`,`name`,`password`,`salt`,`email`,`phone_number`) VALUES (2, 'user_2', '6c6bf02c8d5d3d128f34b1700cb1e32c', 'fcbdd0e8a9404a5585ea4e01d0e4d7a0', 'user2@cmhi.chinamobile.com', '17300000002');

View File

@ -0,0 +1,37 @@
DROP TABLE IF EXISTS `phoenix_user`;
CREATE TABLE `phoenix_user` (
`id` INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT '主键',
`name` VARCHAR(32) NOT NULL UNIQUE COMMENT '用户名',
`password` VARCHAR(32) NOT NULL COMMENT '加密后的密码',
`salt` VARCHAR(32) NOT NULL COMMENT '加密使用的盐',
`email` VARCHAR(32) NOT NULL UNIQUE COMMENT '邮箱',
`phone_number` VARCHAR(15) NOT NULL UNIQUE COMMENT '手机号码',
`status` INT(2) NOT NULL DEFAULT 1 COMMENT '状态,-1逻辑删除0禁用1启用',
`create_time` DATETIME DEFAULT NOW() COMMENT '创建时间',
`last_login_time` DATETIME DEFAULT NULL COMMENT '上次登录时间',
`last_update_time` DATETIME DEFAULT NOW() COMMENT '上次更新时间'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='phoenix用户示例表';
DROP TABLE IF EXISTS `info_collection`;
CREATE TABLE `info_collection` (
`id` INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT '主键',
`username` VARCHAR(32) NOT NULL COMMENT '联系人',
`organization` VARCHAR(128) NOT NULL COMMENT '单位名称',
`province_code` VARCHAR(32) NOT NULL COMMENT '省编码',
`province` VARCHAR(128) NOT NULL COMMENT '',
`city` VARCHAR(128) NOT NULL COMMENT '',
`district` VARCHAR(128) NOT NULL COMMENT '',
`address` VARCHAR(128) NOT NULL COMMENT '单位地址',
`email` VARCHAR(32) NOT NULL COMMENT '邮箱',
`phone_number` VARCHAR(32) NOT NULL COMMENT '手机号码',
`comment` VARCHAR(128) NOT NULL COMMENT '备注',
`product_type` VARCHAR(32) NOT NULL COMMENT '产品类型waf,ddos',
`sync_status` tinyint NOT NULL DEFAULT -1 COMMENT '是否同步过1同步过0未同步',
`create_time` DATETIME DEFAULT NOW() COMMENT '创建时间',
`update_time` DATETIME DEFAULT NOW() COMMENT '上次更新时间'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='信息收集表';
CREATE UNIQUE INDEX ic_phone_pt_index ON info_collection(phone_number,product_type);

View File

@ -0,0 +1,25 @@
#Generated by Git-Commit-Id-Plugin
#Mon Mar 16 17:21:00 CST 2020
git.branch=master
git.build.host=DESKTOP-GJUT8MA
git.build.time=2020-03-16T17\:21\:00+0800
git.build.user.email=huangxin@\u0096cmhi.chinamobile.com
git.build.user.name=HuangXin
git.build.version=1.0.0
git.closest.tag.commit.count=
git.closest.tag.name=
git.commit.id=42f5f76b5e1a99a327d1979368a2db3f1a0fc315
git.commit.id.abbrev=42f5f76
git.commit.id.describe=42f5f76-dirty
git.commit.id.describe-short=42f5f76-dirty
git.commit.message.full=OCT update\n\nOCT update
git.commit.message.short=OCT update
git.commit.time=2020-03-11T23\:38\:05+0800
git.commit.user.email=chiwei@cmhi.chinamobile.com
git.commit.user.name=chiwei
git.dirty=true
git.local.branch.ahead=0
git.local.branch.behind=0
git.remote.origin.url=git@git.komect.net\:WLFHCZ/phoenix_share_framework.git
git.tags=
git.total.commit.count=30

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cmcc.hy.phoenix.mapper.UserMapper">
<!-- mapper xml文件中只编写复杂逻辑的SQL SQL单独拿出来写与代码解耦SQL的熟练编写是每个研发必备的技能 -->
<select id="countByName" resultType="java.lang.Integer">
SELECT count(1) FROM phoenix_user WHERE name = #{name}
</select>
</mapper>

View File

@ -0,0 +1,75 @@
package com.cmcc.hy.phoenix.controller.impl;
import com.cmcc.hy.phoenix.pojo.dto.DemoDTO;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import javax.annotation.Resource;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
*
*
* @author phoenix
* @date 2020年2月8日
*/
@AutoConfigureMockMvc
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
public class DemoControllerTest {
@Resource
private MockMvc mockMvc;
@Resource
private ObjectMapper objectMapper;
@Test
public void save1() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.post("/demo").contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(getDemoDTO()))).andDo(print()).andExpect(status().isOk())
.andExpect(jsonPath("$.age").value(18)).andReturn().getResponse().getContentAsString();
}
@Test(expected = AssertionError.class)
public void save2() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.post("/demo").contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(getDemoDTO()))).andDo(print()).andExpect(status().isOk())
.andExpect(jsonPath("$.age").value(17)).andReturn().getResponse().getContentAsString();
}
@Test
public void update1() throws Exception {
DemoDTO demo = getDemoDTO();
demo.setId(2L);
mockMvc.perform(MockMvcRequestBuilders.put("/demo").contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(demo))).andDo(print()).andExpect(status().isOk())
.andExpect(jsonPath("$.age").value(18)).andReturn().getResponse().getContentAsString();
}
@Test(expected = AssertionError.class)
public void update2() throws Exception {
DemoDTO demo = getDemoDTO();
demo.setId(3L);
mockMvc.perform(MockMvcRequestBuilders.put("/demo").contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(demo))).andDo(print()).andExpect(status().isOk())
.andExpect(jsonPath("$.age").value(18)).andReturn().getResponse().getContentAsString();
}
private DemoDTO getDemoDTO() {
return DemoDTO.builder().age(18).username("石少东").build();
}
}

View File

@ -0,0 +1,39 @@
package com.cmcc.hy.phoenix.enc.dec;
import org.apache.commons.codec.binary.Base64;
import org.junit.Test;
import com.cmcc.aqb.enc.dec.AesECB;
import com.cmcc.hy.phoenix.pojo.dto.MyReqDTO;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
*
*
* @author phoenix
* @date 2020年2月10日
*/
public class EncDecTest {
private String aesKey = "Wt4EJu6Rrq5udd/42bNpCQ==";
@Test
public void test() throws Exception {
MyReqDTO mrd = MyReqDTO.builder().build();
mrd.setId(1L);
mrd.setMsg("test");
mrd.setType(3);
ObjectMapper om = new ObjectMapper();
String json = om.writeValueAsString(mrd);
System.out.println(json);
try {
String enc = Base64.encodeBase64String(AesECB.encByAes(json.getBytes(), aesKey));
System.out.println("密文==" + enc);
//CP+H7A/JlP3yhWGCLjS6HLq+P/sWBVavKpza3UwI8dw=
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,49 @@
package com.cmcc.hy.phoenix.manager;
import javax.annotation.Resource;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.util.ReflectionTestUtils;
import com.cmcc.hy.phoenix.mapper.UserMapper;
import com.cmcc.hy.phoenix.redis.RedisClient;
/**
*
*
* @author phoenix
* @date 2020年2月8日
*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class GlobalManagerTest {
@Mock
private UserMapper userMapper;
@Mock
private RedisClient redisClient;
@Resource
private GlobalManager globalManager;
@Before
public void setUp() {
ReflectionTestUtils.setField(globalManager, "redisClient", redisClient);
ReflectionTestUtils.setField(globalManager, "userMapper", userMapper);
}
@Test
public void test() {
Mockito.when(userMapper.select(null)).thenReturn(null);
Mockito.doNothing().when(redisClient).put(Mockito.anyString(), Mockito.anyString(), Mockito.anyInt());
globalManager.findUserById(1);
}
}

View File

@ -0,0 +1,102 @@
package com.cmcc.hy.phoenix.manager;
import javax.annotation.Resource;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.util.ReflectionTestUtils;
import com.cmcc.hy.phoenix.aop.cache.MyCacheInterceptor;
import com.cmcc.hy.phoenix.mapper.InfoCollectionMapper;
import com.cmcc.hy.phoenix.pojo.entity.InfoCollection;
import com.cmcc.hy.phoenix.redis.RedisClient;
import junit.framework.TestCase;
import lombok.extern.slf4j.Slf4j;
/**
*
*
* @author phoenix
* @date 2020年3月4日
*/
@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class ManagerCacheTest {
@Resource
private RedisClient redisClient;
@Resource
private GlobalManager globalManager;
@Resource
private InfoCollectionMapper infoCollectionMapper;
@Before
public void setUp() {
ReflectionTestUtils.setField(globalManager, "redisClient", redisClient);
ReflectionTestUtils.setField(globalManager, "infoCollectionMapper", infoCollectionMapper);
}
@Test
public void test() {
// 清空表
globalManager.deleteAllIc();
// 生成数据
long id = 1111L;
String phone = "18867101080";
String productType = "waf";
InfoCollection ic = InfoCollection.builder().id(id).phoneNumber(phone).username("chiwei").province("浙江")
.city("城市").district("余杭").address("杭州").email("sdf").comment("sdf").organization("CMCC")
.provinceCode("123456").syncStatus(-1).productType(productType).build();
globalManager.saveInfoCollection(ic);
String idKey = MyCacheInterceptor.CACHE_PREFIX + InfoCollection.class.getSimpleName()
+ MyCacheInterceptor.SPILIT + id;
log.info("idKey={}", idKey);
String ppKey = MyCacheInterceptor.CACHE_PREFIX + InfoCollection.class.getSimpleName()
+ MyCacheInterceptor.SPILIT + phone + MyCacheInterceptor.SPILIT + productType;
log.info("ppKey={}", ppKey);
// 会有两条缓存产生
InfoCollection idIc = redisClient.get(idKey, InfoCollection.class);
TestCase.assertEquals(phone, idIc.getPhoneNumber());
InfoCollection ppIc = redisClient.get(ppKey, InfoCollection.class);
TestCase.assertEquals(id + "", ppIc.getId() + "");
redisClient.del(idKey);
redisClient.del(ppKey);
idIc = redisClient.get(idKey, InfoCollection.class);
TestCase.assertNull(idIc);
ppIc = redisClient.get(ppKey, InfoCollection.class);
TestCase.assertNull(ppIc);
// 数据查询
InfoCollection queryIc = globalManager.findIcById(id);
TestCase.assertEquals(phone, queryIc.getPhoneNumber());
// 有id缓存
idIc = redisClient.get(idKey, InfoCollection.class);
TestCase.assertEquals(phone, idIc.getPhoneNumber());
// phone productType缓存
ppIc = redisClient.get(ppKey, InfoCollection.class);
TestCase.assertNull(ppIc);
redisClient.del(idKey);
redisClient.del(ppKey);
// 查询
queryIc = globalManager.findIcByPhoneAndProductType(phone, productType);
TestCase.assertEquals(id + "", queryIc.getId() + "");
// 无id缓存
idIc = redisClient.get(idKey, InfoCollection.class);
TestCase.assertNull(idIc);
// phone productType缓存
ppIc = redisClient.get(ppKey, InfoCollection.class);
TestCase.assertEquals(id + "", queryIc.getId() + "");
// 删除操作
globalManager.deleteIcByPhoneAndPt(phone, productType);
idIc = redisClient.get(idKey, InfoCollection.class);
TestCase.assertNull(idIc);
ppIc = redisClient.get(ppKey, InfoCollection.class);
TestCase.assertNull(ppIc);
}
}

View File

@ -0,0 +1,106 @@
package com.cmcc.hy.phoenix.mapper;
import java.util.List;
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import com.cmcc.hy.phoenix.pojo.entity.User;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import junit.framework.TestCase;
import lombok.extern.slf4j.Slf4j;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.entity.Example.Criteria;
/**
*
*
* @author phoenix
* @date 2020年2月10日
*/
@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class UserMappTest {
@Resource
private UserMapper userMapper;
@Test
public void test() {
// insert
User user = User.builder().name("phoenix").phoneNumber("18867101080").email("mail").status(1).password("pwd")
.salt("salt").build();
int res = userMapper.insert(user);
TestCase.assertTrue(res > 0);
log.info("insert return primary key id = {}", user.getId());
// read
User readUser = userMapper.selectByPrimaryKey(user.getId());
TestCase.assertEquals("phoenix", readUser.getName());
// update
readUser.setSalt("updateSalt");
userMapper.updateByPrimaryKey(readUser);
readUser = userMapper.selectByPrimaryKey(user.getId());
TestCase.assertEquals("updateSalt", readUser.getSalt());
// delete
userMapper.deleteByPrimaryKey(user.getId());
// read
readUser = userMapper.selectByPrimaryKey(user.getId());
TestCase.assertNull(readUser);
}
@Test
public void testBatchInsert() {
// batch insert
List<User> userList = Lists.newArrayList();
for (int i = 0; i < 10; i++) {
User user = User.builder().name("phoenix" + i).phoneNumber("1886710108" + i).email("mail" + i).status(1)
.password("pwd" + i).salt("salt" + i).build();
userList.add(user);
}
int res = userMapper.insertList(userList);
System.out.println("批量插入返回 " + res);
}
@Test
public void testReadCondition() {
// 条件查询这里用example和condition都可以
Example example = new Example(User.class);
Criteria c = example.createCriteria();
c.andEqualTo("name", "phoenix1");
PageInfo<User> list = PageHelper.startPage(0 * 2, 2).setOrderBy("name asc")
.doSelectPageInfo(() -> userMapper.selectByExample(example));
System.out.println("条件查询返回list " + list.getList());
}
@Test
public void testPage() {
int pageSize = 2;
PageInfo<User> list = PageHelper.startPage(0 * pageSize, 2).setOrderBy("name asc")
.doSelectPageInfo(() -> userMapper.selectAll());
System.out.println("列表查询 " + list.getList());
System.out.println("页码 " + list.getPageNum());
System.out.println("页大小 " + list.getPageSize());
list = PageHelper.startPage(1 * pageSize, 2).setOrderBy("name asc")
.doSelectPageInfo(() -> userMapper.selectAll());
System.out.println("列表查询 " + list.getList());
System.out.println("页码 " + list.getPageNum());
System.out.println("页大小 " + list.getPageSize());
}
@Test
public void testComplicatedSql() {
int res = userMapper.countByName("phoenix1");
System.out.println("复杂自定义SQL执行返回 "+res);
}
}

View File

@ -0,0 +1,84 @@
package com.cmcc.hy.phoenix.redis;
import java.util.Date;
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.redisson.api.RedissonClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import com.cmcc.hy.phoenix.pojo.entity.InfoCollection;
import junit.framework.TestCase;
import lombok.extern.slf4j.Slf4j;
/**
*
*
* @author phoenix
* @date 2020年2月8日
*/
@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class RedisClientTest {
@Resource
private RedisClient redisClient;
@Resource
private RedissonClient redissonClient;
@Test
public void test() {
InfoCollection ic = InfoCollection.builder().username("chiwei").address("address").city("city")
.comment("comment").createTime(new Date()).district("district").email("email").id(1L)
.organization("org").phoneNumber("18867101080").build();
redisClient.put("demokey", ic, 100);
InfoCollection info = redisClient.get("demokey", InfoCollection.class);
log.info("str = " + info.getPhoneNumber());
}
@Test
public void testLock() throws Exception {
// TODO Auto-generated method stub
String key = "locktest1111111111";
boolean flag = redisClient.setLock(key);
TestCase.assertEquals(flag, true);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
redisClient.del(key);
// TODO Auto-generated method stub
flag = redisClient.setLock(key);
TestCase.assertEquals(flag, true);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
redisClient.del(key);
// TODO Auto-generated method stub
flag = redisClient.setLock(key);
TestCase.assertEquals(flag, true);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
redisClient.del(key);
}
@Test
public void testDelLock() {
String key = "locktest1111111111";
redisClient.del(key);
}
}

View File

@ -0,0 +1,11 @@
package com.cmcc.hy.phoenix.service;
/**
*
*
* @author phoenix
* @date 2020年2月10日
*/
public class AsyncServiceTest {
}