From e80605842308283977efa8c049762dc428001082 Mon Sep 17 00:00:00 2001 From: Starrier <1342878298@qq.com> Date: Tue, 7 May 2019 23:01:01 +0800 Subject: [PATCH] add new utils --- .github/workflows/maven-publish.yml | 30 ++ .gitignore | 3 + .travis.yml | 32 ++ LICENSE | 21 ++ README.md | 18 + pom.xml | 334 ++++++++++++++++-- .../org/starrier/common/annotation/README.md | 18 + .../customer/DuplicateSubmitToken.java | 23 ++ .../common/annotation/customer/Http.java | 15 + .../annotation/customer/LockAnnotation.java | 31 ++ .../customer/LockParamAnnotation.java | 21 ++ .../common/annotation/customer/SysLogger.java | 14 + .../annotation/customer/package-info.java | 10 + .../annotation/logger/ExceptionLogger.java | 15 + .../annotation/logger/ExceptionNull.java | 19 + .../annotation/logger/ExceptionZero.java | 19 + .../annotation/logger/package-info.java | 7 + .../annotation/loginlimt/LoginLimit.java | 36 ++ .../annotation/loginlimt/LoginLimitAop.java | 111 ++++++ .../common/annotation/loginlimt/README.md | 0 .../annotation/loginlimt/package-info.java | 1 + .../annotation/methodcount/MethodCount.java | 16 + .../methodcount/MethodCountAop.java | 46 +++ .../common/annotation/methodcount/README.md | 0 .../common/annotation/package-info.java | 7 + .../annotation/ratelimiter/RateLimit.java | 28 ++ .../annotation/ratelimiter/package-info.java | 7 + .../threadsafe/ThreadSafeClass.java | 20 ++ .../threadsafe/ThreadSafeMethod.java | 17 + .../threadsafe/ThreadSafeVariable.java | 20 ++ .../annotation/threadsafe/package-info.java | 7 + .../starrier/common/constant/Constant.java | 22 +- .../common/constant/DataConstant.java | 12 + .../constant/ExceptionLoggerHandler.java | 27 ++ .../common/constant/ExceptionNullHandler.java | 21 ++ .../common/constant/HttpConstant.java | 36 ++ .../common/constant/ResourceNameConstant.java | 6 +- .../common/constant/package-info.java | 10 + .../org/starrier/common/http/HttpAspect.java | 96 +++++ .../starrier/common/http/package-info.java | 7 + .../{pageHelper => page}/PageConstant.java | 66 ++-- .../{pageHelper => page}/PaginatedResult.java | 75 ++-- .../ParameterIllegalException.java | 22 +- .../ParameterInvalidItem.java | 49 ++- .../ResourceNotFoundException.java | 55 +-- .../starrier/common/page/package-info.java | 7 + .../org/starrier/common/result/Result.java | 79 ++++- .../starrier/common/result/ResultCode.java | 9 +- .../starrier/common/result/package-info.java | 7 + .../org/starrier/common/token/DESBuilder.java | 23 +- .../org/starrier/common/token/DESCoder.java | 5 +- .../common/{utils => token}/TokenUtils.java | 13 +- .../starrier/common/token/package-info.java | 7 + .../org/starrier/common/utils/CornUtils.java | 8 + .../org/starrier/common/utils/DateUtils.java | 287 ++++++++++----- .../starrier/common/utils/FastJsonUtils.java | 58 +++ .../common/utils/FetchSensitiveWordUtil.java | 57 +++ .../org/starrier/common/utils/FormatUtil.java | 8 + .../org/starrier/common/utils/GsonUtil.java | 99 ++++++ .../org/starrier/common/utils/HttpUtils.java | 89 +++++ .../org/starrier/common/utils/IpUtil.java | 43 +++ .../org/starrier/common/utils/JedisUtil.java | 187 ++++++++++ .../starrier/common/utils/JodaTimeUtil.java | 291 +++++++++++++++ .../org/starrier/common/utils/PageUtil.java | 2 +- .../org/starrier/common/utils/RandomUtil.java | 123 +++++++ .../starrier/common/utils/RandomUtils.java | 3 +- .../org/starrier/common/utils/RedisUtils.java | 26 ++ .../starrier/common/utils/RedissionUtils.java | 26 ++ .../org/starrier/common/utils/RegexUtil.java | 99 ++++++ .../starrier/common/utils/ScheduleUtil.java | 78 ++++ .../common/utils/SensitiveWordUtil.java | 64 ++-- .../common/utils/SerializableUtil.java | 52 +++ .../org/starrier/common/utils/SignUtils.java | 49 +++ .../starrier/common/utils/ValidatorUtil.java | 24 ++ .../common/utils/encrypt/AES2Utils.java | 49 +++ .../common/utils/encrypt/AESUtils.java | 126 +++++++ .../common/utils/encrypt/EncryptUtils.java | 61 ++++ .../common/utils/encrypt/MD5Utils.java | 25 ++ .../starrier/common/utils/package-info.java | 7 + .../starrier/common/validation/IsMobile.java | 47 +++ .../common/validation/IsMobileValidator.java | 36 ++ .../common/validation/package-info.java | 7 + .../common/utils/encrypt/AES2UtilsTest.java | 36 ++ .../common/utils/encrypt/AESUtilsTest.java | 33 ++ .../validation/IsMobileValidatorTest.java | 23 ++ 85 files changed, 3404 insertions(+), 319 deletions(-) create mode 100644 .github/workflows/maven-publish.yml create mode 100644 .travis.yml create mode 100644 LICENSE create mode 100644 README.md create mode 100644 src/main/java/org/starrier/common/annotation/README.md create mode 100644 src/main/java/org/starrier/common/annotation/customer/DuplicateSubmitToken.java create mode 100644 src/main/java/org/starrier/common/annotation/customer/Http.java create mode 100644 src/main/java/org/starrier/common/annotation/customer/LockAnnotation.java create mode 100644 src/main/java/org/starrier/common/annotation/customer/LockParamAnnotation.java create mode 100644 src/main/java/org/starrier/common/annotation/customer/SysLogger.java create mode 100644 src/main/java/org/starrier/common/annotation/customer/package-info.java create mode 100644 src/main/java/org/starrier/common/annotation/logger/ExceptionLogger.java create mode 100644 src/main/java/org/starrier/common/annotation/logger/ExceptionNull.java create mode 100644 src/main/java/org/starrier/common/annotation/logger/ExceptionZero.java create mode 100644 src/main/java/org/starrier/common/annotation/logger/package-info.java create mode 100644 src/main/java/org/starrier/common/annotation/loginlimt/LoginLimit.java create mode 100644 src/main/java/org/starrier/common/annotation/loginlimt/LoginLimitAop.java create mode 100644 src/main/java/org/starrier/common/annotation/loginlimt/README.md create mode 100644 src/main/java/org/starrier/common/annotation/loginlimt/package-info.java create mode 100644 src/main/java/org/starrier/common/annotation/methodcount/MethodCount.java create mode 100644 src/main/java/org/starrier/common/annotation/methodcount/MethodCountAop.java create mode 100644 src/main/java/org/starrier/common/annotation/methodcount/README.md create mode 100644 src/main/java/org/starrier/common/annotation/package-info.java create mode 100644 src/main/java/org/starrier/common/annotation/ratelimiter/RateLimit.java create mode 100644 src/main/java/org/starrier/common/annotation/ratelimiter/package-info.java create mode 100644 src/main/java/org/starrier/common/annotation/threadsafe/ThreadSafeClass.java create mode 100644 src/main/java/org/starrier/common/annotation/threadsafe/ThreadSafeMethod.java create mode 100644 src/main/java/org/starrier/common/annotation/threadsafe/ThreadSafeVariable.java create mode 100644 src/main/java/org/starrier/common/annotation/threadsafe/package-info.java create mode 100644 src/main/java/org/starrier/common/constant/DataConstant.java create mode 100644 src/main/java/org/starrier/common/constant/ExceptionLoggerHandler.java create mode 100644 src/main/java/org/starrier/common/constant/ExceptionNullHandler.java create mode 100644 src/main/java/org/starrier/common/constant/HttpConstant.java create mode 100644 src/main/java/org/starrier/common/constant/package-info.java create mode 100644 src/main/java/org/starrier/common/http/HttpAspect.java create mode 100644 src/main/java/org/starrier/common/http/package-info.java rename src/main/java/org/starrier/common/{pageHelper => page}/PageConstant.java (85%) rename src/main/java/org/starrier/common/{pageHelper => page}/PaginatedResult.java (84%) rename src/main/java/org/starrier/common/{pageHelper => page}/ParameterIllegalException.java (61%) rename src/main/java/org/starrier/common/{pageHelper => page}/ParameterInvalidItem.java (81%) rename src/main/java/org/starrier/common/{pageHelper => page}/ResourceNotFoundException.java (72%) create mode 100644 src/main/java/org/starrier/common/page/package-info.java create mode 100644 src/main/java/org/starrier/common/result/package-info.java rename src/main/java/org/starrier/common/{utils => token}/TokenUtils.java (84%) create mode 100644 src/main/java/org/starrier/common/token/package-info.java create mode 100644 src/main/java/org/starrier/common/utils/CornUtils.java create mode 100644 src/main/java/org/starrier/common/utils/FastJsonUtils.java create mode 100644 src/main/java/org/starrier/common/utils/FetchSensitiveWordUtil.java create mode 100644 src/main/java/org/starrier/common/utils/FormatUtil.java create mode 100644 src/main/java/org/starrier/common/utils/GsonUtil.java create mode 100644 src/main/java/org/starrier/common/utils/HttpUtils.java create mode 100644 src/main/java/org/starrier/common/utils/IpUtil.java create mode 100644 src/main/java/org/starrier/common/utils/JedisUtil.java create mode 100644 src/main/java/org/starrier/common/utils/JodaTimeUtil.java create mode 100644 src/main/java/org/starrier/common/utils/RandomUtil.java create mode 100644 src/main/java/org/starrier/common/utils/RedisUtils.java create mode 100644 src/main/java/org/starrier/common/utils/RedissionUtils.java create mode 100644 src/main/java/org/starrier/common/utils/RegexUtil.java create mode 100644 src/main/java/org/starrier/common/utils/ScheduleUtil.java create mode 100644 src/main/java/org/starrier/common/utils/SerializableUtil.java create mode 100644 src/main/java/org/starrier/common/utils/SignUtils.java create mode 100644 src/main/java/org/starrier/common/utils/ValidatorUtil.java create mode 100644 src/main/java/org/starrier/common/utils/encrypt/AES2Utils.java create mode 100644 src/main/java/org/starrier/common/utils/encrypt/AESUtils.java create mode 100644 src/main/java/org/starrier/common/utils/encrypt/EncryptUtils.java create mode 100644 src/main/java/org/starrier/common/utils/encrypt/MD5Utils.java create mode 100644 src/main/java/org/starrier/common/utils/package-info.java create mode 100644 src/main/java/org/starrier/common/validation/IsMobile.java create mode 100644 src/main/java/org/starrier/common/validation/IsMobileValidator.java create mode 100644 src/main/java/org/starrier/common/validation/package-info.java create mode 100644 src/main/test/org/starrier/common/utils/encrypt/AES2UtilsTest.java create mode 100644 src/main/test/org/starrier/common/utils/encrypt/AESUtilsTest.java create mode 100644 src/main/test/org/starrier/common/validation/IsMobileValidatorTest.java diff --git a/.github/workflows/maven-publish.yml b/.github/workflows/maven-publish.yml new file mode 100644 index 0000000..5de62b4 --- /dev/null +++ b/.github/workflows/maven-publish.yml @@ -0,0 +1,30 @@ +# This workflow will build a package using Maven and then publish it to GitHub packages when a release is created +# For more information see: https://github.com/actions/setup-java#apache-maven-with-a-settings-path + +name: Maven Package + +on: + release: + types: [created] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Set up JDK 1.8 + uses: actions/setup-java@v1 + with: + java-version: 1.8 + server-id: github # Value of the distributionManagement/repository/id field of the pom.xml + settings-path: ${{ github.workspace }} # location for the settings.xml file + + - name: Build with Maven + run: mvn -B package --file pom.xml + + - name: Publish to GitHub Packages Apache Maven + run: mvn deploy -s $GITHUB_WORKSPACE/settings.xml + env: + GITHUB_TOKEN: ${{ github.token }} diff --git a/.gitignore b/.gitignore index 153c933..475677a 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,6 @@ HELP.md ### VS Code ### .vscode/ + +### Mac OS ### +.DS_Store diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..b94c0d3 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,32 @@ +language: java + +jdk: + - openjdk8 + +cache: + directories: + - '$HOME/.m2/repository' + +before_install: + +script: + - mvn clean package -DskipTests=true + - mvn cobertura:cobertura + +after_success: + - bash <(curl -s https://codecov.io/bash) + - cd ./target + - git init + - git config user.name "Starrier" + - git config user.email "starrier@starrier.com" + - git add . + - git commit -m "travis-ci" + - git push --force --quiet "https://${GITHUB_TOKEN}@${GH_REF}" master:master + +branches: + only: + - master + +env: + global: + - GH_REF=https://github.com/Starrier/commons.git \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..795f11d --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 Starrier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..6bea68b --- /dev/null +++ b/README.md @@ -0,0 +1,18 @@ +# Commons + +![GitHub](https://img.shields.io/github/license/Starrier/commons) +[![Build Status](https://travis-ci.org/Starrier/commons.svg?branch=master)](https://travis-ci.org/Starrier/commons) +[![codecov](https://codecov.io/gh/Starrier/commons/branch/master/graph/badge.svg?token=NBWEZP02H4)](https://codecov.io/gh/Starrier/commons) +[![Maintainability](https://api.codeclimate.com/v1/badges/67ded5e207bab2133673/maintainability)](https://codeclimate.com/github/Starrier/commons/maintainability) +> 通用工具类 + +## 一. Annotation + +### 1. 接口防刷/限流 + +### 2. 登录次数限制 + +## 二. Encrypt + +### 1. AES + diff --git a/pom.xml b/pom.xml index 8ddf5fb..46f24d8 100644 --- a/pom.xml +++ b/pom.xml @@ -6,73 +6,323 @@ org.starrier common 0.0.1-SNAPSHOT - common - common for Starrier - jar - 11 - http://maven.starrier.org/repository/maven-snapshots/ + 1.8 + 28.0-jre + UTF-8 + UTF-8 + 2.1.4.RELEASE + 1.18.16 + 3.8.1 + 1.11 + 0.9.1 + 2.10.1 + http://maven.starrier.org/repository/maven-snapshots/ + 3.8.0 + 3.1.1 + 2.8.2 + 3.0.1 + 2.9.0 + 2.6 + 5.3.1.RELEASE - org.apache.commons - commons-lang3 - 3.8.1 + com.alibaba + fastjson + 1.2.4 + + + com.google.code.findbugs + annotations + 2.0.0 org.projectlombok lombok - true - 1.18.6 + ${lombok.version} - com.google.guava - guava - 27.1-jre + commons-codec + commons-codec + 1.11 + + + org.aspectj + aspectjweaver + 1.9.6 + + + org.springframework + spring-context + 5.3.1 + + + org.springframework + spring-web + 5.3.1 + + + javax.servlet + javax.servlet-api + 4.0.1 + + com.google.code.gson + gson + 2.8.5 + + + + + org.apache.commons + commons-lang3 + 3.11 + + joda-time joda-time 2.10.1 - - commons-codec - commons-codec - 1.11 - io.jsonwebtoken jjwt 0.9.1 + + javax.validation + validation-api + 2.0.1.Final + + + com.twitter + parquet-hadoop-bundle + 1.6.0 + + + redis.clients + jedis + ${jedis.version} + + + + com.google.guava + guava + 28.1-jre + + + + org.springframework.boot + spring-boot-starter-data-redis + 2.1.9.RELEASE + + + slf4j-api + org.slf4j + + + spring-aop + org.springframework + + + spring-context + org.springframework + + + spring-core + org.springframework + + + spring-beans + org.springframework + + + + + org.junit.jupiter + junit-jupiter + RELEASE + test + + + org.junit.jupiter + junit-jupiter-engine + 5.5.2 + test + + + org.springframework.boot + spring-boot-starter-test + 2.4.0 + test + + + + + org.jetbrains + annotations + 20.1.0 + + common + common for Starrier + jar + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.apache.commons + commons-lang3 + ${commons.lang3.version} + + + org.projectlombok + lombok + true + 1.18.16 + + + com.google.guava + guava + 27.1-jre + + + joda-time + joda-time + ${joda.time.version} + + + commons-codec + commons-codec + ${commons.codec.version} + + + io.jsonwebtoken + jjwt + ${jjwt.version} + + + javax.validation + validation-api + 2.0.1.Final + + + com.google.code.gson + gson + 2.8.5 + + + com.google.code.findbugs + annotations + 2.0.0 + + + org.redisson + redisson + + + + + + - StarrierMaven - ${maven.url} + StarrierMavenSnapshots + ${maven.snapshots.url} + src/main/java commons + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 1.8 + 1.8 + UTF-8 + + + + org.apache.maven.plugins + maven-jar-plugin + ${maven.plugin.jar} + + ${project.build.directory}/modules + + + + org.apache.maven.plugins + maven-dependency-plugin + + + package + + copy-dependencies + + + ${project.build.directory}/modules + runtime + spring-boot-devtools + + + + + + org.apache.maven.plugins + maven-deploy-plugin + ${maven.plugin.deploy} + + + org.apache.maven.plugins + maven-source-plugin + ${maven.plugin.source} + + + org.apache.maven.plugins + maven-project-info-reports-plugin + ${maven.plugin.project.info.reports} + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.19.1 + + + + org.apache.maven.plugins maven-compiler-plugin - 3.8.0 - ${java.version} - ${java.version} + 1.8 + 1.8 true - UTF-8 + ${project.encoding} org.apache.maven.plugins maven-jar-plugin - 3.1.1 ${project.basedir}/*.xml @@ -83,12 +333,10 @@ org.apache.maven.plugins maven-deploy-plugin - 2.8.2 org.apache.maven.plugins maven-source-plugin - 3.0.1 package @@ -101,7 +349,37 @@ org.apache.maven.plugins maven-project-info-reports-plugin - 2.6 + + + org.jacoco + jacoco-maven-plugin + 0.8.6 + + + + prepare-agent + + + + report + test + + report + + + + + + org.codehaus.mojo + cobertura-maven-plugin + 2.7 + + + html + xml + + + diff --git a/src/main/java/org/starrier/common/annotation/README.md b/src/main/java/org/starrier/common/annotation/README.md new file mode 100644 index 0000000..9420568 --- /dev/null +++ b/src/main/java/org/starrier/common/annotation/README.md @@ -0,0 +1,18 @@ +# Annotation + +### 一. 接口防抖(防刷) + +> ```java +> @RateLimit +> ``` + + +### 二. 登录限制(次数) + +>```java +>@LoginLimt +>``` + + + + diff --git a/src/main/java/org/starrier/common/annotation/customer/DuplicateSubmitToken.java b/src/main/java/org/starrier/common/annotation/customer/DuplicateSubmitToken.java new file mode 100644 index 0000000..6d095d4 --- /dev/null +++ b/src/main/java/org/starrier/common/annotation/customer/DuplicateSubmitToken.java @@ -0,0 +1,23 @@ +package org.starrier.common.annotation.customer; + +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 Starrier + * @date 2018/12/9. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +@Documented +public @interface DuplicateSubmitToken { + + /** + * Save duplicate commit tags, default to true + */ + boolean save() default true; + +} diff --git a/src/main/java/org/starrier/common/annotation/customer/Http.java b/src/main/java/org/starrier/common/annotation/customer/Http.java new file mode 100644 index 0000000..e535c51 --- /dev/null +++ b/src/main/java/org/starrier/common/annotation/customer/Http.java @@ -0,0 +1,15 @@ +package org.starrier.common.annotation.customer; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; + +/** + * @author Starrier + * @date 2019/05/07 + */ +@Documented +@Target({ElementType.METHOD, ElementType.TYPE}) +public @interface Http { + +} diff --git a/src/main/java/org/starrier/common/annotation/customer/LockAnnotation.java b/src/main/java/org/starrier/common/annotation/customer/LockAnnotation.java new file mode 100644 index 0000000..47e5afe --- /dev/null +++ b/src/main/java/org/starrier/common/annotation/customer/LockAnnotation.java @@ -0,0 +1,31 @@ +package org.starrier.common.annotation.customer; + +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 Starrier + * @date 2018/12/21. + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD, ElementType.TYPE}) +public @interface LockAnnotation { + + /** + * 加锁的 key 的域,用于前缀识别. + * + * @return String. + */ + String lockField() default ""; + + /** + * 锁自定释放的时间. + * + * @return int. + */ + int lockTime() default 3; +} diff --git a/src/main/java/org/starrier/common/annotation/customer/LockParamAnnotation.java b/src/main/java/org/starrier/common/annotation/customer/LockParamAnnotation.java new file mode 100644 index 0000000..e910701 --- /dev/null +++ b/src/main/java/org/starrier/common/annotation/customer/LockParamAnnotation.java @@ -0,0 +1,21 @@ +package org.starrier.common.annotation.customer; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; + +/** + * @author Starrier + * @date 2018/12/21. + */ +@Documented +@Target({ElementType.PARAMETER, ElementType.TYPE}) +public @interface LockParamAnnotation { + + /** + * 参数的域,用于表明参数的业务场景,例如 orderSn. + * + * @return String. + */ + String value() default ""; +} diff --git a/src/main/java/org/starrier/common/annotation/customer/SysLogger.java b/src/main/java/org/starrier/common/annotation/customer/SysLogger.java new file mode 100644 index 0000000..6383ac0 --- /dev/null +++ b/src/main/java/org/starrier/common/annotation/customer/SysLogger.java @@ -0,0 +1,14 @@ +package org.starrier.common.annotation.customer; + +import java.lang.annotation.*; + +/** + * @author Starrier + * @date 2019/08/25 + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface SysLogger { + String value() default ""; +} diff --git a/src/main/java/org/starrier/common/annotation/customer/package-info.java b/src/main/java/org/starrier/common/annotation/customer/package-info.java new file mode 100644 index 0000000..0052110 --- /dev/null +++ b/src/main/java/org/starrier/common/annotation/customer/package-info.java @@ -0,0 +1,10 @@ +/** + * @version 0.0.1-SNAPSHOT + * @describe Customer Annotation + *

+ * {@link org.starrier.common.annotation.customer.DuplicateSubmitToken} + * @author Imperater + * @date 2019/08/25 + * @since 0.0.1-SNAPSHOT + */ +package org.starrier.common.annotation.customer; \ No newline at end of file diff --git a/src/main/java/org/starrier/common/annotation/logger/ExceptionLogger.java b/src/main/java/org/starrier/common/annotation/logger/ExceptionLogger.java new file mode 100644 index 0000000..caa4b12 --- /dev/null +++ b/src/main/java/org/starrier/common/annotation/logger/ExceptionLogger.java @@ -0,0 +1,15 @@ +package org.starrier.common.annotation.logger; + +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; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +@Documented +public @interface ExceptionLogger { + + Class[] value() default {Throwable.class}; +} diff --git a/src/main/java/org/starrier/common/annotation/logger/ExceptionNull.java b/src/main/java/org/starrier/common/annotation/logger/ExceptionNull.java new file mode 100644 index 0000000..831e278 --- /dev/null +++ b/src/main/java/org/starrier/common/annotation/logger/ExceptionNull.java @@ -0,0 +1,19 @@ +package org.starrier.common.annotation.logger; + +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 Starrier + * @date 2019/09/01 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +@Documented +public @interface ExceptionNull { + + Class[] value() default {Throwable.class}; +} diff --git a/src/main/java/org/starrier/common/annotation/logger/ExceptionZero.java b/src/main/java/org/starrier/common/annotation/logger/ExceptionZero.java new file mode 100644 index 0000000..ebe175d --- /dev/null +++ b/src/main/java/org/starrier/common/annotation/logger/ExceptionZero.java @@ -0,0 +1,19 @@ +package org.starrier.common.annotation.logger; + +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 Starrier + * @date 2019/09/01 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +@Documented +public @interface ExceptionZero { + + int exceptionZero() default 0; +} diff --git a/src/main/java/org/starrier/common/annotation/logger/package-info.java b/src/main/java/org/starrier/common/annotation/logger/package-info.java new file mode 100644 index 0000000..889034f --- /dev/null +++ b/src/main/java/org/starrier/common/annotation/logger/package-info.java @@ -0,0 +1,7 @@ +/** + * @author Starrier + * @date 2019/10/15 + * @version 0.0.1-SNAPSHOT + * @since 0.0.1-SNAPSHOT + */ +package org.starrier.common.annotation.logger; \ No newline at end of file diff --git a/src/main/java/org/starrier/common/annotation/loginlimt/LoginLimit.java b/src/main/java/org/starrier/common/annotation/loginlimt/LoginLimit.java new file mode 100644 index 0000000..936816e --- /dev/null +++ b/src/main/java/org/starrier/common/annotation/loginlimt/LoginLimit.java @@ -0,0 +1,36 @@ +package org.starrier.common.annotation.loginlimt; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; + +/** + * @author starrier + * @date 2020/12/31 + */ +@Documented +@Target({ElementType.METHOD,ElementType.ANNOTATION_TYPE}) +public @interface LoginLimit { + + /** + * 唯一标识符,用于登录校验 + */ + String identifier(); + + /** + * 在多长时间内监控, 如希望在 60s 内尝试 + * 次数限制为5次, 那么 watch=60; unit: s + */ + long watch() default 60; + + /** + * 锁定时长, unit: s + */ + long lock() default 60; + + /** + * 错误的尝试次数 + */ + int times() default 5; + +} diff --git a/src/main/java/org/starrier/common/annotation/loginlimt/LoginLimitAop.java b/src/main/java/org/starrier/common/annotation/loginlimt/LoginLimitAop.java new file mode 100644 index 0000000..aa6c03f --- /dev/null +++ b/src/main/java/org/starrier/common/annotation/loginlimt/LoginLimitAop.java @@ -0,0 +1,111 @@ +package org.starrier.common.annotation.loginlimt; + +import org.apache.commons.lang3.StringUtils; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.data.redis.core.ValueOperations; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; +import org.starrier.common.result.Result; +import parquet.org.slf4j.Logger; +import parquet.org.slf4j.LoggerFactory; + +import javax.security.auth.login.LoginException; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.concurrent.TimeUnit; + +/** + * @author starrier + * @date 2020/12/31 + */ +@Aspect +@Component +public class LoginLimitAop { + + private static final Logger LOGGER = LoggerFactory.getLogger(LoginLimitAop.class); + + private final StringRedisTemplate stringRedisTemplate; + + public LoginLimitAop(StringRedisTemplate stringRedisTemplate) { + this.stringRedisTemplate = stringRedisTemplate; + } + + @Around("@annotation(LoginLimit)") + public Object handleLimit(ProceedingJoinPoint joinPoint) { + + MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature(); + final Method method = methodSignature.getMethod(); + // TODO 直接将参数注入 + final LoginLimit loginLimit = method.getAnnotation(LoginLimit.class); + + // + final String identifier = loginLimit.identifier(); + final long watch = loginLimit.watch(); + final int times = loginLimit.times(); + final long lock = loginLimit.lock(); + + String identifierValue = null; + try { + final Object arg = joinPoint.getArgs()[0]; + final Field declaredField = arg.getClass().getDeclaredField(identifier); + declaredField.setAccessible(true); + identifierValue = (String) declaredField.get(arg); + } catch (NoSuchFieldException | IllegalAccessException e) { + LOGGER.error(">>> invalid identifier [{}], cannot find this field in request params", identifier); + } + if (StringUtils.isBlank(identifierValue)) { + LOGGER.error(">>> the value of RedisLimit.identifier cannot be blank, invalid identifier: {}", identifier); + return Result.error("login error"); + } + + // check User locked + final ValueOperations ssOps = stringRedisTemplate.opsForValue(); + final String flag = ssOps.get(identifierValue); + if (flag != null && "lock".contentEquals(flag)) { + + return new ResponseEntity<>(null, HttpStatus.OK); + } + + Object proceed = null; + try { + proceed = joinPoint.proceed(); + } catch (Throwable e) { + return handleLoginException(e, identifierValue, watch, times, lock); + } + return Result.success(proceed, "success"); + + } + + private Result handleLoginException(Throwable e, String identifierValue, final long watch, final int times, final long lock) { + + if (e instanceof LoginException) { + LOGGER.info(">>> handle login exception..."); + final ValueOperations ssOps = stringRedisTemplate.opsForValue(); + Boolean exist = stringRedisTemplate.hasKey(identifierValue); + if (exist == null || !exist) { + ssOps.set(identifierValue, "1", watch, TimeUnit.SECONDS); + return Result.success(); + } + + String count = ssOps.get(identifierValue); + if (StringUtils.isBlank(count)) { + return Result.error("not found"); + } + // has been reached the limitation + if (Integer.parseInt(count) + 1 == times) { + LOGGER.info(">>> [{}] has been reached the limitation and will be locked for {}s", identifierValue, lock); + ssOps.set(identifierValue, "lock", lock, TimeUnit.SECONDS); + return Result.success(); + } + ssOps.increment(identifierValue); + } + LOGGER.error(">>> RedisLimitAOP cannot handle {}", e.getClass().getName()); + return Result.success(); + } +} diff --git a/src/main/java/org/starrier/common/annotation/loginlimt/README.md b/src/main/java/org/starrier/common/annotation/loginlimt/README.md new file mode 100644 index 0000000..e69de29 diff --git a/src/main/java/org/starrier/common/annotation/loginlimt/package-info.java b/src/main/java/org/starrier/common/annotation/loginlimt/package-info.java new file mode 100644 index 0000000..7c9598c --- /dev/null +++ b/src/main/java/org/starrier/common/annotation/loginlimt/package-info.java @@ -0,0 +1 @@ +package org.starrier.common.annotation.loginlimt; \ No newline at end of file diff --git a/src/main/java/org/starrier/common/annotation/methodcount/MethodCount.java b/src/main/java/org/starrier/common/annotation/methodcount/MethodCount.java new file mode 100644 index 0000000..1c53496 --- /dev/null +++ b/src/main/java/org/starrier/common/annotation/methodcount/MethodCount.java @@ -0,0 +1,16 @@ +package org.starrier.common.annotation.methodcount; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; + +/** + * @author starrier + * @date 2021/1/4 + */ +@Documented +@Target({ElementType.METHOD,ElementType.TYPE}) +public @interface MethodCount { + + +} diff --git a/src/main/java/org/starrier/common/annotation/methodcount/MethodCountAop.java b/src/main/java/org/starrier/common/annotation/methodcount/MethodCountAop.java new file mode 100644 index 0000000..e05b604 --- /dev/null +++ b/src/main/java/org/starrier/common/annotation/methodcount/MethodCountAop.java @@ -0,0 +1,46 @@ +package org.starrier.common.annotation.methodcount; + +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.Signature; +import org.aspectj.lang.annotation.After; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.annotation.Pointcut; +import org.springframework.stereotype.Component; +import parquet.org.slf4j.Logger; +import parquet.org.slf4j.LoggerFactory; + +/** + * @author starrier + * @date 2021/1/4 + */ +@Aspect +@Component +public class MethodCountAop { + + private static final Logger LOGGER = LoggerFactory.getLogger(MethodCountAop.class); + + @Pointcut("@annotation(org.starrier.common.annotation.methodcount.MethodCount)") + public void methodCount() { + + } + + @Before("methodCount()") + public void before(JoinPoint joinPoint) { + Long startTime = System.currentTimeMillis(); + + Signature signature = joinPoint.getSignature(); + + String className = signature.getDeclaringTypeName(); + String methodName = signature.getName(); + + LOGGER.info("current method count class name is :[{}] and method is [{}]", className, methodName); + } + + @After("methodCount()") + public void after(ProceedingJoinPoint proceedingJoinPoint) { + + } + +} diff --git a/src/main/java/org/starrier/common/annotation/methodcount/README.md b/src/main/java/org/starrier/common/annotation/methodcount/README.md new file mode 100644 index 0000000..e69de29 diff --git a/src/main/java/org/starrier/common/annotation/package-info.java b/src/main/java/org/starrier/common/annotation/package-info.java new file mode 100644 index 0000000..d3233a0 --- /dev/null +++ b/src/main/java/org/starrier/common/annotation/package-info.java @@ -0,0 +1,7 @@ +/** + * @author Starrier + * @date 2019/05/08 + * @version 0.0.1-SNAPSHOT + * @since 0.0.1-SNAPSHOT + */ +package org.starrier.common.annotation; \ No newline at end of file diff --git a/src/main/java/org/starrier/common/annotation/ratelimiter/RateLimit.java b/src/main/java/org/starrier/common/annotation/ratelimiter/RateLimit.java new file mode 100644 index 0000000..aabb912 --- /dev/null +++ b/src/main/java/org/starrier/common/annotation/ratelimiter/RateLimit.java @@ -0,0 +1,28 @@ +package org.starrier.common.annotation.ratelimiter; + +import java.lang.annotation.*; + +/** + * Customer annotation rateLimiter. + * More detail in {@link com.google.common} + * + * @author Starrier + * @date 2019/1/3. + */ +@Documented +@Inherited +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface RateLimit { + + /** + * Add a token to the token bucket at a fixed rate per second. + */ + double limitNum() default 20; + + /** + * If the token is not obtained in the specified number, + * the service demotion process is taken directly. + */ + long timeout(); +} diff --git a/src/main/java/org/starrier/common/annotation/ratelimiter/package-info.java b/src/main/java/org/starrier/common/annotation/ratelimiter/package-info.java new file mode 100644 index 0000000..4581817 --- /dev/null +++ b/src/main/java/org/starrier/common/annotation/ratelimiter/package-info.java @@ -0,0 +1,7 @@ +/** + * @author Starrier + * @date 2019/10/15 + * @version 0.0.1-SNAPSHOT + * @since 0.0.1-SNAPSHOT + */ +package org.starrier.common.annotation.ratelimiter; \ No newline at end of file diff --git a/src/main/java/org/starrier/common/annotation/threadsafe/ThreadSafeClass.java b/src/main/java/org/starrier/common/annotation/threadsafe/ThreadSafeClass.java new file mode 100644 index 0000000..576c1e5 --- /dev/null +++ b/src/main/java/org/starrier/common/annotation/threadsafe/ThreadSafeClass.java @@ -0,0 +1,20 @@ +package org.starrier.common.annotation.threadsafe; + +import net.jcip.annotations.ThreadSafe; + +import java.lang.annotation.*; + +/** + * @author Starrier + * @date 2018/12/15. + */ +@Target({ElementType.TYPE, + ElementType.FIELD, + ElementType.ANNOTATION_TYPE, + ElementType.CONSTRUCTOR, +}) +@ThreadSafe +@Documented +@Retention(RetentionPolicy.RUNTIME) +public @interface ThreadSafeClass { +} diff --git a/src/main/java/org/starrier/common/annotation/threadsafe/ThreadSafeMethod.java b/src/main/java/org/starrier/common/annotation/threadsafe/ThreadSafeMethod.java new file mode 100644 index 0000000..1de71b2 --- /dev/null +++ b/src/main/java/org/starrier/common/annotation/threadsafe/ThreadSafeMethod.java @@ -0,0 +1,17 @@ +package org.starrier.common.annotation.threadsafe; + +import java.lang.annotation.*; + +/** + * @author Starrier + * @date 2018/12/15. + */ +@Target({ElementType.METHOD, + ElementType.FIELD, + ElementType.ANNOTATION_TYPE, + ElementType.CONSTRUCTOR, + ElementType.PARAMETER}) +@Documented +@Retention(RetentionPolicy.RUNTIME) +public @interface ThreadSafeMethod { +} diff --git a/src/main/java/org/starrier/common/annotation/threadsafe/ThreadSafeVariable.java b/src/main/java/org/starrier/common/annotation/threadsafe/ThreadSafeVariable.java new file mode 100644 index 0000000..ce4b16a --- /dev/null +++ b/src/main/java/org/starrier/common/annotation/threadsafe/ThreadSafeVariable.java @@ -0,0 +1,20 @@ +package org.starrier.common.annotation.threadsafe; + +import net.jcip.annotations.ThreadSafe; + +import java.lang.annotation.*; + +/** + * @author Starrier + * @date 2018/12/15. + */ +@Target({ElementType.METHOD, + ElementType.FIELD, + ElementType.ANNOTATION_TYPE, + ElementType.CONSTRUCTOR, + ElementType.PARAMETER}) +@ThreadSafe +@Documented +@Retention(RetentionPolicy.RUNTIME) +public @interface ThreadSafeVariable { +} diff --git a/src/main/java/org/starrier/common/annotation/threadsafe/package-info.java b/src/main/java/org/starrier/common/annotation/threadsafe/package-info.java new file mode 100644 index 0000000..0b66ccc --- /dev/null +++ b/src/main/java/org/starrier/common/annotation/threadsafe/package-info.java @@ -0,0 +1,7 @@ +/** + * @author Starrier + * @date 2019/10/15 + * @version 0.0.1-SNAPSHOT + * @since 0.0.1-SNAPSHOT + */ +package org.starrier.common.annotation.threadsafe; \ No newline at end of file diff --git a/src/main/java/org/starrier/common/constant/Constant.java b/src/main/java/org/starrier/common/constant/Constant.java index de6a700..b4740d3 100644 --- a/src/main/java/org/starrier/common/constant/Constant.java +++ b/src/main/java/org/starrier/common/constant/Constant.java @@ -10,12 +10,24 @@ public class Constant { /** * 敏感词匹配规则 - * - * 最小匹配规则,如:敏感词库["中国","中国人"],语句:"我是中国人",匹配结果:我是[中国]人 - * 最大匹配规则,如:敏感词库["中国","中国人"],语句:"我是中国人",匹配结果:我是[中国人] + *

+ * 最小匹配规则,如:敏感词库["中国","中国人"],语句:"我是中国人",匹配结果:我是[中国]人 + * 最大匹配规则,如:敏感词库["中国","中国人"],语句:"我是中国人",匹配结果:我是[中国人] */ - public static final int MinMatchTYpe = 1; + public static final int MIN_MATCH_T_YPE = 1; - public static final int MaxMatchType = 2; + public static final int MAX_MATCH_TYPE = 2; + + public static final String IS_END = "isEnd"; + + public static final String ONE = "1"; + + public static final String TWO = "2"; + + public static final String ZERO = "0"; + + public static final String UTF8 = "UTF-8"; + + public static final Integer FOUR = 4; } diff --git a/src/main/java/org/starrier/common/constant/DataConstant.java b/src/main/java/org/starrier/common/constant/DataConstant.java new file mode 100644 index 0000000..cce8eb3 --- /dev/null +++ b/src/main/java/org/starrier/common/constant/DataConstant.java @@ -0,0 +1,12 @@ +package org.starrier.common.constant; + +/** + * @author Starrier + * @date 2019/4/30 + */ +public class DataConstant { + public static final String DATE_FORMAT_DEFAULT = "yyyy-MM-dd"; + public static final String DATE_FORMAT_TIME = "yyyy-MM-dd HH:mm"; + public static final String DATE_FORMAT_ALL = "yyyy-MM-dd HH:mm:ss"; + public static final String DATE_CHINA_DEFAULT = "yyyy年MM月dd日"; +} diff --git a/src/main/java/org/starrier/common/constant/ExceptionLoggerHandler.java b/src/main/java/org/starrier/common/constant/ExceptionLoggerHandler.java new file mode 100644 index 0000000..3744d3b --- /dev/null +++ b/src/main/java/org/starrier/common/constant/ExceptionLoggerHandler.java @@ -0,0 +1,27 @@ +package org.starrier.common.constant; + +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.annotation.Pointcut; + +/** + * @author Starrier + * @date 2019/08/25 + */ +public class ExceptionLoggerHandler { + + @Pointcut("@annotation(org.starrier.common.annotation.logger.ExceptionLogger)") + public void log() { + } + + @Before("log()") + public void doBefore(JoinPoint joinPoint) { + + } + + @Around("log()") + public void around() { + + } +} diff --git a/src/main/java/org/starrier/common/constant/ExceptionNullHandler.java b/src/main/java/org/starrier/common/constant/ExceptionNullHandler.java new file mode 100644 index 0000000..dd4c7d6 --- /dev/null +++ b/src/main/java/org/starrier/common/constant/ExceptionNullHandler.java @@ -0,0 +1,21 @@ +package org.starrier.common.constant; + +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.annotation.Pointcut; + +/** + * @author Starrier + * @date 2019/08/25 + */ +public class ExceptionNullHandler { + + @Pointcut("@annotation(org.starrier.common.annotation.logger.ExceptionNull)") + public void log() { + } + + @Before("log()") + public Object doBefore(JoinPoint joinPoint) { + return null; + } +} diff --git a/src/main/java/org/starrier/common/constant/HttpConstant.java b/src/main/java/org/starrier/common/constant/HttpConstant.java new file mode 100644 index 0000000..9f7b352 --- /dev/null +++ b/src/main/java/org/starrier/common/constant/HttpConstant.java @@ -0,0 +1,36 @@ +package org.starrier.common.constant; + +/** + * @author Starrier + * @date 2019/05/07 + */ +public class HttpConstant { + + public static final String UNKNOWN = "unknown"; + + public static final String PROXY_CLIENT_IP = "Proxy-Client-IP"; + + public static final String WL_PROXY_CLIENT_IP = "WL-Proxy-Client-IP"; + + public static final String HTTP_CLIENT_IP = "HTTP_CLIENT_IP"; + + public static final String HTTP_X_FORWARDED_FOR = "HTTP_X_FORWARDED_FOR"; + + public static final String X_FORWARDED_FOR = "X-Forwarded-For"; + + public static final String POINT = ","; + + public static final String CLASS_NAME = "className"; + + public static final String CLASS_METHOD = "classMethod"; + + public static final String URL = "url"; + + public static final String METHOD = "method"; + + public static final String IP = "ip"; + + public static final String ARGS = "args"; + + public static final String REQUEST = "request: {}"; +} diff --git a/src/main/java/org/starrier/common/constant/ResourceNameConstant.java b/src/main/java/org/starrier/common/constant/ResourceNameConstant.java index 1c1c2c0..dbc356e 100644 --- a/src/main/java/org/starrier/common/constant/ResourceNameConstant.java +++ b/src/main/java/org/starrier/common/constant/ResourceNameConstant.java @@ -5,8 +5,8 @@ import lombok.Setter; /** - * @author Starrier - * @date 2018/6/5. + * @author Starrier + * @date 2018/6/5. */ @Getter @Setter @@ -20,7 +20,7 @@ public class ResourceNameConstant { /** * Prevent instantiation. - * + *

* And if you want to expose these,you can use annotation {@link NoArgsConstructor} */ private ResourceNameConstant() { diff --git a/src/main/java/org/starrier/common/constant/package-info.java b/src/main/java/org/starrier/common/constant/package-info.java new file mode 100644 index 0000000..38df356 --- /dev/null +++ b/src/main/java/org/starrier/common/constant/package-info.java @@ -0,0 +1,10 @@ +/** + * @author Starrier + * @date 2019/05/27 + * @version 0.0.1-SNAPSHOT + * @since 0.0.1-SNAPSHOT + */ +@Nonnull +package org.starrier.common.constant; + +import javax.annotation.Nonnull; \ No newline at end of file diff --git a/src/main/java/org/starrier/common/http/HttpAspect.java b/src/main/java/org/starrier/common/http/HttpAspect.java new file mode 100644 index 0000000..ce0b392 --- /dev/null +++ b/src/main/java/org/starrier/common/http/HttpAspect.java @@ -0,0 +1,96 @@ +package org.starrier.common.http; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.After; +import org.aspectj.lang.annotation.AfterReturning; +import org.aspectj.lang.annotation.AfterThrowing; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.annotation.Pointcut; +import org.springframework.stereotype.Component; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; +import parquet.org.slf4j.Logger; +import parquet.org.slf4j.LoggerFactory; + +import javax.servlet.http.HttpServletRequest; +import java.util.HashMap; +import java.util.Map; + + +import static org.starrier.common.constant.HttpConstant.ARGS; +import static org.starrier.common.constant.HttpConstant.CLASS_METHOD; +import static org.starrier.common.constant.HttpConstant.CLASS_NAME; +import static org.starrier.common.constant.HttpConstant.IP; +import static org.starrier.common.constant.HttpConstant.METHOD; +import static org.starrier.common.constant.HttpConstant.URL; + +/** + * @author Starrier + * @date 2018/11/6. + */ +@Aspect +@Component +public class HttpAspect { + + public static Logger LOGGER = LoggerFactory.getLogger(HttpAspect.class); + + @Pointcut("@annotation(org.starrier.common.annotation.customer.Http)") + public void log() { + } + + @Before("log()") + public void doBefore(JoinPoint joinPoint) { + + ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + HttpServletRequest request = null; + if (null != attributes) { + request = attributes.getRequest(); + } + Map params = new HashMap<>(); + if (null != request) { + params.put(URL, request.getRequestURL()); + } + if (null != request) { + params.put(METHOD, request.getMethod()); + } + if (null != request) { + params.put(IP, request.getRemoteAddr()); + } + params.put(CLASS_NAME, joinPoint.getSignature().getDeclaringTypeName()); + params.put(CLASS_METHOD, joinPoint.getSignature().getName()); + params.put(ARGS, joinPoint.getArgs()); + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + } + + @Around("log()") + public Object doAround(ProceedingJoinPoint point) { + try { + return point.proceed(); + } catch (Throwable throwable) { + return null; + } + } + + @After("log()") + public void doAfter() { + } + + /** + *

Fetch

+ * + * @param object + * @return return value + */ + @AfterReturning(returning = "object", pointcut = "log()") + public void doAfterReturning(Object object) { + } + + @AfterThrowing(pointcut = "log()") + public void doAfterThrowing() { + } +} diff --git a/src/main/java/org/starrier/common/http/package-info.java b/src/main/java/org/starrier/common/http/package-info.java new file mode 100644 index 0000000..cde913e --- /dev/null +++ b/src/main/java/org/starrier/common/http/package-info.java @@ -0,0 +1,7 @@ +/** + * @author Starrier + * @date 2019/10/15 + * @version 0.0.1-SNAPSHOT + * @since 0.0.1-SNAPSHOT + */ +package org.starrier.common.http; \ No newline at end of file diff --git a/src/main/java/org/starrier/common/pageHelper/PageConstant.java b/src/main/java/org/starrier/common/page/PageConstant.java similarity index 85% rename from src/main/java/org/starrier/common/pageHelper/PageConstant.java rename to src/main/java/org/starrier/common/page/PageConstant.java index 0b3d71b..1eb2dbb 100644 --- a/src/main/java/org/starrier/common/pageHelper/PageConstant.java +++ b/src/main/java/org/starrier/common/page/PageConstant.java @@ -1,33 +1,33 @@ -package org.starrier.common.pageHelper; - - -import lombok.Getter; -import lombok.Setter; - -/** - * @author Starrier - * @date 2018/6/5. - */ -@Getter -@Setter -public class PageConstant { - - /** - * Default page number - */ - public static final int PAGE = 1; - - /** - * Default size of per page - */ - public static final int PER_PAGE = 10; - - /** - * Prevent instantiation. - * - * And if you need expose, {@link lombok.NoArgsConstructor} instead of if. - */ - private PageConstant() { - } - -} +package org.starrier.common.page; + + +import lombok.Getter; +import lombok.Setter; + +/** + * @author Starrier + * @date 2018/6/5. + */ +@Getter +@Setter +public class PageConstant { + + /** + * Default page number + */ + public static final int PAGE = 1; + + /** + * Default size of per page + */ + public static final int PER_PAGE = 10; + + /** + * Prevent instantiation. + *

+ * And if you need expose, {@link lombok.NoArgsConstructor} instead of if. + */ + private PageConstant() { + } + +} diff --git a/src/main/java/org/starrier/common/pageHelper/PaginatedResult.java b/src/main/java/org/starrier/common/page/PaginatedResult.java similarity index 84% rename from src/main/java/org/starrier/common/pageHelper/PaginatedResult.java rename to src/main/java/org/starrier/common/page/PaginatedResult.java index 0b150a6..428ae0c 100644 --- a/src/main/java/org/starrier/common/pageHelper/PaginatedResult.java +++ b/src/main/java/org/starrier/common/page/PaginatedResult.java @@ -1,39 +1,38 @@ -package org.starrier.common.pageHelper; - - -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; -import lombok.ToString; -import lombok.experimental.Accessors; - -import java.io.Serializable; - -/** - * @author Starrier - * @date 2019/1/9. - */ -@Accessors(chain = true) -@NoArgsConstructor -@Getter -@Setter -@ToString -public class PaginatedResult implements Serializable { - - private static final long serialVersionUID = 6191745064790884707L; - /** - * Current page number - */ - private int currentPage; - - /** - * Number of total pages - */ - private int totalPage; - - /** - * Paginated resources - */ - private Object data; - +package org.starrier.common.page; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +/** + * @author Starrier + * @date 2019/1/9. + */ +@Accessors(chain = true) +@NoArgsConstructor +@Getter +@Setter +@ToString +public class PaginatedResult implements Serializable { + + private static final long serialVersionUID = 6191745064790884707L; + /** + * Current page number + */ + private int currentPage; + + /** + * Number of total pages + */ + private int totalPage; + + /** + * Paginated resources + */ + private Object data; + } \ No newline at end of file diff --git a/src/main/java/org/starrier/common/pageHelper/ParameterIllegalException.java b/src/main/java/org/starrier/common/page/ParameterIllegalException.java similarity index 61% rename from src/main/java/org/starrier/common/pageHelper/ParameterIllegalException.java rename to src/main/java/org/starrier/common/page/ParameterIllegalException.java index 1afeab8..c93d771 100644 --- a/src/main/java/org/starrier/common/pageHelper/ParameterIllegalException.java +++ b/src/main/java/org/starrier/common/page/ParameterIllegalException.java @@ -1,11 +1,11 @@ -package org.starrier.common.pageHelper; - -/** - * @author Starrier - * @date 2018/6/5. - */ -public class ParameterIllegalException extends RuntimeException { - - private static final long serialVersionUID = 8197086462208138875L; - -} +package org.starrier.common.page; + +/** + * @author Starrier + * @date 2018/6/5. + */ +public class ParameterIllegalException extends RuntimeException { + + private static final long serialVersionUID = 8197086462208138875L; + +} diff --git a/src/main/java/org/starrier/common/pageHelper/ParameterInvalidItem.java b/src/main/java/org/starrier/common/page/ParameterInvalidItem.java similarity index 81% rename from src/main/java/org/starrier/common/pageHelper/ParameterInvalidItem.java rename to src/main/java/org/starrier/common/page/ParameterInvalidItem.java index 73b5a1b..43de186 100644 --- a/src/main/java/org/starrier/common/pageHelper/ParameterInvalidItem.java +++ b/src/main/java/org/starrier/common/page/ParameterInvalidItem.java @@ -1,25 +1,24 @@ -package org.starrier.common.pageHelper; - -import lombok.Data; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -import java.io.Serializable; - -/** - * Controller 参数校验,错误返回封装 - * - * @author Starrier - * @date 2019/1/31. - */ -@Getter -@Setter -@NoArgsConstructor -public class ParameterInvalidItem implements Serializable { - - private String fieldName; - - private String message; - -} +package org.starrier.common.page; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.io.Serializable; + +/** + * Controller 参数校验,错误返回封装 + * + * @author Starrier + * @date 2019/1/31. + */ +@Getter +@Setter +@NoArgsConstructor +public class ParameterInvalidItem implements Serializable { + + private String fieldName; + + private String message; + +} diff --git a/src/main/java/org/starrier/common/pageHelper/ResourceNotFoundException.java b/src/main/java/org/starrier/common/page/ResourceNotFoundException.java similarity index 72% rename from src/main/java/org/starrier/common/pageHelper/ResourceNotFoundException.java rename to src/main/java/org/starrier/common/page/ResourceNotFoundException.java index f28c1af..378d15c 100644 --- a/src/main/java/org/starrier/common/pageHelper/ResourceNotFoundException.java +++ b/src/main/java/org/starrier/common/page/ResourceNotFoundException.java @@ -1,27 +1,28 @@ -package org.starrier.common.pageHelper; - -import lombok.Setter; -import lombok.experimental.Accessors; -import org.apache.commons.lang3.StringUtils; - -/** - * @author Starrier - * @date 2018/6/5. - */ - -@Accessors(chain = true) -@Setter -public class ResourceNotFoundException extends RuntimeException { - - private static final long serialVersionUID = -2565431806475335331L; - - private String resourceName; - - private Long id; - - @Override - public String getMessage() { - return StringUtils.capitalize(resourceName) + " with id " + id + " is not found."; - } - -} +package org.starrier.common.page; + +import lombok.AllArgsConstructor; +import lombok.Setter; +import lombok.experimental.Accessors; +import org.apache.commons.lang3.StringUtils; + +/** + * @author Starrier + * @date 2018/6/5. + */ +@Setter +@Accessors(chain = true) +@AllArgsConstructor +public class ResourceNotFoundException extends RuntimeException { + + private static final long serialVersionUID = -2565431806475335331L; + + private final String resourceName; + + private final Long id; + + @Override + public String getMessage() { + return StringUtils.capitalize(resourceName) + " with id " + id + " is not found."; + } + +} diff --git a/src/main/java/org/starrier/common/page/package-info.java b/src/main/java/org/starrier/common/page/package-info.java new file mode 100644 index 0000000..c08debe --- /dev/null +++ b/src/main/java/org/starrier/common/page/package-info.java @@ -0,0 +1,7 @@ +/** + * @author Starrier + * @date 2019/10/15 + * @version 0.0.1-SNAPSHOT + * @since 0.0.1-SNAPSHOT + */ +package org.starrier.common.page; \ No newline at end of file diff --git a/src/main/java/org/starrier/common/result/Result.java b/src/main/java/org/starrier/common/result/Result.java index 7bc94f7..41d01f5 100644 --- a/src/main/java/org/starrier/common/result/Result.java +++ b/src/main/java/org/starrier/common/result/Result.java @@ -1,10 +1,14 @@ package org.starrier.common.result; import com.google.common.collect.Maps; +import com.google.gson.annotations.SerializedName; +import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; +import lombok.NoArgsConstructor; import lombok.Setter; +import lombok.ToString; import lombok.experimental.Accessors; import java.io.Serializable; @@ -18,11 +22,12 @@ * @date 2018/11/11. * @see Result is the enhanced and custom version of response. */ -@AllArgsConstructor -@Builder @Accessors(chain = true) @Setter @Getter +@ToString +@AllArgsConstructor +@NoArgsConstructor(access = AccessLevel.PRIVATE) public class Result implements Serializable { private static final long serialVersionUID = -1709587390161841001L; @@ -33,19 +38,15 @@ public class Result implements Serializable { private String url; - public Object getData() { - return data; - } - - public void setData(Object data) { - this.data = data; - } - private Object data; - private Result() { + public Integer getCode() { + return code; } + private void setData(Object data) { + this.data = data; + } public Result(Integer errorCode, String errMessage) { this.code = errorCode; @@ -82,12 +83,26 @@ public static Result success(Object data) { return result; } + public static Result success(Object data,String message){ + Result result = new Result(); + result.setData(data); + result.setMessage(message); + return result; + } + public static Result error(ResultCode resultCode) { Result result = new Result(); result.setResultCode(resultCode); return result; } + public static Result error(String errorMessage) { + Result result = new Result(); + result.setResultCode(ResultCode.ERROR); + result.setMessage(errorMessage); + return result; + } + public static Result error(ResultCode resultCode, Object data) { Result result = new Result(); result.setResultCode(resultCode); @@ -95,4 +110,46 @@ public static Result error(ResultCode resultCode, Object data) { return result; } + public static Builder builder() { + return new Builder(); + } + + private Result(Builder builder) { + this.code = builder.code; + this.data = builder.data; + this.message = builder.message; + this.url = builder.url; + } + + @ToString + public static class Builder { + private Integer code; + private String message; + private String url; + private Object data; + + public Builder code(Integer code) { + this.code = code; + return this; + } + + public Builder data(Object data) { + this.data = data; + return this; + } + + public Builder message(String message) { + this.message = message; + return this; + } + + public Builder url(String url) { + this.url = url; + return this; + } + + public Result build() { + return new Result(this); + } + } } diff --git a/src/main/java/org/starrier/common/result/ResultCode.java b/src/main/java/org/starrier/common/result/ResultCode.java index ba2ead0..0435a24 100644 --- a/src/main/java/org/starrier/common/result/ResultCode.java +++ b/src/main/java/org/starrier/common/result/ResultCode.java @@ -5,6 +5,7 @@ * @date 2019/1/31. */ public enum ResultCode { + /* 成功状态码 */ SUCCESS(0, "成功"), ERROR(1, "失败"), @@ -15,6 +16,10 @@ public enum ResultCode { PARAM_TYPE_BIND_ERROR(10003, "参数类型错误"), PARAM_NOT_COMPLETE(10004, "参数缺失"), + /** + * MicroSoft + */ + /* 用户错误:20001-29999*/ USER_NOT_LOGGED_IN(20001, "用户未登录"), @@ -49,7 +54,9 @@ public enum ResultCode { /* 文件上传 */ UPLOAD_ERROR(80001, "上传失败"), - SESSION_TIME_OUT(90001, "Session超时"); + SESSION_TIME_OUT(90001, "Session超时"), + + REQUEST_LIMIT(10001, "请求次数受限"); private Integer code; diff --git a/src/main/java/org/starrier/common/result/package-info.java b/src/main/java/org/starrier/common/result/package-info.java new file mode 100644 index 0000000..da61188 --- /dev/null +++ b/src/main/java/org/starrier/common/result/package-info.java @@ -0,0 +1,7 @@ +/** + * @author Starrier + * @date 2019/10/15 + * @version 0.0.1-SNAPSHOT + * @since 0.0.1-SNAPSHOT + */ +package org.starrier.common.result; \ No newline at end of file diff --git a/src/main/java/org/starrier/common/token/DESBuilder.java b/src/main/java/org/starrier/common/token/DESBuilder.java index c304127..8b309e0 100644 --- a/src/main/java/org/starrier/common/token/DESBuilder.java +++ b/src/main/java/org/starrier/common/token/DESBuilder.java @@ -1,6 +1,8 @@ package org.starrier.common.token; import lombok.Cleanup; +import lombok.Getter; +import lombok.Setter; import lombok.SneakyThrows; import org.apache.commons.codec.binary.Base64; @@ -23,6 +25,8 @@ public class DESBuilder { + @Getter + @Setter private Key key; /** @@ -42,19 +46,11 @@ private void generatorRandomKey(String strKey) { KeyGenerator generator = KeyGenerator.getInstance(KEY_ALGORTHM); generator.init(new SecureRandom(strKey.getBytes())); this.key = generator.generateKey(); - generator = null; } catch (Exception e) { throw new RuntimeException("Error initializing SqlMap class. Cause: " + e); } } - /** - * @return Key对象 - */ - public Key getKey() { - return key; - } - /** * @return Key对象 */ @@ -65,11 +61,10 @@ public String getKeyToString() { /** * @return 文件 */ - public void getKeyToFile(String keyAddress)throws IOException,FileNotFoundException { - @Cleanup FileOutputStream fileOutput =null; - @Cleanup ObjectOutputStream objectOutput = null; - fileOutput = new FileOutputStream(keyAddress); - objectOutput = new ObjectOutputStream(fileOutput); - objectOutput.writeObject(this.key); + public void getKeyToFile(String keyAddress) throws IOException { + try (FileOutputStream fileOutput = new FileOutputStream(keyAddress); + ObjectOutputStream objectOutput = new ObjectOutputStream(fileOutput);) { + objectOutput.writeObject(this.key); + } } } \ No newline at end of file diff --git a/src/main/java/org/starrier/common/token/DESCoder.java b/src/main/java/org/starrier/common/token/DESCoder.java index 706b7a8..5266a74 100644 --- a/src/main/java/org/starrier/common/token/DESCoder.java +++ b/src/main/java/org/starrier/common/token/DESCoder.java @@ -3,7 +3,6 @@ import lombok.SneakyThrows; import org.apache.commons.codec.binary.Base64; -import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESKeySpec; import java.security.Key; @@ -19,14 +18,14 @@ public class DESCoder { @SneakyThrows(Exception.class) - private Key toKey(byte[] key) throws Exception { + private Key toKey(byte[] key) { DESKeySpec dks = new DESKeySpec(key); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(KEY_ALGORTHM); return keyFactory.generateSecret(dks); } @SneakyThrows(Exception.class) - public Key toKey(String key) throws Exception { + public Key toKey(String key) { byte[] keyBytes = Base64.decodeBase64(key); return toKey(keyBytes); } diff --git a/src/main/java/org/starrier/common/utils/TokenUtils.java b/src/main/java/org/starrier/common/token/TokenUtils.java similarity index 84% rename from src/main/java/org/starrier/common/utils/TokenUtils.java rename to src/main/java/org/starrier/common/token/TokenUtils.java index 358c92b..126e868 100644 --- a/src/main/java/org/starrier/common/utils/TokenUtils.java +++ b/src/main/java/org/starrier/common/token/TokenUtils.java @@ -1,11 +1,10 @@ -package org.starrier.common.utils; +package org.starrier.common.token; import com.google.common.collect.Maps; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import lombok.NonNull; -import org.starrier.common.token.DESCoder; import java.util.Collections; import java.util.Date; @@ -29,7 +28,7 @@ public class TokenUtils { * @param claims * @return */ - public static String generateToken(Map claims) throws Exception { + public static String generateToken(Map claims) { return Jwts.builder() .setClaims(claims) .setExpiration(new Date(System.currentTimeMillis() + 30000L)) @@ -43,7 +42,7 @@ public static String generateToken(Map claims) throws Exception * @param token 要解析的token信息 * @return */ - private static Optional getClaimsFromToken(String token) throws Exception { + private static Optional getClaimsFromToken(String token) { return Optional.ofNullable(Jwts.parser() .setSigningKey(new DESCoder().toKey(SECRET)) .parseClaimsJws(token) @@ -58,7 +57,7 @@ private static Optional getClaimsFromToken(String token) throws Exceptio */ public static boolean isExpired(String token) throws Exception { Optional claims = getClaimsFromToken(token); - return claims.filter((@NonNull var value) -> !value.getExpiration().before(new Date())).isPresent(); + return claims.filter(value -> !value.getExpiration().before(new Date())).isPresent(); } /** @@ -67,12 +66,12 @@ public static boolean isExpired(String token) throws Exception { * @param token 要解析的token信息 * @return */ - private static Map extractInfo(String token) throws Exception { + private static Map extractInfo(String token) { Optional claims = getClaimsFromToken(token); if (claims.isPresent()) { Set keySet = claims.get().keySet(); Map info = Maps.newHashMapWithExpectedSize(keySet.size()); - keySet.forEach((@NonNull var key) -> info.put(key, claims.get().get(key))); + keySet.forEach((@NonNull String key) -> info.put(key, claims.get().get(key))); return info; } return Collections.emptyMap(); diff --git a/src/main/java/org/starrier/common/token/package-info.java b/src/main/java/org/starrier/common/token/package-info.java new file mode 100644 index 0000000..cbe1099 --- /dev/null +++ b/src/main/java/org/starrier/common/token/package-info.java @@ -0,0 +1,7 @@ +/** + * @author Starrier + * @date 2019/10/15 + * @version 0.0.1-SNAPSHOT + * @since 0.0.1-SNAPSHOT + */ +package org.starrier.common.token; \ No newline at end of file diff --git a/src/main/java/org/starrier/common/utils/CornUtils.java b/src/main/java/org/starrier/common/utils/CornUtils.java new file mode 100644 index 0000000..1f0d6dd --- /dev/null +++ b/src/main/java/org/starrier/common/utils/CornUtils.java @@ -0,0 +1,8 @@ +package org.starrier.common.utils; + +/** + * @author imperator + * @date 2019-09-10 + */ +public class CornUtils { +} diff --git a/src/main/java/org/starrier/common/utils/DateUtils.java b/src/main/java/org/starrier/common/utils/DateUtils.java index 9275a57..40ad07f 100644 --- a/src/main/java/org/starrier/common/utils/DateUtils.java +++ b/src/main/java/org/starrier/common/utils/DateUtils.java @@ -1,42 +1,120 @@ package org.starrier.common.utils; +import com.google.common.collect.Lists; +import lombok.SneakyThrows; import org.apache.commons.lang3.StringUtils; import org.joda.time.DateTime; +import org.springframework.core.convert.converter.Converter; +import org.starrier.common.annotation.logger.ExceptionZero; import java.sql.Timestamp; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.Locale; +import java.util.TimeZone; + +import static org.starrier.common.constant.Constant.FOUR; +import static org.starrier.common.constant.DataConstant.DATE_FORMAT_DEFAULT; /** * @author Starrier * @date 2019/4/18 */ -public class DateUtils { +public class DateUtils implements Converter { + + private static final List FOR_MARTS = Lists.newArrayListWithExpectedSize(FOUR); + + public static final String FULL_TIME_PATTERN = "yyyyMMddHHmmss"; - public final static String DATE_FORMAT_DEFAULT = "yyyy-MM-dd"; - public final static String DATE_FORMAT_TIME = "yyyy-MM-dd HH:mm"; - public final static String DATE_FORMAT_ALL = "yyyy-MM-dd HH:mm:ss"; - public final static String DATE_CHINA_DEFAULT = "yyyy年MM月dd日"; + public static final String FULL_TIME_SPLIT_PATTERN = "yyyy-MM-dd HH:mm:ss"; + + public static final String CST_TIME_PATTERN = "EEE MMM dd HH:mm:ss zzz yyyy"; /** + * 格式化时间,格式为 yyyyMMddHHmmss * - * @param date - * @param num - * @return + * @param localDateTime LocalDateTime + * @return 格式化后的字符串 + */ + public static String formatFullTime(LocalDateTime localDateTime) { + return formatFullTime(localDateTime, FULL_TIME_PATTERN); + } + + /** + * 根据传入的格式,格式化时间 + * + * @param localDateTime LocalDateTime + * @param format 格式 + * @return 格式化后的字符串 + */ + public static String formatFullTime(LocalDateTime localDateTime, String format) { + DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(format); + return localDateTime.format(dateTimeFormatter); + } + + /** + * 根据传入的格式,格式化时间 + * + * @param date Date + * @param format 格式 + * @return 格式化后的字符串 + */ + public static String getDateFormat(Date date, String format) { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format, Locale.CHINA); + return simpleDateFormat.format(date); + } + + /** + * 格式化 CST类型的时间字符串 + * + * @param date CST类型的时间字符串 + * @param format 格式 + * @return 格式化后的字符串 + * @throws ParseException 异常 + */ + public static String formatCSTTime(String date, String format) throws ParseException { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat(CST_TIME_PATTERN, Locale.US); + Date usDate = simpleDateFormat.parse(date); + return DateUtils.getDateFormat(usDate, format); + } + + /** + * 格式化 Instant + * + * @param instant Instant + * @param format 格式 + * @return 格式化后的字符串 + */ + public static String formatInstant(Instant instant, String format) { + LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault()); + return localDateTime.format(DateTimeFormatter.ofPattern(format)); + } + + /** + * @param date {@link String} + * @param num {@link Integer} + * @return {@link String} */ public static String getDay(String date, int num) { return getDay(date, num, DATE_FORMAT_DEFAULT); } /** - * * @param date * @param num * @param format * @return */ public static String getDay(String date, int num, String format) { - long t = parseStringToLong(date); - return getDay(t, num, DATE_FORMAT_DEFAULT); + return getDay(parseStringToLong(date), num, DATE_FORMAT_DEFAULT); } /** @@ -51,7 +129,8 @@ public static String getDay(long date, int num) { } /** - * 获取指定日期前后num天的日期 + * 获取指定日期前后num天的日期 + * * @param date * @param num * @param format @@ -85,8 +164,7 @@ public static String longToString(long time, String format) { if (StringUtils.isBlank(format)) { format = DATE_FORMAT_DEFAULT; } - DateTime dTime = new DateTime(time); - return dTime.toString(format); + return new DateTime().toString(format); } /** @@ -148,93 +226,136 @@ public static String getCurrentTime() { * 获得当前时间 * * @param format 日期格式 - * @return + * @return {@link String} */ public static String getCurrentTime(String format) { - DateTime dTime = new DateTime(); - return dTime.toString(format); + return new DateTime().toString(format); } /** * 将字符串类型的日期转换为毫秒数 * - * @param dateStr - * @return + * @param dateStr is the start of time. + * @return {@link Long} */ + @ExceptionZero public static long parseStringToLong(String dateStr) { dateStr = dateStr.trim(); + Calendar cal = Calendar.getInstance(); if (dateStr.length() == 19 || dateStr.length() == 23) { - try { - Calendar cal = Calendar.getInstance(); - cal.set(Integer.parseInt(dateStr.substring(0, 4)), - Integer.parseInt(dateStr.substring(5, 7)) - 1, - Integer.parseInt(dateStr.substring(8, 10)), - Integer.parseInt(dateStr.substring(11, 13)), - Integer.parseInt(dateStr.substring(14, 16)), - Integer.parseInt(dateStr.substring(17, 19))); - cal.set(Calendar.MILLISECOND, 0); - return (cal.getTime().getTime()); - } catch (Exception e) { - return 0; - } + cal.set(Integer.parseInt(dateStr.substring(0, 4)), + Integer.parseInt(dateStr.substring(5, 7)) - 1, + Integer.parseInt(dateStr.substring(8, 10)), + Integer.parseInt(dateStr.substring(11, 13)), + Integer.parseInt(dateStr.substring(14, 16)), + Integer.parseInt(dateStr.substring(17, 19))); + cal.set(Calendar.MILLISECOND, 0); + return (cal.getTime().getTime()); } else if (dateStr.length() == 16) { - try { - Calendar cal = Calendar.getInstance(); - cal.set(Integer.parseInt(dateStr.substring(0, 4)), - Integer.parseInt(dateStr.substring(5, 7)) - 1, - Integer.parseInt(dateStr.substring(8, 10)), - Integer.parseInt(dateStr.substring(11, 13)), - Integer.parseInt(dateStr.substring(14, 16))); - cal.set(Calendar.MILLISECOND, 0); - return (cal.getTime().getTime()); - } catch (Exception e) { - return 0; - } - + cal.set(Integer.parseInt(dateStr.substring(0, 4)), + Integer.parseInt(dateStr.substring(5, 7)) - 1, + Integer.parseInt(dateStr.substring(8, 10)), + Integer.parseInt(dateStr.substring(11, 13)), + Integer.parseInt(dateStr.substring(14, 16))); + cal.set(Calendar.MILLISECOND, 0); + return (cal.getTime().getTime()); } else if (dateStr.length() == 14) { - try { - Calendar cal = Calendar.getInstance(); - cal.set(Integer.parseInt(dateStr.substring(0, 4)), - Integer.parseInt(dateStr.substring(4, 6)) - 1, - Integer.parseInt(dateStr.substring(6, 8)), - Integer.parseInt(dateStr.substring(8, 10)), - Integer.parseInt(dateStr.substring(10, 12)), - Integer.parseInt(dateStr.substring(12, 14))); - cal.set(Calendar.MILLISECOND, 0); - return (cal.getTime().getTime()); - } catch (Exception e) { - return 0; - } + cal.set(Integer.parseInt(dateStr.substring(0, 4)), + Integer.parseInt(dateStr.substring(4, 6)) - 1, + Integer.parseInt(dateStr.substring(6, 8)), + Integer.parseInt(dateStr.substring(8, 10)), + Integer.parseInt(dateStr.substring(10, 12)), + Integer.parseInt(dateStr.substring(12, 14))); + cal.set(Calendar.MILLISECOND, 0); + return (cal.getTime().getTime()); } else if (dateStr.length() == 10 || dateStr.length() == 11) { - try { - Calendar cal = Calendar.getInstance(); - cal.set(Integer.parseInt(dateStr.substring(0, 4)), - Integer.parseInt(dateStr.substring(5, 7)) - 1, - Integer.parseInt(dateStr.substring(8, 10)), 0, 0, 0); - cal.set(Calendar.MILLISECOND, 0); - return (cal.getTime().getTime()); - } catch (Exception e) { - return 0; - } + cal.set(Integer.parseInt(dateStr.substring(0, 4)), + Integer.parseInt(dateStr.substring(5, 7)) - 1, + Integer.parseInt(dateStr.substring(8, 10)), 0, 0, 0); + cal.set(Calendar.MILLISECOND, 0); + return (cal.getTime().getTime()); } else if (dateStr.length() == 8) { - try { - Calendar cal = Calendar.getInstance(); - cal.set(Integer.parseInt(dateStr.substring(0, 4)), - Integer.parseInt(dateStr.substring(4, 6)) - 1, - Integer.parseInt(dateStr.substring(6, 8)), 0, 0, 0); - cal.set(Calendar.MILLISECOND, 0); - return (cal.getTime().getTime()); - } catch (Exception e) { - return 0; - } + cal.set(Integer.parseInt(dateStr.substring(0, 4)), + Integer.parseInt(dateStr.substring(4, 6)) - 1, + Integer.parseInt(dateStr.substring(6, 8)), 0, 0, 0); + cal.set(Calendar.MILLISECOND, 0); + return (cal.getTime().getTime()); } else { - try { - return Long.parseLong(dateStr); - } catch (Exception e) { - return 0; - } + return Long.parseLong(dateStr); + } + } + + static { + FOR_MARTS.add("yyyy-MM"); + FOR_MARTS.add("yyyy-MM-dd"); + FOR_MARTS.add("yyyy-MM-dd hh:mm"); + FOR_MARTS.add("yyyy-MM-dd hh:mm:ss"); + } + + @Override + public Date convert(String source) { + String value = source.trim(); + if (StringUtils.EMPTY.equals(value)) { + return null; + } + if (source.matches("^\\d{4}-\\d{1,2}$")) { + return parseDate(source, FOR_MARTS.get(0)); + } else if (source.matches("^\\d{4}-\\d{1,2}-\\d{1,2}$")) { + return parseDate(source, FOR_MARTS.get(1)); + } else if (source.matches("^\\d{4}-\\d{1,2}-\\d{1,2} {1}\\d{1,2}:\\d{1,2}$")) { + return parseDate(source, FOR_MARTS.get(2)); + } else if (source.matches("^\\d{4}-\\d{1,2}-\\d{1,2} {1}\\d{1,2}:\\d{1,2}:\\d{1,2}$")) { + return parseDate(source, FOR_MARTS.get(3)); + } else { + throw new IllegalArgumentException("Invalid boolean value '" + source + "'"); } } + + + /** + * 格式化日期 + * + * @param dateStr String 字符型日期 + * @param format String 格式 + * @return Date 日期 + */ + @SneakyThrows(Exception.class) + public Date parseDate(String dateStr, String format) { + DateFormat dateFormat = new SimpleDateFormat(format); + return dateFormat.parse(dateStr); + } + + /** + * 根据时间戳,获取当天凌晨时间 2019-10-18 00:00:00.0 + * + * @return {@link Timestamp} + */ + public static Timestamp getCurrentDayStartTime() { + //当日零点零分零秒的毫秒数 + long zero = todayZeroTime(); + return new Timestamp(zero); + } + + /** + * 根据时间戳,获取当天最晚时间段 2019-10-18 23:59:59.999 + * + * @return {@link Timestamp} + */ + public static Timestamp getCurrentDayEndTime() { + long zero = todayZeroTime(); + //今天23点59分59秒的毫秒数 + long twelve = zero + 24 * 60 * 60 * 1000 - 1; + return new Timestamp(twelve); + } + + /** + * 今天零点零分零秒的毫秒数 + * + * @return 今天零点零分零秒的毫秒数 + */ + private static long todayZeroTime(){ + return System.currentTimeMillis() / (1000 * 3600 * 24) * (1000 * 3600 * 24) - TimeZone.getDefault().getRawOffset(); + } } \ No newline at end of file diff --git a/src/main/java/org/starrier/common/utils/FastJsonUtils.java b/src/main/java/org/starrier/common/utils/FastJsonUtils.java new file mode 100644 index 0000000..2cf9c0b --- /dev/null +++ b/src/main/java/org/starrier/common/utils/FastJsonUtils.java @@ -0,0 +1,58 @@ +package org.starrier.common.utils; + +import java.util.List; +import java.util.Map; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + +/** + * @author imperator + * @date 2019-09-10 + */ +public class FastJsonUtils { + + /** + * 功能描述:把JSON数据转换成指定的java对象 + * + * @param jsonData JSON数据 + * @param clazz 指定的java对象 + * @return 指定的java对象 + */ + public static T getJsonToBean(String jsonData, Class clazz) { + return JSON.parseObject(jsonData, clazz); + } + + /** + * 功能描述:把java对象转换成JSON数据 + * + * @param object java对象 + * @return JSON数据 + */ + public static String getBeanToJson(Object object) { + return JSON.toJSONString(object); + } + + /** + * 功能描述:把JSON数据转换成指定的java对象列表 + * + * @param jsonData JSON数据 + * @param clazz 指定的java对象 + * @return List + */ + public static List getJsonToList(String jsonData, Class clazz) { + return JSON.parseArray(jsonData, clazz); + } + + /** + * 功能描述:把JSON数据转换成较为复杂的List> + * + * @param jsonData JSON数据 + * @return List> + */ + public static List> getJsonToListMap(String jsonData) { + return JSON.parseObject(jsonData, new TypeReference>>() { + }); + } + +} diff --git a/src/main/java/org/starrier/common/utils/FetchSensitiveWordUtil.java b/src/main/java/org/starrier/common/utils/FetchSensitiveWordUtil.java new file mode 100644 index 0000000..ead1ea5 --- /dev/null +++ b/src/main/java/org/starrier/common/utils/FetchSensitiveWordUtil.java @@ -0,0 +1,57 @@ +package org.starrier.common.utils; + +import com.google.common.collect.Maps; +import lombok.Cleanup; +import lombok.SneakyThrows; +import org.apache.commons.lang3.StringUtils; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; + +/** + * @author Starrier + * @date 2018/12/13. + */ +public class FetchSensitiveWordUtil { + + /** + * @param filePath {@link String} + * @return {@link Map } + */ + @SneakyThrows(IOException.class) + public Map fetchSensitiveWords(final String filePath) { + + Map wordsMaps = Maps.newHashMap(); + File file = new File(filePath); + int count = 0; + if (!file.isFile() || !file.exists()) { + return new HashMap<>(); + } + + @Cleanup InputStreamReader reader = new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8); + @Cleanup BufferedReader bufferedReader = new BufferedReader(reader); + + String lineText = null; + while ((lineText = bufferedReader.readLine()) != null) { + + if (StringUtils.isBlank(lineText)) { + continue; + } + + String readers = lineText.split("\\+")[0]; + wordsMaps.put(count, readers); + count++; + + } + + return wordsMaps; + + } + +} diff --git a/src/main/java/org/starrier/common/utils/FormatUtil.java b/src/main/java/org/starrier/common/utils/FormatUtil.java new file mode 100644 index 0000000..b7d9e5c --- /dev/null +++ b/src/main/java/org/starrier/common/utils/FormatUtil.java @@ -0,0 +1,8 @@ +package org.starrier.common.utils; + +/** + * @author imperator + * @date 2019-09-10 + */ +public class FormatUtil { +} diff --git a/src/main/java/org/starrier/common/utils/GsonUtil.java b/src/main/java/org/starrier/common/utils/GsonUtil.java new file mode 100644 index 0000000..83c3758 --- /dev/null +++ b/src/main/java/org/starrier/common/utils/GsonUtil.java @@ -0,0 +1,99 @@ +package org.starrier.common.utils; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; + +import java.util.List; +import java.util.Map; + +/** + * @author imperator + * @date 2019-09-10 + */ +public class GsonUtil { + private static Gson gson = null; + + static { + if (gson == null) { + gson = new Gson(); + } + } + + private GsonUtil() { + } + + /** + * 对象转成json + * + * @param object + * @return json + */ + public static String gsonString(Object object) { + String gsonString = null; + if (gson != null) { + gsonString = gson.toJson(object); + } + return gsonString; + } + + /** + * Json转成对象 + * + * @param gsonString + * @param cls + * @return 对象 + */ + public static T gsonToBean(String gsonString, Class cls) { + T t = null; + if (gson != null) { + t = gson.fromJson(gsonString, cls); + } + return t; + } + + /** + * json转成list + * + * @param gsonString + * @param cls + * @return list + */ + public static List gsonToList(String gsonString, Class cls) { + List list = null; + if (gson != null) { + list = gson.fromJson(gsonString, new TypeToken>() { + }.getType()); + } + return list; + } + + /** + * json转成list中有map的 + * + * @param gsonString + * @return List> + */ + public static List> gsonToListMaps(String gsonString) { + List> list = null; + if (gson != null) { + list = gson.fromJson(gsonString, new TypeToken>>() { + }.getType()); + } + return list; + } + + /** + * json转成map的 + * + * @param gsonString + * @return Map + */ + public static Map gsonToMaps(String gsonString) { + Map map = null; + if (gson != null) { + map = gson.fromJson(gsonString, new TypeToken>() { + }.getType()); + } + return map; + } +} diff --git a/src/main/java/org/starrier/common/utils/HttpUtils.java b/src/main/java/org/starrier/common/utils/HttpUtils.java new file mode 100644 index 0000000..9477de8 --- /dev/null +++ b/src/main/java/org/starrier/common/utils/HttpUtils.java @@ -0,0 +1,89 @@ +package org.starrier.common.utils; + +import com.google.common.collect.Maps; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletRequest; +import java.util.Enumeration; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +import static org.starrier.common.constant.HttpConstant.HTTP_CLIENT_IP; +import static org.starrier.common.constant.HttpConstant.HTTP_X_FORWARDED_FOR; +import static org.starrier.common.constant.HttpConstant.POINT; +import static org.starrier.common.constant.HttpConstant.PROXY_CLIENT_IP; +import static org.starrier.common.constant.HttpConstant.UNKNOWN; +import static org.starrier.common.constant.HttpConstant.WL_PROXY_CLIENT_IP; +import static org.starrier.common.constant.HttpConstant.X_FORWARDED_FOR; + +/** + * @author Starrier + * @date 018/10/31. + */ +public class HttpUtils { + + /** + * 尝试获取当前请求 HttpServletRequest 实例 + * + * @return HttpServletRequest + */ + public static HttpServletRequest getHttpServletRequest() { + return Optional.of(((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest()).orElse(null); + } + + public static Map getHeaders(HttpServletRequest request) { + Enumeration enumeration = request.getHeaderNames(); + Map map = Maps.newLinkedHashMap(); + while (enumeration.hasMoreElements()) { + map.put(enumeration.nextElement(), request.getHeader(enumeration.nextElement())); + } + return map; + } + + /** + * 获取请求客户端的真实 IP 地址 + * + * @return IP 地址 + */ + public static String getIpAddress() { + return getIpAddress(getHttpServletRequest()); + } + + /** + * 获取请求客户端的真实ip地址,如果通过代理进来,则透过防火墙获取真实IP地址 + * + * @param request 请求对象 + * @return ip地址 + */ + public static String getIpAddress(HttpServletRequest request) { + String ip = request.getHeader(X_FORWARDED_FOR); + if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) { + if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) { + ip = request.getHeader(PROXY_CLIENT_IP); + } + if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) { + ip = request.getHeader(WL_PROXY_CLIENT_IP); + } + if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) { + ip = request.getHeader(HTTP_CLIENT_IP); + } + if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) { + ip = request.getHeader(HTTP_X_FORWARDED_FOR); + } + if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) { + ip = request.getRemoteAddr(); + } + } else if (ip.length() > 15) { + String[] ips = POINT.split(ip); + for (String s : ips) { + if (!(s.equalsIgnoreCase(UNKNOWN))) { + ip = s; + break; + } + } + } + return ip; + } +} diff --git a/src/main/java/org/starrier/common/utils/IpUtil.java b/src/main/java/org/starrier/common/utils/IpUtil.java new file mode 100644 index 0000000..ff88556 --- /dev/null +++ b/src/main/java/org/starrier/common/utils/IpUtil.java @@ -0,0 +1,43 @@ +package org.starrier.common.utils; + +import javax.servlet.http.HttpServletRequest; + +/** + * @author imperator + * @date 2019-09-10 + */ +public class IpUtil { + + /** + * 获取客户端真实ip地址 + * + * @param request + * @return + */ + public static String getIpAddress(HttpServletRequest request) { + String ip = request.getHeader("x-forwarded-for"); + + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("Proxy-Client-IP"); + } + + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("WL-Proxy-Client-IP"); + } + + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("HTTP_CLIENT_IP"); + } + + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("HTTP_X_FORWARDED_FOR"); + } + + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getRemoteAddr(); + } + + return ip; + } + +} diff --git a/src/main/java/org/starrier/common/utils/JedisUtil.java b/src/main/java/org/starrier/common/utils/JedisUtil.java new file mode 100644 index 0000000..093dbc0 --- /dev/null +++ b/src/main/java/org/starrier/common/utils/JedisUtil.java @@ -0,0 +1,187 @@ +package org.starrier.common.utils; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import parquet.org.slf4j.Logger; +import parquet.org.slf4j.LoggerFactory; +import redis.clients.jedis.Jedis; +import redis.clients.jedis.JedisPool; + +/** + * @author imperator + * @date 2019-09-10 + */ +@Component +public class JedisUtil { + + private static final Logger LOGGER = LoggerFactory.getLogger(JedisUtil.class); + @Autowired + private JedisPool jedisPool; + + private Jedis getJedis() { + return jedisPool.getResource(); + } + + /** + * 设值 + * + * @param key + * @param value + * @return + */ + public String set(String key, String value) { + Jedis jedis = null; + try { + jedis = getJedis(); + return jedis.set(key, value); + } catch (Exception e) { + LOGGER.error("set key: {} value: {} error", key, value, e); + return null; + } finally { + close(jedis); + } + } + + /** + * 设值 + * + * @param key + * @param value + * @param expireTime 过期时间, 单位: s + * @return + */ + public String set(String key, String value, int expireTime) { + Jedis jedis = null; + try { + jedis = getJedis(); + return jedis.setex(key, expireTime, value); + } catch (Exception e) { + LOGGER.error("set key:{} value:{} expireTime:{} error", key, value, expireTime, e); + return null; + } finally { + close(jedis); + } + } + + /** + * 设值 + * + * @param key + * @param value + * @return + */ + public Long setnx(String key, String value) { + Jedis jedis = null; + try { + jedis = getJedis(); + return jedis.setnx(key, value); + } catch (Exception e) { + LOGGER.error("set key:{} value:{} error", key, value, e); + return null; + } finally { + close(jedis); + } + } + + /** + * 取值 + * + * @param key + * @return + */ + public String get(String key) { + Jedis jedis = null; + try { + jedis = getJedis(); + return jedis.get(key); + } catch (Exception e) { + LOGGER.error("get key:{} error", key, e); + return null; + } finally { + close(jedis); + } + } + + /** + * 删除key + * + * @param key + * @return + */ + public Long del(String key) { + Jedis jedis = null; + try { + jedis = getJedis(); + return jedis.del(key.getBytes()); + } catch (Exception e) { + LOGGER.error("del key:{} error", key, e); + return null; + } finally { + close(jedis); + } + } + + /** + * 判断key是否存在 + * + * @param key + * @return + */ + public Boolean exists(String key) { + Jedis jedis = null; + try { + jedis = getJedis(); + return jedis.exists(key.getBytes()); + } catch (Exception e) { + LOGGER.error("exists key:{} error", key, e); + return null; + } finally { + close(jedis); + } + } + + /** + * 设值key过期时间 + * + * @param key + * @param expireTime 过期时间, 单位: s + * @return + */ + public Long expire(String key, int expireTime) { + Jedis jedis = null; + try { + jedis = getJedis(); + return jedis.expire(key.getBytes(), expireTime); + } catch (Exception e) { + LOGGER.error("expire key:{} error", key, e); + return null; + } finally { + close(jedis); + } + } + + /** + * 获取剩余时间 + * + * @param key + * @return + */ + public Long ttl(String key) { + Jedis jedis = null; + try { + jedis = getJedis(); + return jedis.ttl(key); + } catch (Exception e) { + LOGGER.error("ttl key:{} error", key, e); + return null; + } finally { + close(jedis); + } + } + + private void close(Jedis jedis) { + if (null != jedis) { + jedis.close(); + } + } +} diff --git a/src/main/java/org/starrier/common/utils/JodaTimeUtil.java b/src/main/java/org/starrier/common/utils/JodaTimeUtil.java new file mode 100644 index 0000000..3db72b4 --- /dev/null +++ b/src/main/java/org/starrier/common/utils/JodaTimeUtil.java @@ -0,0 +1,291 @@ +package org.starrier.common.utils; + +import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.Contract; +import org.joda.time.DateTime; +import org.joda.time.format.DateTimeFormat; +import org.joda.time.format.DateTimeFormatter; +import parquet.org.slf4j.Logger; +import parquet.org.slf4j.LoggerFactory; + +import java.util.Date; + +/** + * @author imperator + * @date 2019-09-10 + */ +public class JodaTimeUtil { + + private static final String STANDARD_FORMAT = "yyyy-MM-dd HH:mm:ss"; + + private static final Logger LOGGER = LoggerFactory.getLogger(JodaTimeUtil.class); + + /** + * date类型 -> string类型 + * + * @param date + * @return + */ + @Contract("null -> null") + public static String dateToStr(Date date) { + if (date == null) { + return null; + } + return dateToStr(date, STANDARD_FORMAT); + } + + /** + * date类型 -> string类型 + * + * @param date + * @param format 自定义日期格式 + * @return + */ + public static String dateToStr(Date date, String format) { + if (date == null) { + return null; + } + + format = StringUtils.isBlank(format) ? STANDARD_FORMAT : format; + DateTime dateTime = new DateTime(date); + return dateTime.toString(format); + } + + /** + * string类型 -> date类型 + * + * @param timeStr + * @return + */ + public static Date strToDate(String timeStr) { + return strToDate(timeStr, STANDARD_FORMAT); + } + + /** + * string类型 -> date类型 + * + * @param timeStr + * @param format 自定义日期格式 + * @return + */ + public static Date strToDate(String timeStr, String format) { + if (StringUtils.isBlank(timeStr)) { + return null; + } + + format = StringUtils.isBlank(format) ? STANDARD_FORMAT : format; + + DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern(format); + DateTime dateTime; + try { + dateTime = dateTimeFormatter.parseDateTime(timeStr); + } catch (Exception e) { + LOGGER.error("strToDate error: timeStr: {}", timeStr, e); + return null; + } + + return dateTime.toDate(); + } + + /** + * 判断date日期是否过期(与当前时刻比较) + * + * @param date + * @return + */ + public static Boolean isTimeExpired(Date date) { + String timeStr = dateToStr(date); + return isBeforeNow(timeStr); + } + + /** + * 判断date日期是否过期(与当前时刻比较) + * + * @param timeStr + * @return + */ + public static Boolean isTimeExpired(String timeStr) { + if (StringUtils.isBlank(timeStr)) { + return true; + } + + return isBeforeNow(timeStr); + } + + /** + * 判断timeStr是否在当前时刻之前 + * + * @param timeStr + * @return + */ + private static Boolean isBeforeNow(String timeStr) { + DateTimeFormatter format = DateTimeFormat.forPattern(STANDARD_FORMAT); + DateTime dateTime; + try { + dateTime = DateTime.parse(timeStr, format); + } catch (Exception e) { + LOGGER.error("isBeforeNow error: timeStr: {}", timeStr, e); + return null; + } + return dateTime.isBeforeNow(); + } + + /** + * 日期加天数 + * + * @param date + * @param days + * @return + */ + public static Date plusDays(Date date, int days) { + return plusOrMinusDays(date, days, 0); + } + + /** + * 日期减天数 + * + * @param date + * @param days + * @return + */ + public static Date minusDays(Date date, int days) { + return plusOrMinusDays(date, days, 1); + } + + /** + * 加减天数 + * + * @param date + * @param days + * @param type 0:加天数 1:减天数 + * @return + */ + private static Date plusOrMinusDays(Date date, int days, Integer type) { + if (null == date) { + return null; + } + + DateTime dateTime = new DateTime(date); + if (type == 0) { + dateTime = dateTime.plusDays(days); + } else { + dateTime = dateTime.minusDays(days); + } + + return dateTime.toDate(); + } + + /** + * 日期加分钟 + * + * @param date + * @param minutes + * @return + */ + public static Date plusMinutes(Date date, int minutes) { + return plusOrMinusMinutes(date, minutes, 0); + } + + /** + * 日期减分钟 + * + * @param date + * @param minutes + * @return + */ + public static Date minusMinutes(Date date, int minutes) { + return plusOrMinusMinutes(date, minutes, 1); + } + + /** + * 加减分钟 + * + * @param date + * @param minutes + * @param type 0:加分钟 1:减分钟 + * @return + */ + private static Date plusOrMinusMinutes(Date date, int minutes, Integer type) { + + if (date == null) { + return null; + } + DateTime dateTime = new DateTime(date); + if (type == 0) { + dateTime = dateTime.plusMinutes(minutes); + } else { + dateTime = dateTime.minusMinutes(minutes); + } + + return dateTime.toDate(); + } + + public static void main(String[] args) { + Date date = plusOrMinusMinutes(null, 1, new Integer(2)); + System.out.println(date); + } + + /** + * 日期加月份 + * + * @param date + * @param months + * @return + */ + public static Date plusMonths(Date date, int months) { + return plusOrMinusMonths(date, months, 0); + } + + /** + * 日期减月份 + * + * @param date + * @param months + * @return + */ + public static Date minusMonths(Date date, int months) { + return plusOrMinusMonths(date, months, 1); + } + + /** + * 加减月份 + * + * @param date + * @param months + * @param type 0:加月份 1:减月份 + * @return + */ + private static Date plusOrMinusMonths(Date date, int months, Integer type) { + if (null == date) { + return null; + } + + DateTime dateTime = new DateTime(date); + if (type == 0) { + dateTime = dateTime.plusMonths(months); + } else { + dateTime = dateTime.minusMonths(months); + } + + return dateTime.toDate(); + } + + /** + * 判断target是否在开始和结束时间之间 + * + * @param target + * @param startTime + * @param endTime + * @return + */ + public static Boolean isBetweenStartAndEndTime(Date target, Date startTime, Date endTime) { + if (null == target || null == startTime || null == endTime) { + return false; + } + + DateTime dateTime = new DateTime(target); + return dateTime.isAfter(startTime.getTime()) && dateTime.isBefore(endTime.getTime()); + } + +} + diff --git a/src/main/java/org/starrier/common/utils/PageUtil.java b/src/main/java/org/starrier/common/utils/PageUtil.java index a30b47c..cc0a068 100644 --- a/src/main/java/org/starrier/common/utils/PageUtil.java +++ b/src/main/java/org/starrier/common/utils/PageUtil.java @@ -1,7 +1,7 @@ package org.starrier.common.utils; import lombok.SneakyThrows; -import org.starrier.common.pageHelper.ParameterIllegalException; +import org.starrier.common.page.ParameterIllegalException; /** * @author Starrier diff --git a/src/main/java/org/starrier/common/utils/RandomUtil.java b/src/main/java/org/starrier/common/utils/RandomUtil.java new file mode 100644 index 0000000..1f553ee --- /dev/null +++ b/src/main/java/org/starrier/common/utils/RandomUtil.java @@ -0,0 +1,123 @@ +package org.starrier.common.utils; + +import java.util.Random; +import java.util.UUID; + +/** + * @author imperator + * @date 2019-09-10 + */ +public class RandomUtil { + public static final String allChar = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + public static final String letterChar = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + public static final String numberChar = "0123456789"; + + public static String UUID32() { + String str = UUID.randomUUID().toString(); + return str.replaceAll("-", ""); + } + + public static String UUID36() { + return UUID.randomUUID().toString(); + } + + /** + * 生成包含大、小写字母、数字的字符串 + * + * @param length + * @return 如: zsK8rCCi + */ + public static String generateStr(int length) { + StringBuffer sb = new StringBuffer(); + Random random = new Random(); + for (int i = 0; i < length; i++) { + sb.append(allChar.charAt(random.nextInt(allChar.length()))); + } + return sb.toString(); + } + + /** + * 生成纯数字字符串 + * + * @param length + * @return 如: 77914 + */ + public static String generateDigitalStr(int length) { + StringBuffer sb = new StringBuffer(); + Random random = new Random(); + for (int i = 0; i < length; i++) { + sb.append(numberChar.charAt(random.nextInt(numberChar.length()))); + } + return sb.toString(); + } + + /** + * 生成只包含大小写字母的字符串 + * + * @param length + * @return 如: XetrWaYc + */ + public static String generateLetterStr(int length) { + StringBuffer sb = new StringBuffer(); + Random random = new Random(); + for (int i = 0; i < length; i++) { + sb.append(letterChar.charAt(random.nextInt(letterChar.length()))); + } + return sb.toString(); + } + + /** + * 生成只包含小写字母的字符串 + * + * @param length + * @return 如: nzcaunmk + */ + public static String generateLowerStr(int length) { + return generateLetterStr(length).toLowerCase(); + } + + /** + * 生成只包含大写字母的字符串 + * + * @param length + * @return 如: KZMQXSXW + */ + public static String generateUpperStr(int length) { + return generateLetterStr(length).toUpperCase(); + } + + /** + * 生成纯0字符串 + * + * @param length + * @return 如: 00000000 + */ + public static String generateZeroStr(int length) { + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < length; i++) { + sb.append('0'); + } + return sb.toString(); + } + + /** + * 根据数字生成字符串,长度不够前面补0 + * + * @param num 数字 + * @param strLength 字符串长度 + * @return 如: 00000099 + */ + public static String generateStrWithZero(int num, int strLength) { + StringBuffer sb = new StringBuffer(); + String strNum = String.valueOf(num); + if (strLength - strNum.length() >= 0) { + sb.append(generateZeroStr(strLength - strNum.length())); + } else { + throw new RuntimeException("将数字" + num + "转化为长度为" + strLength + "的字符串异常!"); + } + sb.append(strNum); + return sb.toString(); + } +} diff --git a/src/main/java/org/starrier/common/utils/RandomUtils.java b/src/main/java/org/starrier/common/utils/RandomUtils.java index e86c4ab..15cb90c 100644 --- a/src/main/java/org/starrier/common/utils/RandomUtils.java +++ b/src/main/java/org/starrier/common/utils/RandomUtils.java @@ -15,8 +15,7 @@ public class RandomUtils { * Get two random number * * @param length number length - * - * */ + */ public static String randomNum(int length) { StringBuilder builder = new StringBuilder(); Random random = new Random(); diff --git a/src/main/java/org/starrier/common/utils/RedisUtils.java b/src/main/java/org/starrier/common/utils/RedisUtils.java new file mode 100644 index 0000000..8cccca6 --- /dev/null +++ b/src/main/java/org/starrier/common/utils/RedisUtils.java @@ -0,0 +1,26 @@ +package org.starrier.common.utils; + +import org.springframework.data.redis.core.StringRedisTemplate; + +import javax.annotation.Resource; + +/** + * Redis Utils + * + * @author imperator + * @date 2019-10-15 + */ +public class RedisUtils { + + @Resource + private StringRedisTemplate redisTemplate; + + public Boolean existKeyInHash(String hashName, String key) { + return redisTemplate.opsForHash().hasKey(hashName, key); + } + + public void putKeyValueInHash(String hashName, String key, String value) { + redisTemplate.opsForHash().put(hashName, key, value); + } + +} diff --git a/src/main/java/org/starrier/common/utils/RedissionUtils.java b/src/main/java/org/starrier/common/utils/RedissionUtils.java new file mode 100644 index 0000000..87eacd8 --- /dev/null +++ b/src/main/java/org/starrier/common/utils/RedissionUtils.java @@ -0,0 +1,26 @@ +package org.starrier.common.utils; + + +/** + * @author Starrier + * @date 7/28/2019 + */ +public class RedissionUtils { + + private static RedissionUtils redissionUtils; + + private RedissionUtils() { + + } + + public static RedissionUtils getInstance() { + if (redissionUtils == null) { + synchronized (RedissionUtils.class) { + if (redissionUtils == null) { + redissionUtils = new RedissionUtils(); + } + } + } + return redissionUtils; + } +} diff --git a/src/main/java/org/starrier/common/utils/RegexUtil.java b/src/main/java/org/starrier/common/utils/RegexUtil.java new file mode 100644 index 0000000..c52c65b --- /dev/null +++ b/src/main/java/org/starrier/common/utils/RegexUtil.java @@ -0,0 +1,99 @@ +package org.starrier.common.utils; + +import org.apache.commons.lang3.StringUtils; + +import java.util.regex.Pattern; + +/** + * 正则表达式 + * + * @author imperator + * @date 2019-09-10 + */ +public class RegexUtil { + /** + * 验证手机号 + */ + private static final String REGEX_MOBILE = "^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199|(147))\\d{8}$"; + /** + * 验证邮箱 + */ + private static final String REGEX_EMAIL = "^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$"; + /** + * 验证汉字 + */ + private static final String REGEX_CHINESE = "^[\u4e00-\u9fa5],{0,}$"; + /** + * 验证身份证 + */ + private static final String REGEX_ID_CARD = "(^\\d{18}$)|(^\\d{15}$)"; + /** + * 验证URL + */ + private static final String REGEX_URL = "http(s)?://([\\w-]+\\.)+[\\w-]+(/[\\w- ./?%&=]*)?"; + /** + * 验证IP地址 + */ + private static final String REGEX_IP_ADDR = "(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)"; + + /** + * 手机号 + * + * @param mobile mobile + * @return boolean + */ + public static boolean isMobile(String mobile) { + return StringUtils.isNotBlank(mobile) && Pattern.matches(REGEX_MOBILE, mobile); + } + + /** + * 邮箱 + * + * @param email email + * @return boolean + */ + public static boolean isEmail(String email) { + return StringUtils.isNotBlank(email) && Pattern.matches(REGEX_EMAIL, email); + } + + /** + * 汉字 + * + * @param chinese chinese + * @return boolean + */ + public static boolean isChinese(String chinese) { + return StringUtils.isNotBlank(chinese) && Pattern.matches(REGEX_CHINESE, chinese); + } + + /** + * 身份证 + * + * @param idCard id card + * @return boolean + */ + public static boolean isIDCard(String idCard) { + return StringUtils.isNotBlank(idCard) && Pattern.matches(REGEX_ID_CARD, idCard); + } + + /** + * URL + * + * @param url url + * @return boolean + */ + public static boolean isUrl(String url) { + return StringUtils.isNotBlank(url) && Pattern.matches(REGEX_URL, url); + } + + /** + * IP地址 + * + * @param ipAddr ip address + * @return boolean + */ + public static boolean isIPAddr(String ipAddr) { + return StringUtils.isNotBlank(ipAddr) && Pattern.matches(REGEX_IP_ADDR, ipAddr); + } + +} diff --git a/src/main/java/org/starrier/common/utils/ScheduleUtil.java b/src/main/java/org/starrier/common/utils/ScheduleUtil.java new file mode 100644 index 0000000..0d6f443 --- /dev/null +++ b/src/main/java/org/starrier/common/utils/ScheduleUtil.java @@ -0,0 +1,78 @@ +package org.starrier.common.utils; + +import java.util.HashMap; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +/** + * @author imperator + * @date 2019-09-10 + */ +public class ScheduleUtil { + /*该接口定义了线程的名字,用于管理,如判断是否存活,是否停止该线程等等*/ + public interface SRunnable extends Runnable { + String getName(); + } + + private static HashMap map = new HashMap<>(); + private static ScheduledExecutorService pool; + + public static void init() { + pool = Executors.newScheduledThreadPool(3); + } + + /** + * @param sr 需要执行测线程,该线程必须继承SRunnable + * @param delay 延迟执行时间 + * @param period 执行周期时间 + * @param unit 时间单位 比如TimeUnit.SECONDS + */ + public static void stard(SRunnable sr, long delay, long period, TimeUnit unit) { + if (sr.getName() == null || map.get(sr.getName()) != null) { + throw new UnsupportedOperationException("线程名不能为空或者线程名不能重复!"); + } + if (pool == null || pool.isShutdown()) init(); + ScheduledFuture scheduledFuture = pool.scheduleAtFixedRate(sr, delay, period, unit); + map.put(sr.getName(), scheduledFuture); + } + + /** + * @param sr 停止当前正在执行的线程,该线程必须是继承SRunnable + */ + public static void stop(SRunnable sr) { + if (sr.getName() == null) { + throw new UnsupportedOperationException("停止线程时,线程名不能为空!"); + } + if (pool == null || pool.isShutdown()) return;//服务未启动 + if (map.size() > 0 && map.get(sr.getName()) != null) { + map.get(sr.getName()).cancel(true); + map.remove(sr.getName()); + } + if (map.size() <= 0) { + shutdown(); + } + } + + /** + * 停止所有线程服务 + */ + public static void shutdown() { + map.clear(); + pool.shutdown(); + } + + /** + * 判断该线程是否还存活着,还在运行 + * + * @param sr + * @return + */ + public static boolean isAlive(SRunnable sr) { + if (map.size() > 0 && map.get(sr.getName()) != null) { + return !map.get(sr.getName()).isDone(); + } + return false; + } +} diff --git a/src/main/java/org/starrier/common/utils/SensitiveWordUtil.java b/src/main/java/org/starrier/common/utils/SensitiveWordUtil.java index 4f10ced..f854a44 100644 --- a/src/main/java/org/starrier/common/utils/SensitiveWordUtil.java +++ b/src/main/java/org/starrier/common/utils/SensitiveWordUtil.java @@ -1,19 +1,21 @@ package org.starrier.common.utils; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.stream.IntStream; -import static org.starrier.common.constant.Constant.MaxMatchType; -import static org.starrier.common.constant.Constant.MinMatchTYpe; +import static org.starrier.common.constant.Constant.IS_END; +import static org.starrier.common.constant.Constant.MAX_MATCH_TYPE; +import static org.starrier.common.constant.Constant.MIN_MATCH_T_YPE; +import static org.starrier.common.constant.Constant.ONE; +import static org.starrier.common.constant.Constant.ZERO; /** * @author Starrier @@ -21,7 +23,6 @@ *

* Description : */ -@NoArgsConstructor @Getter @Setter public class SensitiveWordUtil { @@ -29,7 +30,7 @@ public class SensitiveWordUtil { /** * 敏感词集合 */ - public static HashMap sensitiveWordMap; + public static Map sensitiveWordMap; /** * 初始化敏感词库,构建DFA算法模型 @@ -37,7 +38,7 @@ public class SensitiveWordUtil { * @param sensitiveWordSet 敏感词库 */ public static synchronized void init(Set sensitiveWordSet) { - sensitiveWordSet = Sets.newHashSetWithExpectedSize(7); + sensitiveWordSet = new HashSet<>(7); sensitiveWordSet.add("太多"); sensitiveWordSet.add("爱恋"); sensitiveWordSet.add("静静"); @@ -48,22 +49,27 @@ public static synchronized void init(Set sensitiveWordSet) { initSensitiveWordMap(sensitiveWordSet); } + private SensitiveWordUtil() { + init(null); + } + /** - * 初始化敏感词库,构建DFA算法模型 + * 初始化敏感词库,构建 DFA 算法模型 * * @param sensitiveWordSet 敏感词库 */ + @SuppressWarnings({"rawtypes", "unchecked"}) private static void initSensitiveWordMap(Set sensitiveWordSet) { //初始化敏感词容器,减少扩容操作 - sensitiveWordMap = new HashMap(sensitiveWordSet.size()); + sensitiveWordMap = new HashMap<>(sensitiveWordSet.size()); String key; Map nowMap; - Map newWorMap; + Map newWorMap; + //迭代sensitiveWordSet - Iterator iterator = sensitiveWordSet.iterator(); - while (iterator.hasNext()) { + for (String s : sensitiveWordSet) { //关键字 - key = iterator.next(); + key = s; nowMap = sensitiveWordMap; for (int i = 0; i < key.length(); i++) { //转换成char型 @@ -75,15 +81,15 @@ private static void initSensitiveWordMap(Set sensitiveWordSet) { nowMap = (Map) wordMap; } else { //不存在则,则构建一个map,同时将isEnd设置为0,因为他不是最后一个 - newWorMap = Maps.newHashMapWithExpectedSize(sensitiveWordSet.size()); + newWorMap = new HashMap<>(sensitiveWordSet.size()); //不是最后一个 - newWorMap.put("isEnd", "0"); + newWorMap.put(IS_END, ZERO); nowMap.put(keyChar, newWorMap); nowMap = newWorMap; } if (i == key.length() - 1) { //最后一个 - nowMap.put("isEnd", "1"); + nowMap.put(IS_END, ONE); } } } @@ -113,7 +119,7 @@ private static boolean contains(String txt, int matchType) { * @return 若包含返回true,否则返回false */ public static boolean contains(String txt) { - return contains(txt, MaxMatchType); + return contains(txt, MAX_MATCH_TYPE); } /** @@ -124,7 +130,7 @@ public static boolean contains(String txt) { * @return Set */ private static Set getSensitiveWord(String txt, int matchType) { - Set sensitiveWordList = Sets.newHashSetWithExpectedSize(txt.length()); + Set sensitiveWordList = new HashSet<>(txt.length()); IntStream.range(0, txt.length()).forEach(i -> { int length = checkSensitiveWord(txt, i, matchType); //存在,加入list中 @@ -144,7 +150,7 @@ private static Set getSensitiveWord(String txt, int matchType) { * @return return. */ public static Set getSensitiveWord(String txt) { - return getSensitiveWord(txt, MaxMatchType); + return getSensitiveWord(txt, MAX_MATCH_TYPE); } /** @@ -156,7 +162,7 @@ public static Set getSensitiveWord(String txt) { * @param matchType 敏感词匹配规则 * @return return */ - public static String replaceSensitiveWord(String txt, char replaceChar, int matchType) { + private static String replaceSensitiveWord(String txt, char replaceChar, int matchType) { String resultTxt = txt; //获取所有的敏感词 Set set = getSensitiveWord(txt, matchType); @@ -178,11 +184,10 @@ public static String replaceSensitiveWord(String txt, char replaceChar, int matc * @param txt 文本 * @param replaceChar 替换的字符,匹配的敏感词以字符逐个替换, * 如 语句:我爱中国人 敏感词:中国人,替换字符:*, 替换结果:我爱*** - * @param replaceChar 替换的字符,匹配的敏感词以字符逐个替换,如 语句:我爱中国人 敏感词:中国人,替换字符:*, 替换结果:我爱*** - * @return + * @return result come from {@see SensitiveWordUtil#replaceSensitiveWord(String, char)} */ public static String replaceSensitiveWord(String txt, char replaceChar) { - return replaceSensitiveWord(txt, replaceChar, MaxMatchType); + return replaceSensitiveWord(txt, replaceChar, MAX_MATCH_TYPE); } /** @@ -194,7 +199,7 @@ public static String replaceSensitiveWord(String txt, char replaceChar) { * @param matchType 敏感词匹配规则 * @return return */ - public static String replaceSensitiveWord(String txt, String replaceStr, int matchType) { + private static String replaceSensitiveWord(String txt, String replaceStr, int matchType) { String resultTxt = txt; //获取所有的敏感词 Set set = getSensitiveWord(txt, matchType); @@ -216,7 +221,7 @@ public static String replaceSensitiveWord(String txt, String replaceStr, int mat * @return return. */ public static String replaceSensitiveWord(String txt, String replaceStr) { - return replaceSensitiveWord(txt, replaceStr, MaxMatchType); + return replaceSensitiveWord(txt, replaceStr, MAX_MATCH_TYPE); } /** @@ -227,7 +232,12 @@ public static String replaceSensitiveWord(String txt, String replaceStr) { * @return return. */ private static String getReplaceChars(char replaceChar, int length) { - return String.valueOf(replaceChar) + String.valueOf(replaceChar).repeat(Math.max(0, length - 1)); + //In JDK 11+ + /*return String.valueOf(replaceChar) + String.valueOf( ).repeat(Math.max(0, length - 1));*/ + /** + * In JDK 1.8 + */ + return null; } /** @@ -258,7 +268,7 @@ private static int checkSensitiveWord(String txt, int beginIndex, int matchType) //结束标志位为true flag = true; //最小规则,直接返回,最大规则还需继续查找 - if (MinMatchTYpe == matchType) { + if (MIN_MATCH_T_YPE == matchType) { break; } } diff --git a/src/main/java/org/starrier/common/utils/SerializableUtil.java b/src/main/java/org/starrier/common/utils/SerializableUtil.java new file mode 100644 index 0000000..e5f6188 --- /dev/null +++ b/src/main/java/org/starrier/common/utils/SerializableUtil.java @@ -0,0 +1,52 @@ +package org.starrier.common.utils; + +import parquet.org.slf4j.Logger; +import parquet.org.slf4j.LoggerFactory; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; + +/** + * @author imperator + * @date 2019-09-10 + */ +public class SerializableUtil { + + + private static final Logger LOGGER = LoggerFactory.getLogger(SerializableUtil.class); + + /** + * 序列化 + * + * @param object + * @return + */ + public static byte[] serializable(Object object) { + + try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos);) { + oos.writeObject(object); + return baos.toByteArray(); + } catch (IOException e) { + LOGGER.error("serializable异常: " + e.getMessage()); + throw new RuntimeException("serializable异常: " + e.getMessage()); + } + } + + /** + * 反序列化 + * + * @param bytes + * @return + */ + public static Object unserializable(byte[] bytes) { + try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes); ObjectInputStream ois = new ObjectInputStream(bais)) { + return ois.readObject(); + } catch (Exception e) { + throw new RuntimeException("unserializable异常: " + e.getMessage()); + } + } + +} diff --git a/src/main/java/org/starrier/common/utils/SignUtils.java b/src/main/java/org/starrier/common/utils/SignUtils.java new file mode 100644 index 0000000..1b61919 --- /dev/null +++ b/src/main/java/org/starrier/common/utils/SignUtils.java @@ -0,0 +1,49 @@ +package org.starrier.common.utils; + +import com.alibaba.fastjson.JSONObject; +import lombok.extern.slf4j.Slf4j; +import org.springframework.util.DigestUtils; +import org.springframework.util.StringUtils; +import parquet.org.slf4j.Logger; +import parquet.org.slf4j.LoggerFactory; + +import java.util.SortedMap; + +/** + * 验签工具 + * + * @author imperator + * @date 2019-09-23 + */ +public class SignUtils { + + private static final Logger LOGGER = LoggerFactory.getLogger(SignUtils.class); + + /** + * 验签 + * + * @param params + * @param sign + * @param timestamp + * @return + */ + public static boolean verifySign(SortedMap params, String sign, Long timestamp) { + String paramsJson = "Timestamp" + timestamp + JSONObject.toJSONString(params); + return verifySign(paramsJson, sign); + } + + public static boolean verifySign(String params, String sign) { + LOGGER.info("Header sign:[{}]", sign); + if (StringUtils.isEmpty(params)) { + return false; + } + LOGGER.info("Params:[{}]", params); + String paramSign = getParamsSign(params); + LOGGER.info("Param sign:[{}]", paramSign); + return sign.equals(paramSign); + } + + private static String getParamsSign(String params) { + return DigestUtils.md5DigestAsHex(params.getBytes()).toUpperCase(); + } +} diff --git a/src/main/java/org/starrier/common/utils/ValidatorUtil.java b/src/main/java/org/starrier/common/utils/ValidatorUtil.java new file mode 100644 index 0000000..c76564a --- /dev/null +++ b/src/main/java/org/starrier/common/utils/ValidatorUtil.java @@ -0,0 +1,24 @@ +package org.starrier.common.utils; + + +import org.apache.commons.lang3.StringUtils; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @Author Starrier + * @Time 2018/11/17. + */ +public class ValidatorUtil { + + private static final Pattern MOBILE_PATTERN = Pattern.compile("1\\d{10}"); + + public static boolean isMobile(String src) { + if (StringUtils.isEmpty(src)) { + return false; + } + Matcher matcher = MOBILE_PATTERN.matcher(src); + return matcher.matches(); + } +} diff --git a/src/main/java/org/starrier/common/utils/encrypt/AES2Utils.java b/src/main/java/org/starrier/common/utils/encrypt/AES2Utils.java new file mode 100644 index 0000000..728eff8 --- /dev/null +++ b/src/main/java/org/starrier/common/utils/encrypt/AES2Utils.java @@ -0,0 +1,49 @@ +package org.starrier.common.utils.encrypt; + +import org.apache.commons.codec.binary.Hex; + +/** + * @author starrier + * @date 2021/1/2 + */ +public class AES2Utils { + + /** + * 加密 + * + * @param encryptContent 待加密信息 + * @return 加密字符串 + * @throws Exception 加密过程中可能出现的异常信息 + */ + public static String encrypt(String encryptContent) throws Exception { + + if ("".equals(encryptContent) || encryptContent == null) { + throw new Exception("current encrypt info not allow blank"); + } + + byte[] encrypt = AESUtils.encrypt(encryptContent); + + return Hex.encodeHexString(encrypt); + + } + + /** + * 解密 + * + * @param encryptContent 加密后的加密信息 + * @return 解密后的原始信息 + * @throws Exception 加密过程中可能出现的异常信息 + */ + public static String decrypt(String encryptContent) throws Exception { + + if ("".equals(encryptContent) || encryptContent == null) { + throw new Exception("current decrypt info not allow blank"); + } + + byte[] encryptBytes = Hex.decodeHex(encryptContent.toCharArray()); + byte[] decrypt = AESUtils.decrypt(encryptBytes); + + return new String(decrypt); + } + +} diff --git a/src/main/java/org/starrier/common/utils/encrypt/AESUtils.java b/src/main/java/org/starrier/common/utils/encrypt/AESUtils.java new file mode 100644 index 0000000..e42fe0d --- /dev/null +++ b/src/main/java/org/starrier/common/utils/encrypt/AESUtils.java @@ -0,0 +1,126 @@ +package org.starrier.common.utils.encrypt; + +import javax.crypto.Cipher; +import javax.crypto.KeyGenerator; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; +import java.nio.charset.StandardCharsets; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.util.Base64; + +/** + * @author starrier + * @date 2020/12/28 + */ +public class AESUtils { + + private static final String SEED = "custom.ase.key"; + private static final String ALGORITHM = "AES"; + + /** + * 加密 + * + * @param content + * @return + * @throws Exception + */ + public static byte[] encrypt(String content) throws Exception { + + if ("".equals(content) || content == null) { + throw new Exception("encrypt content not allow blank"); + } + SecretKey secretKey = getSecretKey(); + return encryptAES(content.getBytes(StandardCharsets.UTF_8), secretKey); + + } + + /** + * 解密 + * + * @param encrypt + * @return + * @throws Exception + */ + public static byte[] decrypt(byte[] encrypt) throws Exception { + + SecretKey secretKey = getSecretKey(); + return decryptAES(encrypt, secretKey); + + } + + + /** + * 获得一个 密钥长度为 256 位的 AES 密钥, + * + * @return 返回经 BASE64 处理之后的密钥字符串 + */ + public static String getStrKeyAES() throws NoSuchAlgorithmException { + + SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG"); + secureRandom.setSeed(SEED.getBytes()); + + KeyGenerator keyGen = KeyGenerator.getInstance(ALGORITHM); + // 这里可以是 128、192、256、越大越安全 + keyGen.init(256, secureRandom); + + SecretKey secretKey = keyGen.generateKey(); + return Base64.getEncoder().encodeToString(secretKey.getEncoded()); + + } + + /** + * 将使用 Base64 加密后的字符串类型的 secretKey 转为 SecretKey + * + * @param strKey + * @return SecretKey + */ + public static SecretKey strKey2SecretKey(String strKey) { + + byte[] bytes = Base64.getDecoder().decode(strKey); + return new SecretKeySpec(bytes, ALGORITHM); + + } + + /** + * 加密 + * + * @param content 待加密内容 + * @param secretKey 加密使用的 AES 密钥 + * @return 加密后的密文 byte[] + */ + public static byte[] encryptAES(byte[] content, SecretKey secretKey) throws Exception { + + Cipher cipher = Cipher.getInstance(ALGORITHM); + cipher.init(Cipher.ENCRYPT_MODE, secretKey); + return cipher.doFinal(content); + + } + + /** + * 解密 + * + * @param content 待解密内容 + * @param secretKey 解密使用的 AES 密钥 + * @return 解密后的明文 byte[] + */ + public static byte[] decryptAES(byte[] content, SecretKey secretKey) throws Exception { + + Cipher cipher = Cipher.getInstance(ALGORITHM); + cipher.init(Cipher.DECRYPT_MODE, secretKey); + return cipher.doFinal(content); + + } + + public static SecretKey getSecretKey() throws NoSuchAlgorithmException { + + // 获得经 BASE64 处理之后的 AES 密钥 + String strKeyAES = getStrKeyAES(); + + // 将 BASE64 处理之后的 AES 密钥转为 SecretKey + return strKey2SecretKey(strKeyAES); + + } + + +} diff --git a/src/main/java/org/starrier/common/utils/encrypt/EncryptUtils.java b/src/main/java/org/starrier/common/utils/encrypt/EncryptUtils.java new file mode 100644 index 0000000..23e750a --- /dev/null +++ b/src/main/java/org/starrier/common/utils/encrypt/EncryptUtils.java @@ -0,0 +1,61 @@ +package org.starrier.common.utils.encrypt; + + +import org.apache.commons.codec.binary.Hex; + +import javax.crypto.Cipher; +import javax.crypto.KeyGenerator; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; +import java.security.MessageDigest; +import java.security.SecureRandom; + +/** + * @author imperator + * @date 2019-09-09 + */ +public enum EncryptUtils { + + /** + * SINGLETON + */ + SINGLETON; + + private static final String SECRET = "Starrier"; + + private static final String CHARSET = "UTF-8"; + + + public String sha(String raw) throws Exception { + MessageDigest messageDigest = MessageDigest.getInstance("SHA-256"); + messageDigest.update(raw.getBytes(CHARSET)); + return Hex.encodeHexString(messageDigest.digest()); + } + + private Cipher createAesCipher() throws Exception { + return Cipher.getInstance("AES"); + } + + public String encryptByAes(String raw) throws Exception { + Cipher aesCipher = createAesCipher(); + KeyGenerator keyGenerator = KeyGenerator.getInstance("AES"); + keyGenerator.init(128, new SecureRandom(SECRET.getBytes(CHARSET))); + SecretKey secretKey = keyGenerator.generateKey(); + SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getEncoded(), "AES"); + aesCipher.init(Cipher.ENCRYPT_MODE, secretKeySpec); + byte[] bytes = aesCipher.doFinal(raw.getBytes(CHARSET)); + return Hex.encodeHexString(bytes); + } + + public String decryptByAes(String raw) throws Exception { + byte[] bytes = Hex.decodeHex(raw); + Cipher aesCipher = createAesCipher(); + KeyGenerator keyGenerator = KeyGenerator.getInstance("AES"); + keyGenerator.init(128, new SecureRandom(SECRET.getBytes(CHARSET))); + SecretKey secretKey = keyGenerator.generateKey(); + SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getEncoded(), "AES"); + aesCipher.init(Cipher.DECRYPT_MODE, secretKeySpec); + return new String(aesCipher.doFinal(bytes), CHARSET); + } + +} diff --git a/src/main/java/org/starrier/common/utils/encrypt/MD5Utils.java b/src/main/java/org/starrier/common/utils/encrypt/MD5Utils.java new file mode 100644 index 0000000..718aae2 --- /dev/null +++ b/src/main/java/org/starrier/common/utils/encrypt/MD5Utils.java @@ -0,0 +1,25 @@ +package org.starrier.common.utils.encrypt; + +import org.apache.commons.codec.digest.DigestUtils; + +import java.security.SecureRandom; + +import static org.apache.commons.codec.binary.Base64.encodeBase64String; + +/** + * @author Starrier + * @date 7/28/2019 + */ +public class MD5Utils { + + public static String md5(String src) { + return DigestUtils.md5Hex(src); + } + + public static final String getSalt() { + SecureRandom random = new SecureRandom(); + byte[] bytes = new byte[15]; + random.nextBytes(bytes); + return encodeBase64String(bytes); + } +} diff --git a/src/main/java/org/starrier/common/utils/package-info.java b/src/main/java/org/starrier/common/utils/package-info.java new file mode 100644 index 0000000..cedeeea --- /dev/null +++ b/src/main/java/org/starrier/common/utils/package-info.java @@ -0,0 +1,7 @@ +/** + * @author Starrier + * @date 2019/10/15 + * @version 0.0.1-SNAPSHOT + * @since 0.0.1-SNAPSHOT + */ +package org.starrier.common.utils; \ No newline at end of file diff --git a/src/main/java/org/starrier/common/validation/IsMobile.java b/src/main/java/org/starrier/common/validation/IsMobile.java new file mode 100644 index 0000000..367cf9b --- /dev/null +++ b/src/main/java/org/starrier/common/validation/IsMobile.java @@ -0,0 +1,47 @@ +package org.starrier.common.validation; + +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 Starrier + * @date 2018/11/17. + */ +@Target({ElementType.METHOD, + ElementType.FIELD, + ElementType.ANNOTATION_TYPE, + ElementType.CONSTRUCTOR, + ElementType.PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Constraint(validatedBy = {IsMobileValidator.class}) +public @interface IsMobile { + /** + * 默认 为空. + * 校验不通过,输出 message. + * + * @return the {@code result} with {@link Boolean} type. + */ + boolean required() default false; + + /** + * Define the message which will return when the validation is false. + * + * @return the result with {@code message}. + */ + String message() default "手机号码校验格式不通过"; + + Class[] groups() default {}; + + Class[] payload() default {}; + + +} diff --git a/src/main/java/org/starrier/common/validation/IsMobileValidator.java b/src/main/java/org/starrier/common/validation/IsMobileValidator.java new file mode 100644 index 0000000..9a15c49 --- /dev/null +++ b/src/main/java/org/starrier/common/validation/IsMobileValidator.java @@ -0,0 +1,36 @@ +package org.starrier.common.validation; + + +import org.apache.commons.lang3.StringUtils; +import org.starrier.common.utils.ValidatorUtil; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; + +/** + * @author Starrier + * @date 2018/11/17. + */ +public class IsMobileValidator implements ConstraintValidator { + + private boolean required = false; + + @Override + public void initialize(IsMobile isMobile) { + required = isMobile.required(); + } + + @Override + public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) { + + if (required) { + return ValidatorUtil.isMobile(value); + } else { + if (StringUtils.isBlank(value)) { + return true; + } else { + return ValidatorUtil.isMobile(value); + } + } + } +} diff --git a/src/main/java/org/starrier/common/validation/package-info.java b/src/main/java/org/starrier/common/validation/package-info.java new file mode 100644 index 0000000..d3fad6d --- /dev/null +++ b/src/main/java/org/starrier/common/validation/package-info.java @@ -0,0 +1,7 @@ +/** + * @author Starrier + * @date 2019/10/15 + * @version 0.0.1-SNAPSHOT + * @since 0.0.1-SNAPSHOT + */ +package org.starrier.common.validation; \ No newline at end of file diff --git a/src/main/test/org/starrier/common/utils/encrypt/AES2UtilsTest.java b/src/main/test/org/starrier/common/utils/encrypt/AES2UtilsTest.java new file mode 100644 index 0000000..53a1a99 --- /dev/null +++ b/src/main/test/org/starrier/common/utils/encrypt/AES2UtilsTest.java @@ -0,0 +1,36 @@ +package org.starrier.common.utils.encrypt; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.util.Assert; + +import java.util.Objects; + +/** + * @author starrier + * @date 2021/1/2 + */ +@ExtendWith(SpringExtension.class) +@SpringBootTest +@AutoConfigureMockMvc +class AES2UtilsTest { + + String test = "test"; + + @Test + public void encryptTest() throws Exception { + + String encrypt = AES2Utils.encrypt(test); + + } + + @Test + public void decryptTest() throws Exception { + String encrypt = AES2Utils.encrypt(test); + String decrypt = AES2Utils.decrypt(encrypt); + Assert.isTrue(decrypt.equals(encrypt),"success"); + } +} \ No newline at end of file diff --git a/src/main/test/org/starrier/common/utils/encrypt/AESUtilsTest.java b/src/main/test/org/starrier/common/utils/encrypt/AESUtilsTest.java new file mode 100644 index 0000000..72a4c6a --- /dev/null +++ b/src/main/test/org/starrier/common/utils/encrypt/AESUtilsTest.java @@ -0,0 +1,33 @@ +package org.starrier.common.utils.encrypt; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; +import static org.starrier.common.utils.encrypt.AESUtils.decrypt; +import static org.starrier.common.utils.encrypt.AESUtils.encrypt; + +/** + * @author starrier + * @date 2021/1/2 + */ +class AESUtilsTest { + + String encryptParams = "commons"; + + @Test + @DisplayName("encrypt key") + void encryptTest() throws Exception { + encrypt(encryptParams); + } + + @Test + @DisplayName("decrypt key") + void decryptTest() throws Exception { + + byte[] encrypt = encrypt(encryptParams); + byte[] decrypt = decrypt(encrypt); + + + } +} \ No newline at end of file diff --git a/src/main/test/org/starrier/common/validation/IsMobileValidatorTest.java b/src/main/test/org/starrier/common/validation/IsMobileValidatorTest.java new file mode 100644 index 0000000..eb46f58 --- /dev/null +++ b/src/main/test/org/starrier/common/validation/IsMobileValidatorTest.java @@ -0,0 +1,23 @@ +package org.starrier.common.validation; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + + +/** + * @author starrier + * @date 2021/1/2 + */ +class IsMobileValidatorTest { + + @Test + void initialize() { + } + + @Test + @DisplayName("mobilePhone param validate") + void isValid() { + + String mobilePhone = "12234567889"; + } +} \ No newline at end of file