Commit 1a577745 authored by WeiWei's avatar WeiWei

初始项目

parents
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**
!**/src/test/**
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
### VS Code ###
.vscode/
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.util.Properties;
public class MavenWrapperDownloader {
/**
* Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
*/
private static final String DEFAULT_DOWNLOAD_URL =
"https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar";
/**
* Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
* use instead of the default one.
*/
private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
".mvn/wrapper/maven-wrapper.properties";
/**
* Path where the maven-wrapper.jar will be saved to.
*/
private static final String MAVEN_WRAPPER_JAR_PATH =
".mvn/wrapper/maven-wrapper.jar";
/**
* Name of the property which should be used to override the default download url for the wrapper.
*/
private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
public static void main(String args[]) {
System.out.println("- Downloader started");
File baseDirectory = new File(args[0]);
System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());
// If the maven-wrapper.properties exists, read it and check if it contains a custom
// wrapperUrl parameter.
File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
String url = DEFAULT_DOWNLOAD_URL;
if(mavenWrapperPropertyFile.exists()) {
FileInputStream mavenWrapperPropertyFileInputStream = null;
try {
mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
Properties mavenWrapperProperties = new Properties();
mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
} catch (IOException e) {
System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
} finally {
try {
if(mavenWrapperPropertyFileInputStream != null) {
mavenWrapperPropertyFileInputStream.close();
}
} catch (IOException e) {
// Ignore ...
}
}
}
System.out.println("- Downloading from: : " + url);
File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
if(!outputFile.getParentFile().exists()) {
if(!outputFile.getParentFile().mkdirs()) {
System.out.println(
"- ERROR creating output direcrory '" + outputFile.getParentFile().getAbsolutePath() + "'");
}
}
System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
try {
downloadFileFromURL(url, outputFile);
System.out.println("Done");
System.exit(0);
} catch (Throwable e) {
System.out.println("- Error downloading");
e.printStackTrace();
System.exit(1);
}
}
private static void downloadFileFromURL(String urlString, File destination) throws Exception {
URL website = new URL(urlString);
ReadableByteChannel rbc;
rbc = Channels.newChannel(website.openStream());
FileOutputStream fos = new FileOutputStream(destination);
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
fos.close();
rbc.close();
}
}
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip
#!/bin/sh
# ----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
# Maven2 Start Up Batch script
#
# Required ENV vars:
# ------------------
# JAVA_HOME - location of a JDK home dir
#
# Optional ENV vars
# -----------------
# M2_HOME - location of maven2's installed home dir
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
# e.g. to debug Maven itself, use
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
# ----------------------------------------------------------------------------
if [ -z "$MAVEN_SKIP_RC" ] ; then
if [ -f /etc/mavenrc ] ; then
. /etc/mavenrc
fi
if [ -f "$HOME/.mavenrc" ] ; then
. "$HOME/.mavenrc"
fi
fi
# OS specific support. $var _must_ be set to either true or false.
cygwin=false;
darwin=false;
mingw=false
case "`uname`" in
CYGWIN*) cygwin=true ;;
MINGW*) mingw=true;;
Darwin*) darwin=true
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
if [ -z "$JAVA_HOME" ]; then
if [ -x "/usr/libexec/java_home" ]; then
export JAVA_HOME="`/usr/libexec/java_home`"
else
export JAVA_HOME="/Library/Java/Home"
fi
fi
;;
esac
if [ -z "$JAVA_HOME" ] ; then
if [ -r /etc/gentoo-release ] ; then
JAVA_HOME=`java-config --jre-home`
fi
fi
if [ -z "$M2_HOME" ] ; then
## resolve links - $0 may be a link to maven's home
PRG="$0"
# need this for relative symlinks
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG="`dirname "$PRG"`/$link"
fi
done
saveddir=`pwd`
M2_HOME=`dirname "$PRG"`/..
# make it fully qualified
M2_HOME=`cd "$M2_HOME" && pwd`
cd "$saveddir"
# echo Using m2 at $M2_HOME
fi
# For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin ; then
[ -n "$M2_HOME" ] &&
M2_HOME=`cygpath --unix "$M2_HOME"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
fi
# For Mingw, ensure paths are in UNIX format before anything is touched
if $mingw ; then
[ -n "$M2_HOME" ] &&
M2_HOME="`(cd "$M2_HOME"; pwd)`"
[ -n "$JAVA_HOME" ] &&
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
# TODO classpath?
fi
if [ -z "$JAVA_HOME" ]; then
javaExecutable="`which javac`"
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
# readlink(1) is not available as standard on Solaris 10.
readLink=`which readlink`
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
if $darwin ; then
javaHome="`dirname \"$javaExecutable\"`"
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
else
javaExecutable="`readlink -f \"$javaExecutable\"`"
fi
javaHome="`dirname \"$javaExecutable\"`"
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
JAVA_HOME="$javaHome"
export JAVA_HOME
fi
fi
fi
if [ -z "$JAVACMD" ] ; then
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
else
JAVACMD="`which java`"
fi
fi
if [ ! -x "$JAVACMD" ] ; then
echo "Error: JAVA_HOME is not defined correctly." >&2
echo " We cannot execute $JAVACMD" >&2
exit 1
fi
if [ -z "$JAVA_HOME" ] ; then
echo "Warning: JAVA_HOME environment variable is not set."
fi
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
# traverses directory structure from process work directory to filesystem root
# first directory with .mvn subdirectory is considered project base directory
find_maven_basedir() {
if [ -z "$1" ]
then
echo "Path not specified to find_maven_basedir"
return 1
fi
basedir="$1"
wdir="$1"
while [ "$wdir" != '/' ] ; do
if [ -d "$wdir"/.mvn ] ; then
basedir=$wdir
break
fi
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
if [ -d "${wdir}" ]; then
wdir=`cd "$wdir/.."; pwd`
fi
# end of workaround
done
echo "${basedir}"
}
# concatenates all lines of a file
concat_lines() {
if [ -f "$1" ]; then
echo "$(tr -s '\n' ' ' < "$1")"
fi
}
BASE_DIR=`find_maven_basedir "$(pwd)"`
if [ -z "$BASE_DIR" ]; then
exit 1;
fi
##########################################################################################
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
# This allows using the maven wrapper in projects that prohibit checking in binary data.
##########################################################################################
if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found .mvn/wrapper/maven-wrapper.jar"
fi
else
if [ "$MVNW_VERBOSE" = true ]; then
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
fi
jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"
while IFS="=" read key value; do
case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
esac
done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
if [ "$MVNW_VERBOSE" = true ]; then
echo "Downloading from: $jarUrl"
fi
wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
if command -v wget > /dev/null; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found wget ... using wget"
fi
wget "$jarUrl" -O "$wrapperJarPath"
elif command -v curl > /dev/null; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found curl ... using curl"
fi
curl -o "$wrapperJarPath" "$jarUrl"
else
if [ "$MVNW_VERBOSE" = true ]; then
echo "Falling back to using Java to download"
fi
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
if [ -e "$javaClass" ]; then
if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
if [ "$MVNW_VERBOSE" = true ]; then
echo " - Compiling MavenWrapperDownloader.java ..."
fi
# Compiling the Java class
("$JAVA_HOME/bin/javac" "$javaClass")
fi
if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
# Running the downloader
if [ "$MVNW_VERBOSE" = true ]; then
echo " - Running MavenWrapperDownloader.java ..."
fi
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
fi
fi
fi
fi
##########################################################################################
# End of extension
##########################################################################################
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
if [ "$MVNW_VERBOSE" = true ]; then
echo $MAVEN_PROJECTBASEDIR
fi
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
[ -n "$M2_HOME" ] &&
M2_HOME=`cygpath --path --windows "$M2_HOME"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
fi
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
exec "$JAVACMD" \
$MAVEN_OPTS \
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
"-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
@REM ----------------------------------------------------------------------------
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements. See the NOTICE file
@REM distributed with this work for additional information
@REM regarding copyright ownership. The ASF licenses this file
@REM to you under the Apache License, Version 2.0 (the
@REM "License"); you may not use this file except in compliance
@REM with the License. You may obtain a copy of the License at
@REM
@REM https://www.apache.org/licenses/LICENSE-2.0
@REM
@REM Unless required by applicable law or agreed to in writing,
@REM software distributed under the License is distributed on an
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@REM KIND, either express or implied. See the License for the
@REM specific language governing permissions and limitations
@REM under the License.
@REM ----------------------------------------------------------------------------
@REM ----------------------------------------------------------------------------
@REM Maven2 Start Up Batch script
@REM
@REM Required ENV vars:
@REM JAVA_HOME - location of a JDK home dir
@REM
@REM Optional ENV vars
@REM M2_HOME - location of maven2's installed home dir
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
@REM e.g. to debug Maven itself, use
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
@REM ----------------------------------------------------------------------------
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
@echo off
@REM set title of command window
title %0
@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
@REM set %HOME% to equivalent of $HOME
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
@REM Execute a user defined script before this one
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
:skipRcPre
@setlocal
set ERROR_CODE=0
@REM To isolate internal variables from possible post scripts, we use another setlocal
@setlocal
@REM ==== START VALIDATION ====
if not "%JAVA_HOME%" == "" goto OkJHome
echo.
echo Error: JAVA_HOME not found in your environment. >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
:OkJHome
if exist "%JAVA_HOME%\bin\java.exe" goto init
echo.
echo Error: JAVA_HOME is set to an invalid directory. >&2
echo JAVA_HOME = "%JAVA_HOME%" >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
@REM ==== END VALIDATION ====
:init
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
@REM Fallback to current working directory if not found.
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
set EXEC_DIR=%CD%
set WDIR=%EXEC_DIR%
:findBaseDir
IF EXIST "%WDIR%"\.mvn goto baseDirFound
cd ..
IF "%WDIR%"=="%CD%" goto baseDirNotFound
set WDIR=%CD%
goto findBaseDir
:baseDirFound
set MAVEN_PROJECTBASEDIR=%WDIR%
cd "%EXEC_DIR%"
goto endDetectBaseDir
:baseDirNotFound
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
cd "%EXEC_DIR%"
:endDetectBaseDir
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
@setlocal EnableExtensions EnableDelayedExpansion
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
:endReadAdditionalConfig
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"
FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO (
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
)
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
if exist %WRAPPER_JAR% (
echo Found %WRAPPER_JAR%
) else (
echo Couldn't find %WRAPPER_JAR%, downloading it ...
echo Downloading from: %DOWNLOAD_URL%
powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"
echo Finished downloading %WRAPPER_JAR%
)
@REM End of extension
%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
if ERRORLEVEL 1 goto error
goto end
:error
set ERROR_CODE=1
:end
@endlocal & set ERROR_CODE=%ERROR_CODE%
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
@REM check for post script, once with legacy .bat ending and once with .cmd ending
if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
:skipRcPost
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
if "%MAVEN_BATCH_PAUSE%" == "on" pause
if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
exit /B %ERROR_CODE%
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.21.RELEASE</version>
<relativePath/>
</parent>
<groupId>cn.quantgroup</groupId>
<artifactId>cash-loan-flow-boss</artifactId>
<version>1.0.0</version>
<name>cash-loan-flow-boss</name>
<description>Cash Loan Flow后端管理系统</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.0.3.Final</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.12</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.6</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
package cn.quantgroup.cashloanflowboss;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@EnableTransactionManagement
@EnableAutoConfiguration
@SpringBootApplication(scanBasePackages = {"cn.quantgroup.cashloanflowboss"})
public class Bootstrap {
public static void main(String[] args) {
SpringApplication.run(Bootstrap.class, args);
}
}
package cn.quantgroup.cashloanflowboss.api.log.controller;
import cn.quantgroup.cashloanflowboss.api.log.model.LoginFormModel;
import cn.quantgroup.cashloanflowboss.api.log.service.LogService;
import cn.quantgroup.cashloanflowboss.core.base.Result;
import cn.quantgroup.cashloanflowboss.core.dictionary.ApplicationStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
/**
* Created by WeiWei on 2019/7/22.
*/
@RestController
public class LogController {
@Autowired
private LogService logService;
/**
* 登入
*
* @param loginFormModel
* @return
*/
@PostMapping("/login")
public Result<Boolean> login(@RequestBody @Valid LoginFormModel loginFormModel) {
return new Result<>(ApplicationStatus.SUCCESS, this.logService.login(loginFormModel.getUsername(), loginFormModel.getPassword()));
}
/**
* 登出
*
* @return
*/
@DeleteMapping("/logout")
public Result<Boolean> logout() {
return new Result<>(ApplicationStatus.SUCCESS, this.logService.logout());
}
}
package cn.quantgroup.cashloanflowboss.api.log.model;
import cn.quantgroup.cashloanflowboss.validator.constraints.NotEmpty;
import lombok.Data;
/**
* Created by WeiWei on 2019/7/23.
*/
@Data
public class LoginFormModel {
/**
* 用户名
*/
@NotEmpty(message = "无效的用户名")
private String username;
/**
* 密码
*/
@NotEmpty(message = "无效的密码")
private String password;
}
package cn.quantgroup.cashloanflowboss.api.log.service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Objects;
/**
* Created by WeiWei on 2019/7/22.
*/
@Slf4j
@Service
public class LogService {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private HttpServletRequest request;
/**
* 登入
*
* @param username 用户名
* @param password 密码(明文)
* @return
*/
public boolean login(String username, String password) {
SecurityContext securityContext = SecurityContextHolder.getContext();
securityContext.setAuthentication(this.authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password)));
HttpSession session = this.request.getSession(true);
session.setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, securityContext);
return securityContext.getAuthentication().isAuthenticated();
}
/**
* 登出
*
* @return
*/
public boolean logout() {
new SecurityContextLogoutHandler().logout(this.request, null, SecurityContextHolder.getContext().getAuthentication());
return Objects.isNull(SecurityContextHolder.getContext().getAuthentication());
}
}
package cn.quantgroup.cashloanflowboss.api.user.controller;
import cn.quantgroup.cashloanflowboss.api.user.entity.User;
import cn.quantgroup.cashloanflowboss.api.user.model.Pagination;
import cn.quantgroup.cashloanflowboss.api.user.model.RegisterUserFormModel;
import cn.quantgroup.cashloanflowboss.api.user.service.UserService;
import cn.quantgroup.cashloanflowboss.validator.constraints.NotEmpty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
/**
* Created by WeiWei on 2019/7/22.
*/
@RestController
@RequestMapping("user")
public class UserController {
@Autowired
private UserService userService;
/**
* 注册用户
*
* @param registerUserFormModel
* @return
*/
@PostMapping()
public Boolean createUser(@RequestBody @Valid RegisterUserFormModel registerUserFormModel) {
return this.userService.createUser(registerUserFormModel.getUsername(), registerUserFormModel.getPassword());
}
/**
* 获取用户列表(分页)
*
* @return
*/
@GetMapping("/list")
public Page<User> queryUsers(@RequestParam @Valid Pagination pagination) {
return this.userService.getUsers(pagination.getPageNumber(), pagination.getPageSize());
}
/**
* 启用用户
*
* @param id 用户ID
* @return
*/
@PutMapping("/enable")
public Boolean enableUser(@RequestParam @Valid @NotEmpty(message = "无效的用户ID") String id) {
return this.userService.enableUser(id);
}
/**
* 禁用用户
*
* @param id 用户ID
* @return
*/
@PutMapping("/disable")
public Boolean disableUser(@RequestParam @Valid @NotEmpty(message = "无效的用户ID") String id) {
return this.userService.disableUser(id);
}
/**
* 移除用户
*
* @param id 用户ID
* @return
*/
@DeleteMapping()
public Boolean removeUser(@RequestParam @Valid @NotEmpty(message = "无效的用户ID") String id) {
return this.userService.removeUser(id);
}
}
package cn.quantgroup.cashloanflowboss.api.user.dictionary;
/**
* Created by WeiWei on 2019/7/22.
*/
public enum UserStatus {
/**
* 已启用的
*/
ENABLED,
/**
* 已禁用的
*/
DISABLED;
}
package cn.quantgroup.cashloanflowboss.api.user.entity;
import cn.quantgroup.cashloanflowboss.api.user.dictionary.UserStatus;
import cn.quantgroup.cashloanflowboss.core.persistence.Primary;
import lombok.Data;
import javax.persistence.*;
import java.util.Date;
/**
* Created by WeiWei on 2019/7/22.
*/
@Data
@Entity
@Table(name = "user")
public class User extends Primary {
/**
* 用户名
*/
@Column(name = "username")
private String username;
/**
* 密码
*/
@Column(name = "password")
private String password;
/**
* 用户状态
*/
@Enumerated(EnumType.STRING)
@Column(name = "status")
private UserStatus status;
/**
* 最后登录时间
*/
@Column(name = "last_login_time")
private Date lastLoginTime;
}
package cn.quantgroup.cashloanflowboss.api.user.model;
import lombok.Data;
/**
* Created by WeiWei on 2019/7/22.
*/
@Data
public class Pagination {
/**
* 页数
*/
private Integer pageNumber = 0;
/**
* 分页大小
*/
private Integer pageSize = 10;
}
package cn.quantgroup.cashloanflowboss.api.user.model;
import cn.quantgroup.cashloanflowboss.validator.constraints.NotEmpty;
import lombok.Data;
/**
* Created by WeiWei on 2019/7/22.
*/
@Data
public class RegisterUserFormModel {
/**
* 用户名
*/
@NotEmpty(message = "无效用户名")
private String username;
/**
* 密码
*/
@NotEmpty(message = "无效的密码")
private String password;
}
package cn.quantgroup.cashloanflowboss.api.user.repository;
import cn.quantgroup.cashloanflowboss.api.user.entity.User;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.stereotype.Repository;
/**
* Created by WeiWei on 2019/7/22.
*/
@Repository
public interface UserRepository extends PagingAndSortingRepository<User, String> {
/**
* 获取用户
*
* @param username 用户名
* @return
*/
User getUserByUsername(String username);
/**
* 获取用户列表(分页)
*
* @param pageable 分页
* @return
*/
Page<User> findAllBy(Pageable pageable);
}
package cn.quantgroup.cashloanflowboss.api.user.service;
import cn.quantgroup.cashloanflowboss.api.user.dictionary.UserStatus;
import cn.quantgroup.cashloanflowboss.api.user.entity.User;
import cn.quantgroup.cashloanflowboss.api.user.repository.UserRepository;
import cn.quantgroup.cashloanflowboss.core.asserts.Assert;
import cn.quantgroup.cashloanflowboss.core.dictionary.ApplicationStatus;
import cn.quantgroup.cashloanflowboss.utils.MD5Tools;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import java.util.Objects;
/**
* Created by WeiWei on 2019/7/22.
*/
@Slf4j
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
/**
* 创建用户
*
* @param username 用户名
* @param password 登录密码(明文)
* @return
*/
public boolean createUser(String username, String password) {
User user = new User();
user.setUsername(username);
user.setPassword(MD5Tools.md5(password));
user.setStatus(UserStatus.ENABLED);
return Objects.nonNull(this.userRepository.save(user));
}
/**
* 获取用户
*
* @param username 用户名
* @return
*/
public User getUser(String username) {
return this.userRepository.getUserByUsername(username);
}
/**
* 获取用户列表(分页)
*
* @param pageNumber
* @param pageSize
* @return
*/
public Page<User> getUsers(Integer pageNumber, Integer pageSize) {
return this.userRepository.findAllBy(new PageRequest(pageNumber, pageSize));
}
/**
* 启用用户
*
* @param id 用户ID
* @return
*/
public boolean enableUser(String id) {
User user = this.userRepository.findOne(id);
// 检查用户是否存在
Assert.isNull(user, ApplicationStatus.INVALID_USER);
user.setStatus(UserStatus.ENABLED);
return Objects.nonNull(this.userRepository.save(user));
}
/**
* 禁用用户
*
* @param id 用户ID
* @return
*/
public boolean disableUser(String id) {
User user = this.userRepository.findOne(id);
// 检查用户是否存在
Assert.isNull(user, ApplicationStatus.INVALID_USER);
user.setStatus(UserStatus.DISABLED);
return Objects.nonNull(this.userRepository.save(user));
}
/**
* 更新用户
*
* @param user
* @return
*/
public User updateUser(User user) {
return this.userRepository.save(user);
}
/**
* 移除用户
*
* @param id 用户ID
* @return
*/
public Boolean removeUser(String id) {
try {
this.userRepository.delete(id);
return true;
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return false;
}
}
package cn.quantgroup.cashloanflowboss.core;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEvent;
import org.springframework.stereotype.Component;
import org.springframework.web.context.ServletContextAware;
import javax.servlet.ServletContext;
import javax.validation.Validation;
import javax.validation.Validator;
/**
* Created by WeiWei on 2017/5/23.
*/
@Component
public class Application implements ApplicationContextAware, ServletContextAware {
private static ApplicationContext applicationContext;
private static ServletContext servletContext;
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
@Override
public void setApplicationContext(ApplicationContext context) throws BeansException {
applicationContext = context;
}
public static ServletContext getServletContext() {
return servletContext;
}
@Override
public void setServletContext(ServletContext context) {
servletContext = context;
}
/**
* 获取应用名称
*
* @return
*/
public static String getApplicationName() {
return Application.getValue("${spring.application.name}");
}
/**
* 获取应用IP地址
*
* @return
*/
public static String getHost() {
return Application.getValue("${spring.cloud.client.ipAddress}");
}
/**
* 获取应用端口号
*
* @return
*/
public static String getPort() {
return Application.getValue("${server.port}");
}
/**
* 获取配置属性值
*
* @param placeHolder
* @return
*/
public static String getValue(String placeHolder) {
return Application.getApplicationContext().getEnvironment().resolvePlaceholders(placeHolder);
}
/**
* 获取Bean
*
* @param bean
* @param <T>
* @return
*/
public static <T> T getBean(Class<T> bean) {
return applicationContext.getBean(bean);
}
/**
* 获取Bean
*
* @param bean
* @param arguments
* @param <T>
* @return
*/
public static <T> T getBean(Class<T> bean, Object... arguments) {
return applicationContext.getBean(bean, arguments);
}
/**
* 获取Bean
*
* @param beanName
* @param <T>
* @return
*/
public static <T> T getBean(String beanName) {
return (T) applicationContext.getBean(beanName);
}
/**
* 获取Bean
*
* @param beanName
* @param <T>
* @return
*/
public static <T> T getBean(String beanName, Object... arguments) {
return (T) applicationContext.getBean(beanName, arguments);
}
/**
* 发布事件
*
* @param event
*/
public static void publishEvent(ApplicationEvent event) {
applicationContext.publishEvent(event);
}
/**
* 获取验证器
*
* @return
*/
public static Validator getValidator() {
return Validation.buildDefaultValidatorFactory().getValidator();
}
}
\ No newline at end of file
package cn.quantgroup.cashloanflowboss.core.asserts;
import cn.quantgroup.cashloanflowboss.core.dictionary.Status;
import cn.quantgroup.cashloanflowboss.core.exception.ApplicationException;
import java.util.Collection;
import java.util.Objects;
/**
* 断言
* <p>
* Created by WeiWei on 2017/7/17.
*/
public class Assert {
/**
* 参数是否为False
*
* @param object
* @return
*/
public static boolean isFalse(Object object) {
return !isTrue(object);
}
/**
* 参数是否为False,如果是抛出指定异常和描述信息
*
* @param object
* @param status
*/
public static void isFalse(Object object, Status status) {
if (!isTrue(object)) {
throw new ApplicationException(status);
}
}
/**
* 参数是否为False,如果是抛出指定异常和描述信息
*
* @param object
* @param message
*/
public static void isFalse(Object object, String message) {
if (!isTrue(object)) {
throw new ApplicationException(message);
}
}
/**
* 参数是否为True
*
* @param object
* @return
*/
public static boolean isTrue(Object object) {
if (Boolean.class.isInstance(object)) {
return (boolean) object;
}
return false;
}
/**
* 参数是否为True,如果是抛出指定异常和描述信息
*
* @param object
* @param status
*/
public static void isTrue(Object object, Status status) {
if (isTrue(object)) {
throw new ApplicationException(status);
}
}
/**
* 参数是否为True,如果是抛出指定异常和描述信息
*
* @param object
* @param message
*/
public static void isTrue(Object object, String message) {
if (isTrue(object)) {
throw new ApplicationException(message);
}
}
/**
* 参数是否为非Null
*
* @param object
* @return
*/
public static boolean notNull(Object object) {
return !isNull(object);
}
/**
* 参数是否为非Null,如果是抛出指定异常和描述信息
*
* @param object
* @param status
*/
public static void notNull(Object object, Status status) {
if (notNull(object)) {
throw new ApplicationException(status);
}
}
/**
* 参数是否为非Null,如果是抛出指定异常和描述信息
*
* @param object
* @param message
*/
public static void notNull(Object object, String message) {
if (notNull(object)) {
throw new ApplicationException(message);
}
}
/**
* 参数是否为Null
*
* @param object
* @return
*/
public static boolean isNull(Object object) {
return Objects.isNull(object);
}
/**
* 参数是否为Null,如果是抛出指定异常和描述信息
*
* @param object
* @param status
*/
public static void isNull(Object object, Status status) {
if (isNull(object)) {
throw new ApplicationException(status);
}
}
/**
* 参数是否为Null,如果是抛出指定异常和描述信息
*
* @param object
* @param message
*/
public static void isNull(Object object, String message) {
if (isNull(object)) {
throw new ApplicationException(message);
}
}
/**
* 字符串参数是否为空
*
* @param data
* @return
*/
public static boolean isEmpty(String data) {
return (Objects.isNull(data) || data.isEmpty());
}
/**
* 字符串参数是否为空,如果是抛出指定异常和描述信息
*
* @param data
* @param status
*/
public static void isEmpty(String data, Status status) {
if (isEmpty(data)) {
throw new ApplicationException(status);
}
}
/**
* 字符串参数是否为空,如果是抛出指定异常和描述信息
*
* @param data
* @param message
*/
public static void isEmpty(String data, String message) {
if (isEmpty(data)) {
throw new ApplicationException(message);
}
}
/**
* 字符串参数是否为空
*
* @param data
* @param isTrim 是否去除前后导空白
* @return
*/
public static boolean isEmpty(String data, boolean isTrim) {
return isTrim ? isEmpty(data.trim()) : isEmpty(data);
}
/**
* 集合参数是否为空
*
* @param collection
* @return
*/
public static boolean isEmpty(Collection<?> collection) {
return (isNull(collection) || collection.isEmpty());
}
/**
* 集合参数是否为空,如果是抛出指定异常和描述信息
*
* @param collection
* @param status
*/
public static void isEmpty(Collection<?> collection, Status status) {
if (isEmpty(collection)) {
throw new ApplicationException(status);
}
}
/**
* 集合参数是否为空,如果是抛出指定异常和描述信息
*
* @param collection
* @param message
*/
public static void isEmpty(Collection<?> collection, String message) {
if (isEmpty(collection)) {
throw new ApplicationException(message);
}
}
/**
* 字符串参数是否为非空
*
* @param data
* @return
*/
public static boolean notEmpty(String data) {
return (Objects.nonNull(data) && !data.isEmpty());
}
/**
* 字符串参数是否为非空
*
* @param data
* @param isTrim 是否去除前后导空白
* @return
*/
public static boolean notEmpty(String data, boolean isTrim) {
return isTrim ? notEmpty(data.trim()) : notEmpty(data);
}
/**
* 字符串参数是否为非空,如果是抛出指定异常和描述信息
*
* @param data
* @param status
*/
public static void notEmpty(String data, Status status) {
if (notEmpty(data)) {
throw new ApplicationException(status);
}
}
/**
* 字符串参数是否为非空,如果是抛出指定异常和描述信息
*
* @param data
* @param message
*/
public static void notEmpty(String data, String message) {
if (notEmpty(data)) {
throw new ApplicationException(message);
}
}
/**
* 集合参数是否为非空
*
* @param collection
* @return
*/
public static boolean notEmpty(Collection<?> collection) {
return (notNull(collection) && !collection.isEmpty());
}
/**
* 集合参数是否为非空,如果是抛出指定异常和描述信息
*
* @param collection
* @param status
*/
public static void notEmpty(Collection<?> collection, Status status) {
if (notEmpty(collection)) {
throw new ApplicationException(status);
}
}
/**
* 集合参数是否为非空,如果是抛出指定异常和描述信息
*
* @param collection
* @param message
*/
public static void notEmpty(Collection<?> collection, String message) {
if (notEmpty(collection)) {
throw new ApplicationException(message);
}
}
}
package cn.quantgroup.cashloanflowboss.core.base;
import cn.quantgroup.cashloanflowboss.core.dictionary.Status;
import cn.quantgroup.cashloanflowboss.utils.RandomTools;
import lombok.Data;
import java.util.Calendar;
import java.util.Objects;
/**
* 请求返回数据结构实体类
* <p>
* Created by WeiWei on 2017/5/2.
*/
@Data
public class Result<T> {
/**
* 返回结果ID
*/
private String id = RandomTools.getUUID();
/**
* 状态码
*/
private int code;
/**
* 描述信息
*/
private String message;
/**
* 响应时间戳
*/
private long timestamp = Calendar.getInstance().getTimeInMillis();
/**
* 返回结果
*/
private T data;
public Result() {
}
public Result(Status status) {
this(status, null);
}
public Result(Status status, T data) {
this(status, data, null);
}
public Result(Status status, T data, String message) {
if (Objects.nonNull(status)) {
this.code = status.getCode();
this.message = Objects.isNull(message) ? status.getMessage() : message;
this.data = data;
}
}
}
package cn.quantgroup.cashloanflowboss.core.configuration;
import cn.quantgroup.cashloanflowboss.core.asserts.Assert;
import cn.quantgroup.cashloanflowboss.core.base.Result;
import cn.quantgroup.cashloanflowboss.core.dictionary.ApplicationStatus;
import cn.quantgroup.cashloanflowboss.core.exception.ApplicationException;
import com.fasterxml.jackson.core.io.JsonEOFException;
import com.fasterxml.jackson.databind.JsonMappingException;
import org.springframework.core.annotation.Order;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.util.Objects;
/**
* 应用系统异常配置
* <p>
* Created by WeiWei on 2017/5/2.
*/
@Order(1)
@Component
@RestControllerAdvice
public class ApplicationExceptionConfiguration {
/**
* 封装系统异常
*
* @param e
* @return
*/
@ExceptionHandler({ApplicationException.class})
public Result applicationExceptionHandler(ApplicationException e) {
return new Result<>(e.getStatus(), null, e.getMessage());
}
/**
* 封装数据绑定异常
*
* @param e
* @return
*/
@ExceptionHandler({MethodArgumentNotValidException.class, BindException.class})
public Result validExceptionHandler(Throwable e) {
Result result = new Result(ApplicationStatus.ARGUMENT_VALID_EXCEPTION);
BindingResult bindingResult = null;
if (MethodArgumentNotValidException.class.isInstance(e)) {
MethodArgumentNotValidException validException = (MethodArgumentNotValidException) e;
bindingResult = validException.getBindingResult();
} else if (BindException.class.isInstance(e)) {
BindException bindException = (BindException) e;
bindingResult = bindException.getBindingResult();
}
if (Assert.notEmpty(bindingResult.getAllErrors())) {
ObjectError error = bindingResult.getAllErrors().get(0);
result.setMessage(error.getDefaultMessage());
}
return result;
}
/**
* 封装JSON格式化异常
*
* @param e
* @return
*/
@ExceptionHandler({HttpMessageNotReadableException.class, JsonEOFException.class, JsonMappingException.class})
public Result jsonFormatException(Throwable e) {
return new Result<>(ApplicationStatus.JSON_DATA_EXCEPTION, null, HttpMessageNotReadableException.class.isInstance(e) ? ((HttpMessageNotReadableException) e).getRootCause().getMessage() : e.getMessage());
}
/**
* 封装未明确的异常
*
* @param e
* @return
*/
@ExceptionHandler({Throwable.class})
public Result generalException(Throwable e) {
Throwable cause = e.getCause();
while (Objects.nonNull(cause.getCause())) {
if (cause instanceof ApplicationException) {
cause = cause.getCause();
}
}
return new Result<>(ApplicationStatus.INTERNAL_SERVICE_ERROR, cause.getMessage());
}
}
\ No newline at end of file
package cn.quantgroup.cashloanflowboss.core.configuration.security;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* Created by WeiWei on 2019/7/23.
*/
@Component
public class AuthenticationLinstener implements AuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
httpServletResponse.getWriter().write("wocuole");
}
}
package cn.quantgroup.cashloanflowboss.core.configuration.security;
import cn.quantgroup.cashloanflowboss.api.user.dictionary.UserStatus;
import cn.quantgroup.cashloanflowboss.api.user.entity.User;
import cn.quantgroup.cashloanflowboss.api.user.service.UserService;
import cn.quantgroup.cashloanflowboss.core.asserts.Assert;
import cn.quantgroup.cashloanflowboss.core.dictionary.ApplicationStatus;
import cn.quantgroup.cashloanflowboss.utils.MD5Tools;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Component;
import java.util.Collection;
/**
* Created by WeiWei on 2019/7/22.
*/
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
@Autowired
private UserService userService;
@Override
public boolean supports(Class<?> clazz) {
return true;
}
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
User user = this.userService.getUser(authentication.getName());
// 检查用户是否存在
Assert.isNull(user, ApplicationStatus.INVALID_USER);
// 检查用户是否被禁用
Assert.isTrue(UserStatus.DISABLED.equals(user.getStatus()), ApplicationStatus.DISABLED_USER);
// 检查用户密码是否一致
Assert.isFalse(user.getPassword().equalsIgnoreCase(MD5Tools.md5(authentication.getCredentials().toString())), ApplicationStatus.USERNAME_OR_PASSWORD_ERROR);
Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
return new UsernamePasswordAuthenticationToken(user, authentication.getCredentials(), authorities);
}
}
package cn.quantgroup.cashloanflowboss.core.configuration.security;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.repository.configuration.EnableRedisRepositories;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
/**
* Created by WeiWei on 2019/7/22.
*/
@Configuration
@EnableWebSecurity
@EnableRedisHttpSession
@EnableRedisRepositories
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().ignoringAntMatchers("/**");
http.authorizeRequests().antMatchers("/login").permitAll();
http.authorizeRequests().anyRequest().authenticated();
}
}
package cn.quantgroup.cashloanflowboss.core.dictionary;
import lombok.Getter;
/**
* 应用状态码
* <p>
* Created by WeiWei on 2017/5/8.
*/
@Getter
public enum ApplicationStatus implements Status<ApplicationStatus> {
SUCCESS(200000, "Service request processing successful"),
FAILURE(500000, "Service request processing failure"),
INTERNAL_SERVICE_ERROR(500001, "内部服务错误"),
ARGUMENT_VALID_EXCEPTION(500002, "无效的请求参数"),
AUTHENTICATION_FAILURE(500003, "非法访问"),
REENTRY_LOCK_EXCEPTION(500004, "请求过于频繁"),
JSON_DATA_EXCEPTION(500005, "无效的JSON数据"),
INVALID_USER(501001, "无效的用户"),
DISABLED_USER(501002, "用户已被禁用"),
USERNAME_OR_PASSWORD_ERROR(501003, "用户名或密码错误");
private int code;
private String message;
private Status status;
ApplicationStatus(int code, String message) {
this.code = code;
this.message = message;
this.status = this;
}
}
package cn.quantgroup.cashloanflowboss.core.dictionary;
/**
* Created by WeiWei on 2017/11/3.
*/
public interface Status<T> {
/**
* 获取数字编码
*
* @return
*/
default int getCode() {
return this.getStatus().getCode();
}
/**
* 获取状态描述
*
* @return
*/
default String getMessage() {
return this.getStatus().getMessage();
}
/**
* 获取状态对象
*
* @return
*/
Status<T> getStatus();
}
package cn.quantgroup.cashloanflowboss.core.exception;
import cn.quantgroup.cashloanflowboss.core.dictionary.ApplicationStatus;
import cn.quantgroup.cashloanflowboss.core.dictionary.Status;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.util.Objects;
/**
* 自定义系统异常
* <p>
* Created by WeiWei on 2017/5/2.
*/
@Slf4j
@Data
public class ApplicationException extends RuntimeException {
/**
* 异常状态码
*/
private int code;
/**
* 异常描述信息
*/
private String message;
/**
* 异常状态对象
*/
private Status status;
public ApplicationException() {
this(ApplicationStatus.FAILURE);
}
public ApplicationException(String message) {
this(ApplicationStatus.FAILURE, message);
}
public ApplicationException(Throwable throwable) {
this(ApplicationStatus.FAILURE, throwable, ApplicationStatus.FAILURE.getMessage());
}
public ApplicationException(Status status) {
this(status, status.getMessage());
}
public ApplicationException(Status status, String message) {
this(status, null, message);
}
public ApplicationException(Status status, Throwable throwable, String message) {
super(Objects.nonNull(message) ? message : Objects.nonNull(status) ? status.getMessage() : Objects.nonNull(throwable) ? throwable.getMessage() : "", throwable);
this.status = Objects.nonNull(status) ? status : ApplicationStatus.FAILURE;
this.code = this.status.getCode();
this.message = (Objects.nonNull(message) ? message : Objects.nonNull(status) ? status.getMessage() : Objects.nonNull(throwable) ? throwable.getMessage() : "");
log.error(Objects.nonNull(throwable) ? throwable.getMessage() : message, Objects.nonNull(throwable) ? throwable : this);
}
}
package cn.quantgroup.cashloanflowboss.core.persistence;
import cn.quantgroup.cashloanflowboss.core.Application;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.id.IdentityGenerator;
import java.io.Serializable;
/**
* Created by WeiWei on 2017/5/17.
*/
public class IdGenerator extends IdentityGenerator {
@Override
public Serializable generate(SessionImplementor session, Object object) throws HibernateException {
return Application.getBean(SnowflakeGenerator.class).nextId();
}
}
package cn.quantgroup.cashloanflowboss.core.persistence;
import lombok.Data;
import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;
/**
* Created by WeiWei on 2017/6/13.
*/
@Data
@MappedSuperclass
public class Primary implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
/**
* 创建时间
*/
@Column(name = "create_time")
private Date createTime;
/**
* 更新时间
*/
@Column(name = "update_time")
private Date updateTime;
@PrePersist
public void prePersist() {
Date data = new Date();
createTime = data;
updateTime = data;
}
@PreUpdate
public void preUpdate() {
updateTime = new Date();
}
}
package cn.quantgroup.cashloanflowboss.core.persistence;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* Created by WeiWei on 2017/5/17.
*/
@Component
public class SnowflakeGenerator {
/**
* 开始时间截 (2015-01-01)
*/
private final long START_STMP = 1420041600000L;
/**
* 每一部分占用的位数
*/
private final static long SEQUENCE_BIT = 12; //序列号占用的位数
private final static long MACHINE_BIT = 5; //机器标识占用的位数
private final static long DATA_CENTER_BIT = 5;//数据中心占用的位数
/**
* 每一部分的最大值
*/
private final static long MAX_SEQUENCE_NUMBER = -1L ^ (-1L << SEQUENCE_BIT);
private final static long MAX_MACHINE_NUMBER = -1L ^ (-1L << MACHINE_BIT);
private final static long MAX_DATA_CENTER_NUMBER = -1L ^ (-1L << DATA_CENTER_BIT);
/**
* 每一部分向左的位移
*/
private final static long MACHINE_LEFT = SEQUENCE_BIT;
private final static long DATA_CENTER_LEFT = SEQUENCE_BIT + MACHINE_BIT;
private final static long TIMESTAMP_LEFT = DATA_CENTER_LEFT + DATA_CENTER_BIT;
/**
* 数据中心ID
*/
@Value("${application.server.dataCenterId:0}")
private long dataCenterId;
/**
* 机器标识ID
*/
@Value("${application.server.machineId:0}")
private long machineId;
/**
* 序列号
*/
private long sequence;
/**
* 上次记录时间
*/
private long lastTimestamp = -1L;
public SnowflakeGenerator() {
if (dataCenterId > MAX_DATA_CENTER_NUMBER || dataCenterId < 0) {
throw new IllegalArgumentException("dataCenterId can't be greater than MAX_DATA_CENTER_NUMBER or less than 0");
}
if (machineId > MAX_MACHINE_NUMBER || machineId < 0) {
throw new IllegalArgumentException("machineId can't be greater than MAX_MACHINE_NUMBER or less than 0");
}
}
/**
* 生成下一个ID
*
* @return
*/
public synchronized long nextId() {
long currentTimestamp = System.currentTimeMillis();
if (currentTimestamp < lastTimestamp) {
throw new IllegalStateException("Clock moved backwards. Refusing to generate id");
}
if (currentTimestamp == lastTimestamp) {
//相同毫秒内,序列号自增
sequence = (sequence + 1) & MAX_SEQUENCE_NUMBER;
//同一毫秒的序列数已经达到最大
if (sequence == 0L) {
while (currentTimestamp <= lastTimestamp) {
currentTimestamp = System.currentTimeMillis();
}
}
} else {
//不同毫秒内,序列号置为0
sequence = 0L;
}
lastTimestamp = currentTimestamp;
return (currentTimestamp - START_STMP) << TIMESTAMP_LEFT | dataCenterId << DATA_CENTER_LEFT | machineId << MACHINE_LEFT | sequence;
}
}
\ No newline at end of file
package cn.quantgroup.cashloanflowboss.utils;
import cn.quantgroup.cashloanflowboss.core.Application;
import cn.quantgroup.cashloanflowboss.core.dictionary.ApplicationStatus;
import cn.quantgroup.cashloanflowboss.core.exception.ApplicationException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
/**
* JSON工具类,默认是用Jackson
* <p>
* Created by WeiWei on 2017/7/31.
*/
public class JSONTools {
private static final ObjectMapper objectMapper;
static {
objectMapper = Application.getBean(ObjectMapper.class);
}
/**
* 序列化
*
* @param data
* @return
*/
public static String serialize(Object data) {
try {
return objectMapper.writeValueAsString(data);
} catch (JsonProcessingException e) {
throw new ApplicationException(ApplicationStatus.JSON_DATA_EXCEPTION, e.getMessage());
}
}
/**
* 反序列化
*
* @param dataString
* @param type
* @param <T>
* @return
*/
public static <T> T deserialize(String dataString, TypeReference type) {
try {
return objectMapper.readValue(dataString, type);
} catch (IOException e) {
throw new ApplicationException(ApplicationStatus.JSON_DATA_EXCEPTION, e.getMessage());
}
}
/**
* 反序列化
*
* @param dataString
* @param type
* @param <T>
* @return
*/
public static <T> T deserialize(String dataString, Class<T> type) {
try {
return objectMapper.readValue(dataString, type);
} catch (IOException e) {
throw new ApplicationException(ApplicationStatus.JSON_DATA_EXCEPTION, e.getMessage());
}
}
/**
* 转换数据类型
*
* @param data
* @param type
* @param <T>
* @return
*/
public static <T> T convert(Object data, Class<T> type) {
return deserialize(JSONTools.serialize(data), type);
}
/**
* 转换数据类型
*
* @param data
* @param type
* @param <T>
* @return
*/
public static <T> T convert(Object data, TypeReference type) {
return deserialize(JSONTools.serialize(data), type);
}
}
package cn.quantgroup.cashloanflowboss.utils;
import java.security.MessageDigest;
/**
* Created by WeiWei on 2019/7/22.
*/
public class MD5Tools {
public final static String md5(String content) {
char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
try {
// 获得MD5摘要算法的 MessageDigest 对象
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
// 使用指定的字节更新摘要
messageDigest.update(content.getBytes());
// 获得密文
byte[] digest = messageDigest.digest();
// 把密文转换成十六进制的字符串形式
int j = digest.length;
char str[] = new char[j * 2];
int k = 0;
for (int i = 0; i < j; i++) {
byte byte0 = digest[i];
str[k++] = hexDigits[byte0 >>> 4 & 0xf];
str[k++] = hexDigits[byte0 & 0xf];
}
return new String(str);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
package cn.quantgroup.cashloanflowboss.utils;
import java.util.Random;
import java.util.UUID;
/**
* Created by WeiWei on 2017/9/28.
*/
public class RandomTools {
/**
* 获取随机UUID,32位
*
* @return
*/
public static String getUUID() {
return UUID.randomUUID().toString().replaceAll("-", "");
}
/**
* 获取随机字符串
*
* @param length
* @param seeds
* @return
*/
public static String getRandomString(int length, String... seeds) {
Random random = new Random();
StringBuilder result = new StringBuilder();
for (int i = 0; i < length; i++) {
result.append(seeds[seeds.length == 1 ? 0 : random.nextInt(seeds.length)]);
}
return result.toString();
}
/**
* 获取范围随机整数
*
* @param min
* @param max
* @return
*/
public static int getRandomInteger(int min, int max) {
return new Random().nextInt(max - min + 1) + min;
}
}
package cn.quantgroup.cashloanflowboss.validator;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Hashtable;
import java.util.Objects;
import java.util.regex.Pattern;
/**
* 身份证号码的格式:610821-20061222-612-X
* 由18位数字组成:前6位为地址码,第7至14位为出生日期码,第15至17位为顺序码,
* 第18位为校验码。检验码分别是0-10共11个数字,当检验码为“10”时,为了保证公民身份证号码18位,所以用“X”表示。虽然校验码为“X”不能更换,但若需全用数字表示,只需将18位公民身份号码转换成15位居民身份证号码,去掉第7至8位和最后1位3个数码。
* 当今的身份证号码有15位和18位之分。1985年我国实行居民身份证制度,当时签发的身份证号码是15位的,1999年签发的身份证由于年份的扩展(由两位变为四位)和末尾加了效验码,就成了18位。
* (1)前1、2位数字表示:所在省份的代码;
* (2)第3、4位数字表示:所在城市的代码;
* (3)第5、6位数字表示:所在区县的代码;
* (4)第7~14位数字表示:出生年、月、日;
* (5)第15、16位数字表示:所在地的派出所的代码;
* (6)第17位数字表示性别:奇数表示男性,偶数表示女性
* (7)第18位数字是校检码:根据一定算法生成
* <p>
* Created by WeiWei on 2017/7/24.
*/
public class IDValidator {
/**
* 校验码
*/
private static final String[] validateCodes = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"};
/**
* 因子
*/
private static final int[] weights = new int[]{7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1};
/**
* 地区编码
*/
private static final Hashtable zones = new Hashtable();
/**
* 初始化省市编码
*/
static {
zones.put("11", "北京");
zones.put("12", "天津");
zones.put("13", "河北");
zones.put("14", "山西");
zones.put("15", "内蒙古");
zones.put("21", "辽宁");
zones.put("22", "吉林");
zones.put("23", "黑龙江");
zones.put("31", "上海");
zones.put("32", "江苏");
zones.put("33", "浙江");
zones.put("34", "安徽");
zones.put("35", "福建");
zones.put("36", "江西");
zones.put("37", "山东");
zones.put("41", "河南");
zones.put("42", "湖北");
zones.put("43", "湖南");
zones.put("44", "广东");
zones.put("45", "广西");
zones.put("46", "海南");
zones.put("50", "重庆");
zones.put("51", "四川");
zones.put("52", "贵州");
zones.put("53", "云南");
zones.put("54", "西藏");
zones.put("61", "陕西");
zones.put("62", "甘肃");
zones.put("63", "青海");
zones.put("64", "宁夏");
zones.put("65", "新疆");
zones.put("71", "台湾");
zones.put("81", "香港");
zones.put("82", "澳门");
zones.put("91", "国外");
}
public static void main(String[] args) {
boolean result = new IDValidator().validate("130204198509042724");
System.out.println(result);
}
/**
* 身份证验证
*
* @param idNumber
* @return
*/
public boolean validate(String idNumber) {
if (Objects.isNull(idNumber)) {
return false;
}
if (Pattern.matches("^[\\d]{15}$", idNumber)) {
return this.validate15(idNumber);
} else if (Pattern.matches("^([\\d]{17}((?i)X))|([\\d]{18})$", idNumber)) {
return this.validate18(idNumber);
}
return false;
}
/**
* 验证15位身份证号
*
* @param idNumber
* @return
*/
private boolean validate15(String idNumber) {
return this.validate18(this.convert(idNumber));
}
/**
* 验证18位身份证号
*
* @param idNumber
* @return
*/
private boolean validate18(String idNumber) {
return (this.checkBirthday(idNumber) && this.checkZone(idNumber) && this.checkValidateCode(idNumber));
}
/**
* 将15位身份证号转成18位身份证号
*
* @return
*/
private String convert(String idNumber) {
String newIdNumber = idNumber.substring(0, 6) + "19" + idNumber.substring(6);
// 校验码
int sum = 0;
for (int i = 0; i < 17; i++) {
int ai = Integer.parseInt(String.valueOf(newIdNumber.charAt(i)));
sum = sum + ai * weights[i];
}
int modValue = sum % 11;
String validateCode;
switch (modValue) {
case 0:
validateCode = "1";
break;
case 1:
validateCode = "0";
break;
case 2:
validateCode = "X";
break;
default:
validateCode = "" + (12 - modValue);
}
return newIdNumber + validateCode;
}
/**
* 验证出生日期
*
* @param idNumber
* @return
*/
private boolean checkBirthday(String idNumber) {
try {
Date birthday = new SimpleDateFormat("yyyyMMdd").parse(idNumber.substring(6, 14));
return (System.currentTimeMillis() > birthday.getTime());
} catch (java.text.ParseException e) {
e.printStackTrace();
}
return false;
}
/**
* 验证地区
*
* @param idNumber
* @return
*/
private boolean checkZone(String idNumber) {
return zones.containsKey(idNumber.substring(0, 2));
}
/**
* 验证末位校验码
* 判断第18位校验码是否正确
* 第18位校验码的计算方式:
* 1. 对前17位数字本体码加权求和
* 公式为:S = Sum(Ai * Wi), i = 0, ... , 16
* 其中Ai表示第i个位置上的身份证号码数字值,Wi表示第i位置上的加权因子,其各位对应的值依次为: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2
* 2. 用11对计算结果取模
* Y = mod(S, 11)
* 3. 根据模的值得到对应的校验码
* 对应关系为:
* Y值: 0 1 2 3 4 5 6 7 8 9 10
* 校验码: 1 0 X 9 8 7 6 5 4 3 2
*
* @param idNumber
* @return
*/
private boolean checkValidateCode(String idNumber) {
int sum = 0;
for (int i = 0; i < 17; i++) {
sum = sum + Integer.parseInt(String.valueOf(idNumber.charAt(i))) * weights[i];
}
int modValue = sum % 11;
String validateCode = validateCodes[modValue];
return idNumber.substring(idNumber.length() - 1).equalsIgnoreCase(validateCode);
}
}
package cn.quantgroup.cashloanflowboss.validator.constraints;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;
/**
* Created by WeiWei on 2017/7/13.
*/
@Documented
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {DateRangeValidator.class})
public @interface DateRange {
String message() default "{cn.quantgroup.validator.constraints.DateRange.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
boolean nullable() default false;
/**
* 起始时间
*
* @return
*/
long startTime() default 0;
/**
* 结束时间
*
* @return
*/
long endTime() default 0;
/**
* 偏差
*
* @return
*/
long offset() default 0;
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@interface List {
DateRange[] value();
}
}
\ No newline at end of file
package cn.quantgroup.cashloanflowboss.validator.constraints;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.Calendar;
import java.util.Objects;
/**
* 时间范围约束验证器
*
* Created by WeiWei on 2017/8/9.
*/
public class DateRangeValidator implements ConstraintValidator<DateRange, Long> {
private DateRange annotation;
public DateRangeValidator() {
}
@Override
public void initialize(DateRange constraintAnnotation) {
this.annotation = constraintAnnotation;
}
@Override
public boolean isValid(Long value, ConstraintValidatorContext context) {
if(Objects.isNull(value)) {
return this.annotation.nullable();
}
Long currentTime = Calendar.getInstance().getTimeInMillis();
Long startTime = this.annotation.startTime() == 0 ? currentTime : this.annotation.startTime();
Long endTime = this.annotation.endTime() == 0 ? currentTime : this.annotation.endTime();
Long offset = this.annotation.offset();
if(value < (startTime - offset) || value > (endTime + offset)) {
return false;
}
return true;
}
}
package cn.quantgroup.cashloanflowboss.validator.constraints;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;
/**
* Created by WeiWei on 2017/7/13.
*/
@Documented
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {EmailValidator.class})
public @interface Email {
String message() default "{cn.quantgroup.validator.constraints.Email.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
String regularExpression() default "^\\\\w+[-+.]\\\\w+)*@\\\\w+([-.]\\\\w+)*\\\\.\\\\w+([-.]\\\\w+)*$";
boolean nullable() default false;
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@interface List {
Email[] value();
}
}
\ No newline at end of file
package cn.quantgroup.cashloanflowboss.validator.constraints;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.Objects;
import java.util.regex.Pattern;
/**
* 邮箱格式约束验证器
*
* Created by WeiWei on 2017/8/9.
*/
public class EmailValidator implements ConstraintValidator<Email, CharSequence> {
private Email annotation;
public EmailValidator() {
}
@Override
public void initialize(Email constraintAnnotation) {
this.annotation = constraintAnnotation;
}
@Override
public boolean isValid(CharSequence value, ConstraintValidatorContext context) {
if(Objects.isNull(value)) {
return this.annotation.nullable();
}
return Pattern.matches(this.annotation.regularExpression(), value);
}
}
package cn.quantgroup.cashloanflowboss.validator.constraints;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;
/**
* Created by WeiWei on 2017/7/13.
*/
@Documented
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {IDNumberValidator.class})
public @interface IDNumber {
String message() default "{cn.quantgroup.validator.constraints.IDNumber.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
boolean nullable() default false;
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@interface List {
IDNumber[] value();
}
}
\ No newline at end of file
package cn.quantgroup.cashloanflowboss.validator.constraints;
import cn.quantgroup.cashloanflowboss.validator.IDValidator;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.Objects;
/**
* 身份证约束验证器
* <p>
* Created by WeiWei on 2017/7/24.
*/
public class IDNumberValidator implements ConstraintValidator<IDNumber, CharSequence> {
private static final IDValidator idValidator = new IDValidator();
private IDNumber annotation;
public IDNumberValidator() {
}
@Override
public void initialize(IDNumber constraintAnnotation) {
this.annotation = constraintAnnotation;
}
@Override
public boolean isValid(CharSequence value, ConstraintValidatorContext context) {
if (Objects.isNull(value)) {
return this.annotation.nullable();
}
return idValidator.validate(value.toString());
}
}
package cn.quantgroup.cashloanflowboss.validator.constraints;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;
/**
* Created by WeiWei on 2017/7/13.
*/
@Documented
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {NotEmptyValidator.class})
public @interface NotEmpty {
String message() default "{cn.quantgroup.validator.constraints.NotEmpty.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
boolean nullable() default false;
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@interface List {
NotEmpty[] value();
}
}
\ No newline at end of file
package cn.quantgroup.cashloanflowboss.validator.constraints;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.Collection;
import java.util.Objects;
/**
* 空值约束验证器
*
* Created by WeiWei on 2017/8/9.
*/
public class NotEmptyValidator implements ConstraintValidator<NotEmpty, Object> {
private NotEmpty annotation;
public NotEmptyValidator() {
}
@Override
public void initialize(NotEmpty constraintAnnotation) {
this.annotation = constraintAnnotation;
}
@Override
public boolean isValid(Object value, ConstraintValidatorContext context) {
if(Objects.isNull(value)) {
return this.annotation.nullable();
}
return Collection.class.isInstance(value) ? !((Collection) value).isEmpty() : String.class.isInstance(value) ? !((String) value).isEmpty() : true;
}
}
package cn.quantgroup.cashloanflowboss.validator.constraints;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;
/**
* Created by WeiWei on 2017/7/13.
*/
@Documented
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {PhoneValidator.class})
public @interface Phone {
String message() default "{cn.quantgroup.validator.constraints.Phone.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
String regularExpression() default "^1\\d{10}$"; //"^((13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$";
boolean nullable() default false;
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@interface List {
Phone[] value();
}
}
\ No newline at end of file
package cn.quantgroup.cashloanflowboss.validator.constraints;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.Objects;
import java.util.regex.Pattern;
/**
* 手机号格式约束验证器
*
* Created by WeiWei on 2017/8/9.
*/
public class PhoneValidator implements ConstraintValidator<Phone, CharSequence> {
private Phone annotation;
public PhoneValidator() {
}
@Override
public void initialize(Phone constraintAnnotation) {
this.annotation = constraintAnnotation;
}
@Override
public boolean isValid(CharSequence value, ConstraintValidatorContext context) {
if(Objects.isNull(value)) {
return this.annotation.nullable();
}
return Pattern.matches(this.annotation.regularExpression(), value);
}
}
package cn.quantgroup.cashloanflowboss.validator.constraints;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;
/**
* Created by WeiWei on 2017/7/13.
*/
@Documented
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {})
public @interface TelPhone {
String message() default "{cn.quantgroup.validator.constraints.TelPhone.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
String regularExpression() default "^(0\\\\d{2}-\\\\d{8}(-\\\\d{1,4})?)|(0\\\\d{3}-\\\\d{7,8}(-\\\\d{1,4})?)$";
boolean nullable() default false;
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@interface List {
TelPhone[] value();
}
}
\ No newline at end of file
package cn.quantgroup.cashloanflowboss.validator.constraints;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.Objects;
import java.util.regex.Pattern;
/**
* 座机电话格式约束验证器
* <p>
* Created by WeiWei on 2017/8/9.
*/
public class TelPhoneValidator implements ConstraintValidator<TelPhone, CharSequence> {
private TelPhone annotation;
public TelPhoneValidator() {
}
@Override
public void initialize(TelPhone constraintAnnotation) {
this.annotation = constraintAnnotation;
}
@Override
public boolean isValid(CharSequence value, ConstraintValidatorContext context) {
if (Objects.isNull(value)) {
return this.annotation.nullable();
}
return Pattern.matches(this.annotation.regularExpression(), value);
}
}
# \u9879\u76EE\u540D\u79F0
spring.application.name = cash-loan-flow-boss
# \u670D\u52A1\u7AEF\u53E3\u53F7
server.port = 51200
#-------------------------------- Database Setting --------------------------------#
# \u6570\u636E\u5E93\u9A71\u52A8\u7C7B\u8DEF\u5F84
spring.datasource.driverClassName = com.mysql.cj.jdbc.Driver
# \u6570\u636E\u5E93\u8FDE\u63A5URL
spring.datasource.url = jdbc:mysql://172.17.5.14:31763/cash_loan_flow_boss?useUnicode=true&characterEncoding=UTF8&serverTimezone=GMT%2b8
# \u6570\u636E\u5E93\u8D26\u53F7
spring.datasource.username = qa
# \u6570\u636E\u5E93\u5BC6\u7801
spring.datasource.password = qatest
# \u6570\u636E\u5E93\u8FDE\u63A5\u6C60\u6700\u5927\u8FDE\u63A5\u6570
spring.datasource.hikari.maximumPoolSize = 30
# \u6570\u636E\u5E93\u8FDE\u63A5\u6C60\u6700\u5C0F\u7A7A\u95F2\u63A5\u6570
spring.datasource.hikari.minimumIdle = 10
# \u6570\u636E\u5E93\u8FDE\u63A5\u6D4B\u8BD5\u8BED\u53E5
spring.datasource.hikari.connectionTestQuery = select 1
#-------------------------------- Redis Setting --------------------------------#
# Redis\u6570\u636E\u5E93\u7D22\u5F15\uFF08\u9ED8\u8BA4\u4E3A0\uFF09
spring.redis.database = 8
# Redis\u670D\u52A1\u5668\u5730\u5740
spring.redis.host = 172.17.5.10
# Redis\u670D\u52A1\u5668\u8FDE\u63A5\u7AEF\u53E3
spring.redis.port = 32244
# Redis\u670D\u52A1\u5668\u8FDE\u63A5\u5BC6\u7801\uFF08\u9ED8\u8BA4\u4E3A\u7A7A\uFF09
spring.redis.password =
# \u8FDE\u63A5\u6C60\u6700\u5927\u8FDE\u63A5\u6570\uFF08\u4F7F\u7528\u8D1F\u503C\u8868\u793A\u6CA1\u6709\u9650\u5236\uFF09
spring.redis.pool.maxActive = 30
# \u8FDE\u63A5\u6C60\u6700\u5927\u963B\u585E\u7B49\u5F85\u65F6\u95F4\uFF08\u4F7F\u7528\u8D1F\u503C\u8868\u793A\u6CA1\u6709\u9650\u5236\uFF09
spring.redis.pool.maxWait = -1
# \u8FDE\u63A5\u6C60\u4E2D\u7684\u6700\u5927\u7A7A\u95F2\u8FDE\u63A5
spring.redis.pool.maxIdle = 10
# \u8FDE\u63A5\u6C60\u4E2D\u7684\u6700\u5C0F\u7A7A\u95F2\u8FDE\u63A5
spring.redis.pool.minIdle = 1
# \u8FDE\u63A5\u8D85\u65F6\u65F6\u95F4\uFF08\u6BEB\u79D2\uFF09
spring.redis.timeout = 10000
#-------------------------------- Application Custom Setting --------------------------------#
# \u6570\u636E\u4E2D\u5FC3ID
application.server.dataCenterId=01
# \u6570\u636E\u4E2D\u5FC3\u673A\u5668ID
application.server.machineId=001
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<springProperty name="spring.application.name" source="spring.application.name"/>
<property name="LOG_LEVEL_PATTERN" value="%clr(%5p) %clr([${spring.application.name:-},%X{X-B3-TraceId:-},%X{X-B3-SpanId:-},%X{X-Span-Export:-}]){yellow}"/>
<property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{MM-dd HH:mm:ss.SSS}){faint} [%-10X{TRACING_ID}] %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%10.10t]){faint} [%40.40file:%4.4line] %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<logger name="cn.quantgroup" level="DEBUG" />
<logger name="org.springframework" level="DEBUG" />
<logger name="org.hibernate" level="warn"/>
<logger name="org.apache" level="warn"/>
<logger name="ch.qos.logback" level="warn"/>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<Pattern>%date{yyyy-MM-dd HH:mm:ss.SSS} %-5level[%thread]%logger{56}.%method:%L -%msg%n</Pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE" />
</root>
</configuration>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<springProperty name="spring.application.name" source="spring.application.name"/>
<property name="LOG_LEVEL_PATTERN"
value="%5p [${spring.application.name:-}, %X{X-B3-TraceId:-}, %X{X-B3-SpanId:-}, %X{X-Span-Export:-}]"/>
<property name="FILE_LOG_PATTERN"
value="${FILE_LOG_PATTERN:-%d{yyyy-MM-dd HH:mm:ss.SSS} ${LOG_LEVEL_PATTERN:-%5p} [%-10X{TRACING_ID}] --- [%thread] [%file:%line] %logger - %msg%n}"/>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>/home/quant_group/logs/${spring.application.name:-application}.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>/home/quant_group/logs/${spring.application.name:-application}.log.%d{yyyy-MM-dd}</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
</encoder>
</appender>
<appender name="Sentry" class="cn.quantgroup.sentry.appender.StandardSentryAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
<!-- level:基本建议ERROR or WARN -->
</filter>
</appender>
<logger name="org.springframework" level="warn"/>
<logger name="org.hibernate" level="warn"/>
<logger name="org.apache" level="warn"/>
<logger name="ch.qos.logback" level="warn"/>
<logger name="com.atomikos" level="warn"/>
<logger name="cn.quantgroup.user.UserSdkServiceImpl" level="warn"/>
<root level="info">
<appender-ref ref="FILE"/>
<appender-ref ref="Sentry"/>
</root>
</configuration>
\ No newline at end of file
package cn.quantgroup.cashloanflowboss;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class CashLoanFlowBossApplicationTests {
@Test
public void contextLoads() {
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment