Browse Source

Initial commit

admin 6 years ago
commit
3409ffb8af
43 changed files with 3214 additions and 0 deletions
  1. 26 0
      .gitignore
  2. 114 0
      .mvn/wrapper/MavenWrapperDownloader.java
  3. BIN
      .mvn/wrapper/maven-wrapper.jar
  4. 1 0
      .mvn/wrapper/maven-wrapper.properties
  5. 286 0
      mvnw
  6. 161 0
      mvnw.cmd
  7. 189 0
      pom.xml
  8. 13 0
      src/main/java/com/honter/ServletInitializer.java
  9. 23 0
      src/main/java/com/honter/SpringbootApplication.java
  10. 45 0
      src/main/java/com/honter/allexception/ConfCenterException.java
  11. 33 0
      src/main/java/com/honter/allexception/ExceptionHandler.java
  12. 240 0
      src/main/java/com/honter/allexception/ResultInfo.java
  13. 20 0
      src/main/java/com/honter/allexception/TokenException.java
  14. 67 0
      src/main/java/com/honter/config/ConfigBeanValue.java
  15. 248 0
      src/main/java/com/honter/config/DruidConfiguration.java
  16. 19 0
      src/main/java/com/honter/config/LogConfig.java
  17. 60 0
      src/main/java/com/honter/config/Swagger2Config.java
  18. 106 0
      src/main/java/com/honter/controller/HelloController.java
  19. 101 0
      src/main/java/com/honter/ehcache/CacheConfig.java
  20. 29 0
      src/main/java/com/honter/ehcache/EhcacheUtil.java
  21. 105 0
      src/main/java/com/honter/mail/MailSend.java
  22. 24 0
      src/main/java/com/honter/mapper/UserMapper.java
  23. 43 0
      src/main/java/com/honter/model/User.java
  24. 22 0
      src/main/java/com/honter/security/AuthenticationEntryPointImpl.java
  25. 21 0
      src/main/java/com/honter/security/DatabaseUserDetailService.java
  26. 102 0
      src/main/java/com/honter/security/JwtAuthenticationFilter.java
  27. 79 0
      src/main/java/com/honter/security/JwtTokenProvider.java
  28. 48 0
      src/main/java/com/honter/security/UserAuthService.java
  29. 67 0
      src/main/java/com/honter/security/WebSecurityConfig.java
  30. 20 0
      src/main/java/com/honter/service/UserService.java
  31. 93 0
      src/main/java/com/honter/serviceImpl/UserServiceImpl.java
  32. 81 0
      src/main/java/com/honter/util/JwtToken.java
  33. 69 0
      src/main/java/com/honter/util/JwtUtil.java
  34. 31 0
      src/main/java/com/honter/util/SchedulerTask.java
  35. 5 0
      src/main/resources/application-prod.properties
  36. 6 0
      src/main/resources/application-test.properties
  37. 56 0
      src/main/resources/application.properties
  38. 35 0
      src/main/resources/application.yml
  39. 121 0
      src/main/resources/ehcache-config.xml
  40. 36 0
      src/main/resources/generator/generatorConfig.xml
  41. 189 0
      src/main/resources/logging-config.xml
  42. 103 0
      src/main/resources/mapping/UserMapper.xml
  43. 77 0
      src/test/java/com/honter/SpringbootApplicationTests.java

+ 26 - 0
.gitignore

@@ -0,0 +1,26 @@
+HELP.md
+/target/
+!.mvn/wrapper/maven-wrapper.jar
+
+### 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/

+ 114 - 0
.mvn/wrapper/MavenWrapperDownloader.java

@@ -0,0 +1,114 @@
+/*
+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
+
+  http://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();
+    }
+
+}

BIN
.mvn/wrapper/maven-wrapper.jar


+ 1 - 0
.mvn/wrapper/maven-wrapper.properties

@@ -0,0 +1 @@
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip

+ 286 - 0
mvnw

@@ -0,0 +1,286 @@
+#!/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
+#
+#    http://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 "$@"

+ 161 - 0
mvnw.cmd

@@ -0,0 +1,161 @@
+@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    http://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%

+ 189 - 0
pom.xml

@@ -0,0 +1,189 @@
+<?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.6.RELEASE</version>
+		<relativePath/> <!-- lookup parent from repository -->
+	</parent>
+	<groupId>com.honter</groupId>
+	<artifactId>springboot</artifactId>
+	<version>0.0.1-SNAPSHOT</version>
+	<packaging>war</packaging>
+	<name>springboot</name>
+	<description>Demo project for Spring Boot</description>
+
+	<properties>
+		<java.version>1.8</java.version>
+	</properties>
+
+	<dependencies>
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-jdbc</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.mybatis.spring.boot</groupId>
+			<artifactId>mybatis-spring-boot-starter</artifactId>
+			<version>1.3.0</version>
+		</dependency>
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-web</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>mysql</groupId>
+			<artifactId>mysql-connector-java</artifactId>
+			<scope>5.1.35</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-tomcat</artifactId>
+			<scope>provided</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-test</artifactId>
+			<scope>test</scope>
+		</dependency>
+		<!-- alibaba的druid数据库连接池 -->
+		<dependency>
+			<groupId>com.alibaba</groupId>
+			<artifactId>druid</artifactId>
+			<version>1.0.11</version>
+		</dependency>
+		<!-- alibaba的druid数据库连接池 -->
+		<dependency>
+			<groupId>com.alibaba</groupId>
+			<artifactId>druid-spring-boot-starter</artifactId>
+			<version>1.1.0</version>
+		</dependency>
+		<dependency>
+			<groupId>com.fasterxml.jackson.core</groupId>
+			<artifactId>jackson-core</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>com.fasterxml.jackson.core</groupId>
+			<artifactId>jackson-databind</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>com.fasterxml.jackson.datatype</groupId>
+			<artifactId>jackson-datatype-joda</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>com.fasterxml.jackson.module</groupId>
+			<artifactId>jackson-module-parameter-names</artifactId>
+		</dependency>
+		<!-- 分页插件 -->
+		<dependency>
+			<groupId>com.github.pagehelper</groupId>
+			<artifactId>pagehelper-spring-boot-starter</artifactId>
+			<version>1.1.2</version>
+		</dependency>
+		<!-- 读取project文件 -->
+		<dependency>
+			<groupId>net.sf.mpxj</groupId>
+			<artifactId>mpxj</artifactId>
+			<version>7.1.0</version>
+		</dependency>
+		<!-- jwt 加密解密需要的 -->
+		<dependency>
+			<groupId>com.auth0</groupId>
+			<artifactId>java-jwt</artifactId>
+			<version>3.0.1</version>
+		</dependency>
+		<dependency>
+			<groupId>io.jsonwebtoken</groupId>
+			<artifactId>jjwt</artifactId>
+			<version>0.7.0</version>
+		</dependency>
+		<dependency>
+			<groupId>commons-logging</groupId>
+			<artifactId>commons-logging</artifactId>
+			<version>1.2</version>
+		</dependency>
+		<dependency>
+			<groupId>com.google.code.gson</groupId>
+			<artifactId>gson</artifactId>
+			<version>2.8.2</version>
+		</dependency>
+		<!--序列化支持fastjson-->
+		<dependency>
+			<groupId>com.alibaba</groupId>
+			<artifactId>fastjson</artifactId>
+			<version>1.2.19</version>
+		</dependency>
+		<!--swagger2-->
+		<dependency>
+			<groupId>io.springfox</groupId>
+			<artifactId>springfox-swagger-ui</artifactId>
+			<version>2.9.2</version>
+		</dependency>
+		<dependency>
+			<groupId>io.springfox</groupId>
+			<artifactId>springfox-swagger2</artifactId>
+			<version>2.9.2</version>
+		</dependency>
+		<dependency>
+			<groupId>org.projectlombok</groupId>
+			<artifactId>lombok</artifactId>
+			<version>1.16.10</version>
+		</dependency>
+		<!--spring security -->
+		<dependency>
+			<groupId>org.springframework.security.oauth</groupId>
+			<artifactId>spring-security-oauth2</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.springframework.security</groupId>
+			<artifactId>spring-security-jwt</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>io.jsonwebtoken</groupId>
+			<artifactId>jjwt</artifactId>
+			<version>0.9.0</version>
+		</dependency>
+		<!--spring ehcache -->
+		<dependency>
+			<groupId>net.sf.ehcache</groupId>
+			<artifactId>ehcache</artifactId>
+			<version>2.10.4</version>
+		</dependency>
+		<dependency>
+			<groupId>org.springframework</groupId>
+			<artifactId>spring-context-support</artifactId>
+		</dependency>
+		<!-- javax mail -->
+		<dependency>
+			<groupId>javax.mail</groupId>
+			<artifactId>mail</artifactId>
+			<version>1.4.7</version>
+		</dependency>
+
+    </dependencies>
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.springframework.boot</groupId>
+				<artifactId>spring-boot-maven-plugin</artifactId>
+			</plugin>
+			<!-- mybatis generator 自动生成代码插件 -->
+			<plugin>
+				<groupId>org.mybatis.generator</groupId>
+				<artifactId>mybatis-generator-maven-plugin</artifactId>
+				<version>1.3.2</version>
+				<configuration>
+					<configurationFile>${basedir}/src/main/resources/generator/generatorConfig.xml</configurationFile>
+					<overwrite>true</overwrite>
+					<verbose>true</verbose>
+				</configuration>
+			</plugin>
+		</plugins>
+
+	</build>
+
+</project>

+ 13 - 0
src/main/java/com/honter/ServletInitializer.java

@@ -0,0 +1,13 @@
+package com.honter;
+
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.support.SpringBootServletInitializer;
+
+public class ServletInitializer extends SpringBootServletInitializer {
+
+	@Override
+	protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
+		return application.sources(SpringbootApplication.class);
+	}
+
+}

+ 23 - 0
src/main/java/com/honter/SpringbootApplication.java

@@ -0,0 +1,23 @@
+package com.honter;
+
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+@SpringBootApplication
+@EnableScheduling//启动定时
+@EnableSwagger2
+@MapperScan("com.honter.mapper")
+//@ComponentScan(basePackages={"com.honter.service"})据说spring boot 自动扫描,可以不加
+@EnableTransactionManagement // 启注解事务管理,等同于xml配置方式的 <tx:annotation-driven />
+public class SpringbootApplication {
+
+	public static void main(String[] args) {
+		SpringApplication.run(SpringbootApplication.class, args);
+	}
+
+}

+ 45 - 0
src/main/java/com/honter/allexception/ConfCenterException.java

@@ -0,0 +1,45 @@
+package com.honter.allexception;
+
+/**
+ * @Author: kevin
+ * @Description: 基础异常类
+ * @Date: Created In 2018/3/10 14:51
+ */
+public abstract class ConfCenterException extends RuntimeException {
+    /**
+     * uid
+     */
+    private static final long serialVersionUID = 8037891447646609768L;
+
+    /**
+     * 默认构造函数
+     */
+    public ConfCenterException() {
+    }
+
+    /**
+     * 构造函数
+     * @param errMsg 异常消息
+     */
+    public ConfCenterException(String errMsg) {
+        super(errMsg);
+    }
+
+    /**
+     * 构造函数
+     * @param cause 原始异常
+     */
+    public ConfCenterException(Throwable cause) {
+        super(cause);
+    }
+
+    /**
+     * 构造函数
+     * @param errMsg 异常消息
+     * @param cause 原始异常
+     */
+    public ConfCenterException(String errMsg, Throwable cause) {
+        super(errMsg, cause);
+    }
+
+}

+ 33 - 0
src/main/java/com/honter/allexception/ExceptionHandler.java

@@ -0,0 +1,33 @@
+package com.honter.allexception;
+
+import com.honter.allexception.ResultInfo;
+import com.honter.allexception.ConfCenterException;
+import com.honter.config.LogConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+/**
+ * @Author: kevin
+ * @Description: 异常统一处理
+ * @Date: Created In 2018/4/16 10:25
+ */
+@ControllerAdvice
+public class ExceptionHandler {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(LogConfig.class);
+
+    @org.springframework.web.bind.annotation.ExceptionHandler(value = Exception.class)
+    @ResponseBody
+    public ResultInfo handler(Exception e) {
+        ResultInfo resultInfo=new ResultInfo();
+        LOGGER.error("----ExceptionHandler----:"+e.getMessage());
+        if (e instanceof TokenException) {
+            resultInfo = ResultInfo.result(2,"TokenException",e.getMessage());
+        } else {
+            resultInfo = ResultInfo.result(1,"errorException",e.getMessage());
+        }
+        return resultInfo;
+    }
+}

+ 240 - 0
src/main/java/com/honter/allexception/ResultInfo.java

@@ -0,0 +1,240 @@
+package com.honter.allexception;
+
+/**
+ * 客户端的HTTP调用的应答结果类
+ */
+public class ResultInfo {
+
+    /**
+     * 应答结果状态码——成功
+     */
+    public static final int RESULT_CODE_SUCCESS = 0;
+    /**
+     * 应答结果状态码——通用错误
+     */
+    public static final int RESULT_CODE_COMMONERR = 9999;
+
+    /**
+     * session过期
+     */
+    public static final int RESULT_SESSION_TIMEOUT = 1;
+
+    /**
+     * 返回状态
+     */
+    private int status = RESULT_CODE_SUCCESS;
+
+    /**
+     * 返回状态描述
+     */
+    private String statusInfo = "SUCCESS"; // 操作结果描述信息
+
+    /**
+     * 返回数据
+     */
+    private Object data;// 操作返回数据绑定
+
+    /**
+     * 返回一个默认的错误结果
+     *
+     * @return 错误结果
+     */
+    public static ResultInfo error() {
+        ResultInfo res = new ResultInfo(RESULT_CODE_COMMONERR, "ERROR");
+        return res;
+    }
+
+    /**
+     * 返回一个带错误信息的错误结果
+     *
+     * @param errorMessage 错误信息
+     * @return 错误结果
+     */
+    public static ResultInfo errorMessage(String errorMessage) {
+        ResultInfo res = new ResultInfo(RESULT_CODE_COMMONERR, errorMessage);
+        return res;
+    }
+
+    /**
+     * session过期
+     *
+     * @return
+     */
+    public static ResultInfo sessionTimeout() {
+        ResultInfo res = new ResultInfo(RESULT_SESSION_TIMEOUT, "登录超时");
+        return res;
+    }
+
+    /**
+     * 返回一个带错误信息和数据的错误结果
+     *
+     * @param errorMessage 错误信息
+     * @param data         数据
+     * @return 错误结果
+     */
+    public static ResultInfo errorMessage(String errorMessage, Object data) {
+        ResultInfo res = new ResultInfo(RESULT_CODE_COMMONERR, errorMessage);
+        res.setData(data);
+        return res;
+    }
+
+    /**
+     * 返回一个带状态和信息的结果
+     *
+     * @param status 状态
+     * @param info   信息
+     * @return 返回结果
+     */
+    public static ResultInfo result(int status, String info) {
+        ResultInfo res = new ResultInfo();
+        res.status = status;
+        res.statusInfo = info;
+        return res;
+    }
+
+    /**
+     * 返回一个带状态,信息和数据的结果
+     *
+     * @param status 状态
+     * @param info   信息
+     * @param data   数据
+     * @return 返回结果
+     */
+    public static ResultInfo result(int status, String info, Object data) {
+        ResultInfo res = new ResultInfo();
+        res.status = status;
+        res.statusInfo = info;
+        res.data = data;
+        return res;
+    }
+
+    /**
+     * 返回一个成功结果
+     *
+     * @return 成功结果
+     */
+    public static ResultInfo success() {
+        ResultInfo res = new ResultInfo();
+        return res;
+    }
+
+    /**
+     * 返回一个带数据的成功结果
+     *
+     * @param data 数据
+     * @return 成功结果
+     */
+    public static ResultInfo success(Object data) {
+        ResultInfo res = new ResultInfo();
+        res.setData(data);
+        return res;
+    }
+
+    /**
+     * 返回一个带信息的成功结果
+     *
+     * @param message 提示信息
+     * @return 成功结果
+     */
+    public static ResultInfo successMessage(String message) {
+        ResultInfo res = new ResultInfo(RESULT_CODE_SUCCESS, message);
+        return res;
+    }
+
+    /**
+     * 默认构造函数
+     */
+    public ResultInfo() {
+    }
+
+    /**
+     * 带状态和信息的构造函数
+     *
+     * @param status     状态
+     * @param statusInfo 提示信息
+     */
+    public ResultInfo(int status, String statusInfo) {
+        this.status = status;
+        this.statusInfo = statusInfo;
+    }
+
+    /**
+     * 带状态,信息和数据的构造函数
+     *
+     * @param status     状态
+     * @param statusInfo 提示信息
+     * @param data       数据
+     */
+    public ResultInfo(int status, String statusInfo, Object data) {
+        super();
+        this.status = status;
+        this.statusInfo = statusInfo;
+        this.data = data;
+    }
+
+    public Object getData() {
+        return data;
+    }
+
+    public int getStatus() {
+        return status;
+    }
+
+    public String getStatusInfo() {
+        return statusInfo;
+    }
+
+    public void setData(Object data) {
+        this.data = data;
+    }
+
+    public void setStatus(int status) {
+        this.status = status;
+    }
+
+    public void setStatusInfo(String statusInfo) {
+        this.statusInfo = statusInfo;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((data == null) ? 0 : data.hashCode());
+        result = prime * result + status;
+        result = prime * result + ((statusInfo == null) ? 0 : statusInfo.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        ResultInfo other = (ResultInfo) obj;
+        if (data == null) {
+            if (other.data != null) {
+                return false;
+            }
+        } else if (!data.equals(other.data)) {
+            return false;
+        }
+        if (status != other.status) {
+            return false;
+        }
+        if (statusInfo == null) {
+            if (other.statusInfo != null) {
+                return false;
+            }
+        } else if (!statusInfo.equals(other.statusInfo)) {
+            return false;
+        }
+        return true;
+    }
+}

+ 20 - 0
src/main/java/com/honter/allexception/TokenException.java

@@ -0,0 +1,20 @@
+package com.honter.allexception;
+
+/**
+ * Created by admin on 2019/3/14.
+ */
+public class TokenException extends Exception {
+    /**
+     * 默认构造函数
+     */
+    public TokenException() {
+    }
+
+    /**
+     * 构造函数
+     * @param errMsg 异常消息
+     */
+    public TokenException(String errMsg) {
+        super(errMsg);
+    }
+}

+ 67 - 0
src/main/java/com/honter/config/ConfigBeanValue.java

@@ -0,0 +1,67 @@
+package com.honter.config;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+/**
+ * Created by admin on 2019/3/26.
+ * 读取配置文件数据
+ */
+@Component
+
+public class ConfigBeanValue {
+    private String jwtTokenSecret;
+    private long tokenExpiredMs;
+    private long tokenRefreshMs;
+    private String EMAIL_OWNER_ADDR_HOST; //smtp.163.com  smtp.aliyun.com  smtp.qq.com
+    private String EMAIL_OWNER_ADDR;
+    private String EMAIL_OWNER_ADDR_PASS;
+
+    public String getJwtTokenSecret() {
+        return jwtTokenSecret;
+    }
+    @Value("${jwtspringboot.jwtTokenSecret}")
+    public void setJwtTokenSecret(String jwtTokenSecret) {
+        this.jwtTokenSecret = jwtTokenSecret;
+    }
+
+    public long getTokenExpiredMs() {
+        return tokenExpiredMs;
+    }
+    @Value("${jwtspringboot.tokenExpiredMs}")
+    public void setTokenExpiredMs(long tokenExpiredMs) {
+        this.tokenExpiredMs = tokenExpiredMs;
+    }
+
+    public long getTokenRefreshMs() {
+        return tokenRefreshMs;
+    }
+    @Value("${jwtspringboot.tokenRefreshMs}")
+    public void setTokenRefreshMs(long tokenRefreshMs) {
+        this.tokenRefreshMs = tokenRefreshMs;
+    }
+
+    public String getEMAIL_OWNER_ADDR_HOST() {
+        return EMAIL_OWNER_ADDR_HOST;
+    }
+    @Value("${mailsend.EMAIL_OWNER_ADDR_HOST}")
+    public void setEMAIL_OWNER_ADDR_HOST(String EMAIL_OWNER_ADDR_HOST) {
+        this.EMAIL_OWNER_ADDR_HOST = EMAIL_OWNER_ADDR_HOST;
+    }
+
+    public String getEMAIL_OWNER_ADDR() {
+        return EMAIL_OWNER_ADDR;
+    }
+    @Value("${mailsend.EMAIL_OWNER_ADDR}")
+    public void setEMAIL_OWNER_ADDR(String EMAIL_OWNER_ADDR) {
+        this.EMAIL_OWNER_ADDR = EMAIL_OWNER_ADDR;
+    }
+
+    public String getEMAIL_OWNER_ADDR_PASS() {
+        return EMAIL_OWNER_ADDR_PASS;
+    }
+    @Value("${mailsend.EMAIL_OWNER_ADDR_PASS}")
+    public void setEMAIL_OWNER_ADDR_PASS(String EMAIL_OWNER_ADDR_PASS) {
+        this.EMAIL_OWNER_ADDR_PASS = EMAIL_OWNER_ADDR_PASS;
+    }
+}

+ 248 - 0
src/main/java/com/honter/config/DruidConfiguration.java

@@ -0,0 +1,248 @@
+package com.honter.config;
+import com.alibaba.druid.pool.DruidDataSource;
+import com.alibaba.druid.support.http.StatViewServlet;
+import com.alibaba.druid.support.http.WebStatFilter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
+import org.springframework.boot.web.servlet.ServletRegistrationBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+import org.springframework.stereotype.Component;
+
+import javax.sql.DataSource;
+import java.sql.SQLException;
+
+@Configuration
+public class DruidConfiguration {
+
+    private static final Logger logger = LoggerFactory.getLogger(DruidConfiguration.class);
+
+    private static final String DB_PREFIX = "spring.datasource";
+
+    @Bean
+    public ServletRegistrationBean druidServlet() {
+        logger.info("init Druid Servlet Configuration ");
+        ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
+        // IP白名单
+//        servletRegistrationBean.addInitParameter("allow", "*");
+        // IP黑名单(共同存在时,deny优先于allow)
+//        servletRegistrationBean.addInitParameter("deny", "192.168.1.100");
+        //控制台管理用户
+        servletRegistrationBean.addInitParameter("loginUsername", "admin");
+        servletRegistrationBean.addInitParameter("loginPassword", "admin");
+        //是否能够重置数据 禁用HTML页面上的“Reset All”功能
+        servletRegistrationBean.addInitParameter("resetEnable", "false");
+        return servletRegistrationBean;
+    }
+
+    @Bean
+    public FilterRegistrationBean filterRegistrationBean() {
+        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter());
+        filterRegistrationBean.addUrlPatterns("/*");
+        filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
+        return filterRegistrationBean;
+    }
+
+    //解决 spring.datasource.filters=stat,wall,log4j 无法正常注册进去
+    @Component
+    @ConfigurationProperties(prefix = DB_PREFIX)
+    class IDataSourceProperties {
+        private String url;
+        private String username;
+        private String password;
+        private String driverClassName;
+        private int initialSize;
+        private int minIdle;
+        private int maxActive;
+        private int maxWait;
+        private int timeBetweenEvictionRunsMillis;
+        private int minEvictableIdleTimeMillis;
+        private String validationQuery;
+        private boolean testWhileIdle;
+        private boolean testOnBorrow;
+        private boolean testOnReturn;
+        private boolean poolPreparedStatements;
+        private int maxPoolPreparedStatementPerConnectionSize;
+        private String filters;
+        private String connectionProperties;
+
+        @Bean(destroyMethod = "close", initMethod = "init")     //声明其为Bean实例
+        @Primary  //在同样的DataSource中,首先使用被标注的DataSource
+        public DataSource dataSource() {
+            DruidDataSource datasource = new DruidDataSource();
+            datasource.setUrl(url);
+            datasource.setUsername(username);
+            datasource.setPassword(password);
+            datasource.setDriverClassName(driverClassName);
+
+            //configuration
+            datasource.setInitialSize(initialSize);
+            datasource.setMinIdle(minIdle);
+            datasource.setMaxActive(maxActive);
+            datasource.setMaxWait(maxWait);
+            datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
+            datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
+            datasource.setValidationQuery(validationQuery);
+            datasource.setTestWhileIdle(testWhileIdle);
+            datasource.setTestOnBorrow(testOnBorrow);
+            datasource.setTestOnReturn(testOnReturn);
+            datasource.setPoolPreparedStatements(poolPreparedStatements);
+            datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
+            try {
+                datasource.setFilters(filters);
+            } catch (SQLException e) {
+                System.err.println("druid configuration initialization filter: " + e);
+            }
+            datasource.setConnectionProperties(connectionProperties);
+            return datasource;
+        }
+
+        public String getUrl() {
+            return url;
+        }
+
+        public void setUrl(String url) {
+            this.url = url;
+        }
+
+        public String getUsername() {
+            return username;
+        }
+
+        public void setUsername(String username) {
+            this.username = username;
+        }
+
+        public String getPassword() {
+            return password;
+        }
+
+        public void setPassword(String password) {
+            this.password = password;
+        }
+
+        public String getDriverClassName() {
+            return driverClassName;
+        }
+
+        public void setDriverClassName(String driverClassName) {
+            this.driverClassName = driverClassName;
+        }
+
+        public int getInitialSize() {
+            return initialSize;
+        }
+
+        public void setInitialSize(int initialSize) {
+            this.initialSize = initialSize;
+        }
+
+        public int getMinIdle() {
+            return minIdle;
+        }
+
+        public void setMinIdle(int minIdle) {
+            this.minIdle = minIdle;
+        }
+
+        public int getMaxActive() {
+            return maxActive;
+        }
+
+        public void setMaxActive(int maxActive) {
+            this.maxActive = maxActive;
+        }
+
+        public int getMaxWait() {
+            return maxWait;
+        }
+
+        public void setMaxWait(int maxWait) {
+            this.maxWait = maxWait;
+        }
+
+        public int getTimeBetweenEvictionRunsMillis() {
+            return timeBetweenEvictionRunsMillis;
+        }
+
+        public void setTimeBetweenEvictionRunsMillis(int timeBetweenEvictionRunsMillis) {
+            this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
+        }
+
+        public int getMinEvictableIdleTimeMillis() {
+            return minEvictableIdleTimeMillis;
+        }
+
+        public void setMinEvictableIdleTimeMillis(int minEvictableIdleTimeMillis) {
+            this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
+        }
+
+        public String getValidationQuery() {
+            return validationQuery;
+        }
+
+        public void setValidationQuery(String validationQuery) {
+            this.validationQuery = validationQuery;
+        }
+
+        public boolean isTestWhileIdle() {
+            return testWhileIdle;
+        }
+
+        public void setTestWhileIdle(boolean testWhileIdle) {
+            this.testWhileIdle = testWhileIdle;
+        }
+
+        public boolean isTestOnBorrow() {
+            return testOnBorrow;
+        }
+
+        public void setTestOnBorrow(boolean testOnBorrow) {
+            this.testOnBorrow = testOnBorrow;
+        }
+
+        public boolean isTestOnReturn() {
+            return testOnReturn;
+        }
+
+        public void setTestOnReturn(boolean testOnReturn) {
+            this.testOnReturn = testOnReturn;
+        }
+
+        public boolean isPoolPreparedStatements() {
+            return poolPreparedStatements;
+        }
+
+        public void setPoolPreparedStatements(boolean poolPreparedStatements) {
+            this.poolPreparedStatements = poolPreparedStatements;
+        }
+
+        public int getMaxPoolPreparedStatementPerConnectionSize() {
+            return maxPoolPreparedStatementPerConnectionSize;
+        }
+
+        public void setMaxPoolPreparedStatementPerConnectionSize(int maxPoolPreparedStatementPerConnectionSize) {
+            this.maxPoolPreparedStatementPerConnectionSize = maxPoolPreparedStatementPerConnectionSize;
+        }
+
+        public String getFilters() {
+            return filters;
+        }
+
+        public void setFilters(String filters) {
+            this.filters = filters;
+        }
+
+        public String getConnectionProperties() {
+            return connectionProperties;
+        }
+
+        public void setConnectionProperties(String connectionProperties) {
+            this.connectionProperties = connectionProperties;
+        }
+    }
+
+}

+ 19 - 0
src/main/java/com/honter/config/LogConfig.java

@@ -0,0 +1,19 @@
+package com.honter.config;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * Created by admin on 2019/3/12.
+ */
+@Configuration
+public class LogConfig {
+    private static final Logger LOG = LoggerFactory.getLogger(LogConfig.class);
+    @Bean
+    public String logMethod() {
+        LOG.info("==========print log==========");
+        return "";
+    }
+}

+ 60 - 0
src/main/java/com/honter/config/Swagger2Config.java

@@ -0,0 +1,60 @@
+package com.honter.config;
+
+import com.google.common.base.Predicates;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.ParameterBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.schema.ModelRef;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.service.Contact;
+import springfox.documentation.service.Parameter;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @Author: hongtao li
+ * @email: yong.wang@alldobetter.com,nothingnull@foxmail.com
+ * @since: 2018/2/12 14:34.
+ */
+
+@Configuration
+public class Swagger2Config {
+    @Bean
+    public Docket api() {
+        //可以添加多个header或参数
+        ParameterBuilder aParameterBuilder = new ParameterBuilder();
+        aParameterBuilder
+                .parameterType("header") //参数类型支持header, cookie, body, query etc
+                .name("Authorization") //参数名
+                .defaultValue("Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ7XCJkYXRlXCI6MTU1MzI0NDAxOTcwOCxcInVzZXJuYW1lXCI6XCIxMjExMVwifSIsImV4cCI6OTAwMDAwMTU1MzI0NDAxOSwiaWF0IjoxNTUzMjQ0MDE5fQ.iiO_WT2uPXrNpzNIPjYhjbYfFLrswah7VrVaXLJLAXJHe451FdB00J1u7ElucAgyC3g_VnkAwz_w8oNBXfgFmQ") //默认值
+                .description("header中测试token字段")
+                .modelRef(new ModelRef("string"))//指定参数值的类型
+                .required(false).build(); //非必需,这里是全局配置,然而在登陆的时候是不用验证的
+        List<Parameter> aParameters = new ArrayList<>();
+        aParameters.add(aParameterBuilder.build());
+
+        return new Docket(DocumentationType.SWAGGER_2)
+                .apiInfo(apiInfo())
+                .pathMapping("/")
+                .select() // 选择那些路径和api会生成document
+                .apis(RequestHandlerSelectors.any())// 对所有api进行监控
+                //不显示错误的接口地址
+                .paths(Predicates.not(PathSelectors.regex("/error.*")))//错误路径不监控
+                .paths(PathSelectors.regex("/.*"))// 对根下所有路径进行监控
+                .build().globalOperationParameters(aParameters);
+    }
+
+    private ApiInfo apiInfo() {
+        return new ApiInfoBuilder().title("这是我的接口文档")
+                .version("v1.0")
+                .build();
+    }
+}

File diff suppressed because it is too large
+ 106 - 0
src/main/java/com/honter/controller/HelloController.java


+ 101 - 0
src/main/java/com/honter/ehcache/CacheConfig.java

@@ -0,0 +1,101 @@
+package com.honter.ehcache;
+
+
+import com.google.common.hash.Hashing;
+import com.honter.config.LogConfig;
+import org.apache.ibatis.jdbc.Null;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.cache.CacheManager;
+import org.springframework.cache.annotation.CachingConfigurerSupport;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.cache.ehcache.EhCacheCacheManager;
+import org.springframework.cache.interceptor.KeyGenerator;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Profile;
+import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+import org.springframework.util.ClassUtils;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Method;
+import java.nio.charset.Charset;
+
+/**
+ * Created by Smart on 2018/3/16.
+ */
+@Configuration
+@EnableCaching
+//@Profile("cache")
+public class CacheConfig extends CachingConfigurerSupport {
+    private static final Logger LOGGER = LoggerFactory.getLogger(LogConfig.class);
+    /**
+     * 缓存配置文件路径
+     */
+    @Value("${spring.cache.ehcache.config}")
+    String myCacheLocation;
+
+    /**
+     * ehcache缓存
+     */
+    @Bean
+    @Override
+    public CacheManager cacheManager() {
+
+        try {
+            return new EhCacheCacheManager(
+                    net.sf.ehcache.CacheManager.newInstance(
+                            new PathMatchingResourcePatternResolver().getResources(this.myCacheLocation)[0].getURL()
+                    ));
+        } catch (Exception ex) {
+            LOGGER.error("ehcache缓存获取异常:"+ex.getMessage());
+            return null;
+        }
+    }
+
+    /**
+     * 自动生成缓存健值
+     */
+    @Bean
+    @Override
+    public KeyGenerator keyGenerator() {
+        return new KeyGenerator() {
+            @Override
+            public Object generate(Object target, Method method, Object... params) {
+                StringBuilder key = new StringBuilder();
+                key.append(target.getClass().getSimpleName()).append(".").append(method.getName()).append(":");
+                if (params.length == 0) {
+                    //NO_PARAM_KEY
+                    return key.append(0).toString();
+                }
+                for (Object param : params) {
+                    if (param == null) {
+//                log.warn("input null param for Spring cache, use default key={}", NULL_PARAM_KEY);
+                        //NULL_PARAM_KEY
+                        key.append(53);
+                    } else if (ClassUtils.isPrimitiveArray(param.getClass())) {
+                        int length = Array.getLength(param);
+                        for (int i = 0; i < length; i++) {
+                            key.append(Array.get(param, i));
+                            key.append(',');
+                        }
+                    } else if (ClassUtils.isPrimitiveOrWrapper(param.getClass()) || param instanceof String) {
+                        key.append(param);
+                    } else {
+//                log.warn("Using an object as a cache key may lead to unexpected results. " +
+//                        "Either use @Cacheable(key=..) or implement CacheKey. Method is " + target.getClass() + "#" + method.getClassName());
+                        key.append(param.hashCode());
+                    }
+                    key.append('-');
+                }
+
+                String finalKey = key.toString();
+                long cacheKeyHash = Hashing.murmur3_128().hashString(finalKey, Charset.defaultCharset()).asLong();
+//        log.debug("using cache key={} hashCode={}", finalKey, cacheKeyHash);
+                return key.toString();
+            }
+        };
+    }
+
+}

+ 29 - 0
src/main/java/com/honter/ehcache/EhcacheUtil.java

@@ -0,0 +1,29 @@
+package com.honter.ehcache;
+
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.CacheManager;
+
+import javax.lang.model.element.Element;
+
+/**
+ * Created by admin on 2019/3/25.
+ */
+public class EhcacheUtil {
+
+    private static CacheManager cacheManager;
+
+    @Autowired
+    public EhcacheUtil(CacheManager cacheManager) {
+        EhcacheUtil.cacheManager = cacheManager;
+    }
+
+    public static void createEhcacheValue(String ehcacheName,String key,String value){
+        cacheManager.getCache(ehcacheName).put(key,value);
+    }
+
+    public static Object getEhcacheValue(String ehcacheName,String key){
+        Object value=cacheManager.getCache(ehcacheName).get(key).get();
+        return value;
+    }
+}

+ 105 - 0
src/main/java/com/honter/mail/MailSend.java

@@ -0,0 +1,105 @@
+package com.honter.mail;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeUtility;
+import java.io.File;
+import java.io.UnsupportedEncodingException;
+import java.util.Properties;
+
+/**
+ * Created by Administrator on 2017/9/29 0029.
+ */
+@Component
+public class MailSend {
+    public static  String EMAIL_OWNER_ADDR_HOST; //smtp.163.com  smtp.aliyun.com  smtp.qq.com
+    public static  String EMAIL_OWNER_ADDR;
+    public static  String EMAIL_OWNER_ADDR_PASS;
+
+    @Value("${mailsend.EMAIL_OWNER_ADDR_HOST}")
+    public  void setEmailOwnerAddrHost(String EMAIL_OWNER_ADDR_HOST) {
+        MailSend.EMAIL_OWNER_ADDR_HOST = EMAIL_OWNER_ADDR_HOST;
+    }
+
+    @Value("${mailsend.EMAIL_OWNER_ADDR}")
+    public  void setEmailOwnerAddr(String EMAIL_OWNER_ADDR) {
+        MailSend.EMAIL_OWNER_ADDR = EMAIL_OWNER_ADDR;
+    }
+
+    @Value("${mailsend.EMAIL_OWNER_ADDR_PASS}")
+    public  void setEmailOwnerAddrPass(String EMAIL_OWNER_ADDR_PASS) {
+        MailSend.EMAIL_OWNER_ADDR_PASS = EMAIL_OWNER_ADDR_PASS;
+    }
+
+    public static void sendMail(String title, String email, String content) throws MessagingException {
+        Properties prop = new Properties();
+        prop.put("mail.host", EMAIL_OWNER_ADDR_HOST);
+        prop.put("mail.transport.protocol", "smtp");
+        prop.put("mail.smtp.auth", "true");
+        //如果不加下面的这行代码 windows下正常,linux环境下发送失败,解决:http://www.cnblogs.com/Harold-Hua/p/7029117.html
+        prop.setProperty("mail.smtp.ssl.enable", "true");
+        //使用java发送邮件5步骤
+        //1.创建sesssion
+        Session session = Session.getInstance(prop);
+        //开启session的调试模式,可以查看当前邮件发送状态
+        //session.setDebug(true);
+
+        //2.通过session获取Transport对象(发送邮件的核心API)
+        Transport ts = session.getTransport();
+        //3.通过邮件用户名密码链接,阿里云默认是开启个人邮箱pop3、smtp协议的,所以无需在阿里云邮箱里设置
+        ts.connect(EMAIL_OWNER_ADDR, EMAIL_OWNER_ADDR_PASS);
+
+        //4.创建邮件
+        //创建邮件对象
+        MimeMessage mm = new MimeMessage(session);
+        //设置发件人
+        mm.setFrom(new InternetAddress(EMAIL_OWNER_ADDR));
+        //设置收件人
+        mm.setRecipient(Message.RecipientType.TO, new InternetAddress(email));
+        //设置抄送人
+        //mm.setRecipient(Message.RecipientType.CC, new InternetAddress("XXXX@qq.com"));
+
+        //mm.setSubject("吸引力注册邮件");
+        mm.setSubject(title);
+
+        //mm.setContent("您的注册验证码为:<b style=\"color:blue;\">0123</b>", "text/html;charset=utf-8");
+        mm.setContent(content, "text/html;charset=utf-8");
+
+        // true表示开始附件模式 -----------------------------------------------------------------------
+        /*MimeMessageHelper messageHelper = new MimeMessageHelper(mm, true, "utf-8");
+        // 设置收件人,寄件人
+        messageHelper.setTo(email);
+        messageHelper.setFrom(EMAIL_OWNER_ADDR);
+        messageHelper.setSubject(title);
+        // true 表示启动HTML格式的邮件
+        messageHelper.setText(content, true);
+
+        FileSystemResource file1 = new FileSystemResource(new File("d:/rongke.log"));
+        FileSystemResource file2 = new FileSystemResource(new File("d:/新建文本文档.txt"));
+        // 添加2个附件
+        messageHelper.addAttachment("rongke.log", file1);
+        try {
+            //附件名有中文可能出现乱码
+            messageHelper.addAttachment(MimeUtility.encodeWord("新建文本文档.txt"), file2);
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+            throw new MessagingException();
+        }*/
+        //-------------------------------------------------------------------------------------------
+        //5.发送电子邮件
+
+        ts.sendMessage(mm, mm.getAllRecipients());
+    }
+
+    public static void main(String[] args) throws MessagingException {
+        //sendMail("吸引力注册邮件", "xxx@qq.com", "您的注册验证码为:<b style=\"color:blue;\">651899</b>");
+        sendMail("吸引力", "li.hongtaolove@163.com", "spring boot 邮件测试");
+    }
+}

+ 24 - 0
src/main/java/com/honter/mapper/UserMapper.java

@@ -0,0 +1,24 @@
+package com.honter.mapper;
+
+import com.honter.model.User;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+public interface UserMapper {
+    int deleteByPrimaryKey(@Param("userId")Integer userId);
+
+    int insert(User record);
+
+    int insertSelective(User record);
+
+    User selectByPrimaryKey(@Param("userId")Integer userId);
+
+    int updateByPrimaryKeySelective(User record);
+
+    int updateByPrimaryKey(User record);
+
+    List<User> getUsersByuserId(@Param("userId")Integer userId,@Param("userName")String userName);
+
+    User getUsersByUserName(@Param("userName")String userName);
+}

+ 43 - 0
src/main/java/com/honter/model/User.java

@@ -0,0 +1,43 @@
+package com.honter.model;
+
+public class User {
+    private Integer userId;
+
+    private String userName;
+
+    private String password;
+
+    private String phone;
+
+    public Integer getUserId() {
+        return userId;
+    }
+
+    public void setUserId(Integer userId) {
+        this.userId = userId;
+    }
+
+    public String getUserName() {
+        return userName;
+    }
+
+    public void setUserName(String userName) {
+        this.userName = userName == null ? null : userName.trim();
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password == null ? null : password.trim();
+    }
+
+    public String getPhone() {
+        return phone;
+    }
+
+    public void setPhone(String phone) {
+        this.phone = phone == null ? null : phone.trim();
+    }
+}

+ 22 - 0
src/main/java/com/honter/security/AuthenticationEntryPointImpl.java

@@ -0,0 +1,22 @@
+package com.honter.security;
+
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.web.AuthenticationEntryPoint;
+import org.springframework.stereotype.Service;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * Created by Shuangyao
+ * 16:34 2018/9/9
+ */
+@Service
+public class AuthenticationEntryPointImpl implements AuthenticationEntryPoint {
+    @Override
+    public void commence(HttpServletRequest httpServletRequest,
+                         HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException {
+        httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, e.getMessage());
+    }
+}

+ 21 - 0
src/main/java/com/honter/security/DatabaseUserDetailService.java

@@ -0,0 +1,21 @@
+package com.honter.security;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.stereotype.Service;
+
+/**
+ * This service will reload user information from database.
+ */
+@Service
+public class DatabaseUserDetailService implements UserDetailsService {
+
+    @Autowired
+    private UserAuthService userAuthService;
+
+    @Override
+    public UserDetails loadUserByUsername(String userName) {
+        return userAuthService.getUserDetailByUserName(userName);
+    }
+}

+ 102 - 0
src/main/java/com/honter/security/JwtAuthenticationFilter.java

@@ -0,0 +1,102 @@
+package com.honter.security;
+
+import com.alibaba.fastjson.JSONObject;
+import com.honter.config.ConfigBeanValue;
+import io.jsonwebtoken.Jwts;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.stereotype.Component;
+import org.springframework.web.filter.OncePerRequestFilter;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Created by Shuangyao
+ * 22:55 2018/10/15
+ */
+public class JwtAuthenticationFilter extends OncePerRequestFilter {
+
+    private Logger logger = LoggerFactory.getLogger(JwtAuthenticationFilter.class);
+
+    @Autowired
+    private JwtTokenProvider jwtTokenProvider;
+
+    @Autowired
+    private ConfigBeanValue configBeanValue;
+
+    @Autowired
+    private UserAuthService userAuthService;
+
+    //1.从每个请求header获取token
+    //2.调用前面写的validateToken方法对token进行合法性验证
+    //3.解析得到username,并从database取出用户相关信息权限
+    //4.把用户信息以UserDetail形式放进SecurityContext以备整个请求过程使用。
+    // (例如哪里需要判断用户权限是否足够时可以直接从SecurityContext取出去check
+    @Override
+    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
+            throws ServletException, IOException {
+        String token = getJwtFromRequest(request);
+
+        if (token != null && jwtTokenProvider.validateToken(token)) {
+            Map<String, Object> map = new HashMap<String, Object>();
+            map = getUsernameFromJwt(token);
+            String username = map!=null?(map.get("username")!=null?(String)map.get("username"):""):"";
+            UserDetails userDetails = userAuthService.getUserDetailByUserName(username);
+            //SecurityContextHolder.getContext().getAuthentication().getCredentials()获取map得值
+            Authentication authentication = new UsernamePasswordAuthenticationToken(
+                    userDetails, map, userDetails.getAuthorities());
+            SecurityContextHolder.getContext().setAuthentication(authentication);
+            //自动刷新token并保存到Reponse中
+            AutomaticallyRefreshToken(map,response);
+        } else {
+            logger.error(request.getParameter("username") + " :Token is null");
+        }
+        super.doFilter(request, response, filterChain);
+    }
+
+    private String getJwtFromRequest(HttpServletRequest request) {
+        String token = request.getHeader("Authorization");
+        if (token != null && token.startsWith("Bearer")) {
+            return token.replace("Bearer ", "");
+        }
+        return null;
+    }
+
+    private Map<String, Object> getUsernameFromJwt(String token) {
+        String mapstr=Jwts.parser().setSigningKey(configBeanValue.getJwtTokenSecret())
+                .parseClaimsJws(token)
+                .getBody()
+                .getSubject();
+        Map<String, Object> map = new HashMap<String, Object>();
+        map=(Map) JSONObject.parse(mapstr);
+        return map;
+    }
+
+    private void AutomaticallyRefreshToken(Map<String, Object> map,HttpServletResponse response){
+        if(map!=null&&map.get("date")!=null){
+            Long dd=(Long)map.get("date");
+            Date now=new Date();
+            if(now.getTime()-dd>configBeanValue.getTokenRefreshMs()){
+                map.put("date",now.getTime());
+                response.setHeader("Authorization","Bearer "+jwtTokenProvider.createJwtTokenContMap(map));
+            }
+        }else{
+            map.put("date",new Date().getTime());
+            response.setHeader("Authorization","Bearer "+jwtTokenProvider.createJwtTokenContMap(map));
+        }
+    }
+}

+ 79 - 0
src/main/java/com/honter/security/JwtTokenProvider.java

@@ -0,0 +1,79 @@
+package com.honter.security;
+
+import com.alibaba.fastjson.JSONObject;
+import com.honter.config.ConfigBeanValue;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.SignatureAlgorithm;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.core.Authentication;
+import org.springframework.stereotype.Component;
+
+import java.util.Date;
+import java.util.Map;
+
+@Component
+public class JwtTokenProvider {
+
+    Logger logger = LoggerFactory.getLogger(JwtTokenProvider.class);
+
+    @Autowired
+    private ConfigBeanValue configBeanValue;
+
+    /**
+     * Generate token for user login.
+     *
+     * @param authentication
+     * @return return a token string.
+     */
+    public String createJwtToken(Authentication authentication) {
+        //user name
+        String username = ((org.springframework.security.core.userdetails
+                .User) authentication.getPrincipal()).getUsername();
+        //expire time
+        Date expireTime = new Date(System.currentTimeMillis() + configBeanValue.getTokenExpiredMs());
+        //create token
+        String token = Jwts.builder()
+                .setSubject(username)
+                .setExpiration(expireTime)
+                .setIssuedAt(new Date())
+                .signWith(SignatureAlgorithm.HS512, configBeanValue.getJwtTokenSecret())
+                .compact();
+
+        return token;
+    }
+
+    /**
+     * validate token eligible.
+     * if Jwts can parse the token string and no throw any exception, then the token is eligible.
+     *
+     * @param token a jws string.
+     */
+    public boolean validateToken(String token) {
+        String VALIDATE_FAILED = "validate failed : ";
+        //ExpiredJwtException, UnsupportedJwtException, MalformedJwtException, SignatureException, IllegalArgumentException
+        try {
+            Jwts.parser().setSigningKey(configBeanValue.getJwtTokenSecret()).parseClaimsJws(token);
+            return true;
+        } catch (Exception ex) {
+            logger.error(VALIDATE_FAILED + ex.getMessage());
+
+            return false;
+        }
+    }
+    public String createJwtTokenContMap(Map<String, Object> map) {
+        //expire time
+        Date expireTime = new Date(System.currentTimeMillis() + configBeanValue.getTokenExpiredMs());
+        //create token
+        String token = Jwts.builder()
+                .setSubject(JSONObject.toJSON(map).toString())
+                .setExpiration(expireTime)
+                .setIssuedAt(new Date())
+                .signWith(SignatureAlgorithm.HS512, configBeanValue.getJwtTokenSecret())
+                .compact();
+
+        return token;
+    }
+
+}

+ 48 - 0
src/main/java/com/honter/security/UserAuthService.java

@@ -0,0 +1,48 @@
+package com.honter.security;
+
+import com.honter.model.User;
+import com.honter.service.UserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Created by Shuangyao
+ * 23:08 2018/9/6
+ */
+@Service
+public class UserAuthService {
+
+    @Autowired
+    private UserService userService;
+
+    /**
+     * Get {@link UserDetails} by user name.
+     * @return
+     */
+    @Transactional
+    public UserDetails getUserDetailByUserName(String username){
+
+        User user = userService.getUsersByUserName(username);
+
+        if(user == null){
+            throw new UsernameNotFoundException("user + " + username + "not found.");
+        }
+
+//        List<String> roleList = this.userRepository.queryUserOwnedRoleCodes(username);
+        List<String> roleList =new ArrayList<>();
+//        roleList.add("all");
+        List<GrantedAuthority> authorities = roleList.stream()
+                .map(role -> new SimpleGrantedAuthority(role)).collect(Collectors.toList());
+        return new org.springframework.security.core.userdetails
+                .User(username,user.getPassword(),authorities);
+    }
+}

+ 67 - 0
src/main/java/com/honter/security/WebSecurityConfig.java

@@ -0,0 +1,67 @@
+package com.honter.security;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.builders.WebSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.config.http.SessionCreationPolicy;
+import org.springframework.security.web.AuthenticationEntryPoint;
+import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
+
+/**
+ * Created by admin on 2019/3/19.
+ */
+@EnableWebSecurity
+//@EnableGlobalMethodSecurity(prePostEnabled = true)
+public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
+    @Autowired
+    private AuthenticationEntryPointImpl entryPoint;
+    @Autowired
+    private DatabaseUserDetailService userDetailsService;
+    @Bean
+    public JwtAuthenticationFilter getJwtAuthenticationFilter(){
+        return new JwtAuthenticationFilter();
+    }
+    protected void configure(HttpSecurity http) throws Exception {
+        http
+                .addFilterBefore(getJwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
+                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
+                .and().csrf().disable()
+                .authorizeRequests()
+                //以下路径不需要swagger验证权限
+                .antMatchers("/api/v1/login").permitAll()
+                .antMatchers("/swagger*//**").permitAll()
+                .antMatchers("/webjars/**").permitAll()
+                .antMatchers("/v2/api-docs",//swagger api json
+                        "/swagger-resources/configuration/ui",//用来获取支持的动作
+                        "/swagger-resources",//用来获取api-docs的URL
+                        "/swagger-resources/configuration/security",//安全选择
+                        "/swagger-ui.html"
+                ).permitAll()
+                //以下路径不需要业务验证权限
+                .antMatchers("/ceshi/login").permitAll()
+                .anyRequest().authenticated()
+                .and()
+//                .sessionManagement().disable()
+                .cors()
+//                .and().formLogin().loginProcessingUrl("/ceshi/login")
+//                .successHandler(successHandler)
+//                .failureHandler(failHandler)
+                //统一进行异常处理
+                .and().exceptionHandling().authenticationEntryPoint(entryPoint);
+    }
+    @Override
+    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
+        auth.userDetailsService(userDetailsService);
+    }
+    //允许访问druid资源
+    @Override
+    public void configure(WebSecurity web) throws Exception {
+        web.ignoring().antMatchers("/druid/**");
+        //可以仿照上面一句忽略静态资源
+    }
+}

+ 20 - 0
src/main/java/com/honter/service/UserService.java

@@ -0,0 +1,20 @@
+package com.honter.service;
+
+import com.honter.model.User;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Isolation;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+/**
+ * Created by admin on 2019/3/7.
+ */
+public interface UserService {
+    public User queryUserByUserId(Integer userId);
+    @Transactional(isolation = Isolation.REPEATABLE_READ)
+    public Integer insertUser(User user);
+    public void updateUserByUserId(User user);
+    public List<User> getUsersByuserId(Integer userId, String userName);
+    public User getUsersByUserName(String userName);
+}

+ 93 - 0
src/main/java/com/honter/serviceImpl/UserServiceImpl.java

@@ -0,0 +1,93 @@
+package com.honter.serviceImpl;
+
+import com.honter.mapper.UserMapper;
+import com.honter.model.User;
+import com.honter.service.UserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+import org.springframework.transaction.annotation.Isolation;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Created by admin on 2019/3/5.
+ */
+@EnableTransactionManagement
+@Service
+public class UserServiceImpl implements UserService {
+    @Autowired
+    private UserMapper userMapper;
+    public User queryUserByUserId(Integer userId){
+        SimpleDateFormat ft = new SimpleDateFormat ("yyyy.MM.dd hh:mm:ss");
+        Date now = new Date( );
+        System.out.println("开始时间:"+ft.format(now));
+        try {
+            Thread.sleep(3);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+        Date nowOver = new Date( );
+        System.out.println("结束时间:"+ft.format(nowOver));
+        User user=userMapper.selectByPrimaryKey(userId);
+        return user;
+    }
+
+    /**
+     *  Isolation.READ_UNCOMMITTED读取未提交数据(会出现脏读, 不可重复读) 基本不使用
+     *  Isolation.READ_COMMITTED读取已提交数据(会出现不可重复读和幻读)
+     *  Isolation.REPEATABLE_READ可重复读(会出现幻读)
+     *  Isolation.SERIALIZABLE串行化
+
+     MYSQL: 默认为REPEATABLE_READ级别
+     SQLSERVER: 默认为READ_COMMITTED
+
+     脏读 : 一个事务读取到另一事务未提交的更新数据
+     不可重复读 : 在同一事务中, 多次读取同一数据返回的结果有所不同, 换句话说, 
+     后续读取可以读到另一事务已提交的更新数据. 相反, "可重复读"在同一事务中多次
+     读取数据时, 能够保证所读数据一样, 也就是后续读取不能读到另一事务已提交的更新数据
+     幻读 : 一个事务读到另一个事务已提交的insert数据
+
+     @Transactional 只能被应用到public方法上, 对于其它非public的方法,
+     如果标记了@Transactional也不会报错,但方法没有事务功能
+     @Transactional可以放在接口的方法中
+     */
+    public Integer insertUser(User user){
+        userMapper.insertSelective(user);
+//        String str=null;
+//        str.equals("ss");
+        return user.getUserId();
+    }
+    @Transactional(isolation = Isolation.REPEATABLE_READ)
+    public void updateUserByUserId(User user){
+        User user33=userMapper.selectByPrimaryKey(user.getUserId());
+        System.out.println(user33.getPhone());
+        SimpleDateFormat ft = new SimpleDateFormat ("yyyy.MM.dd hh:mm:ss");
+        Date now = new Date( );
+        System.out.println("开始时间:"+ft.format(now));
+        try {
+            Thread.sleep(3);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+        Date nowOver = new Date( );
+        System.out.println("结束时间:"+ft.format(nowOver));
+        User user44=userMapper.selectByPrimaryKey(user.getUserId());
+        System.out.println(user44.getPhone());
+        userMapper.updateByPrimaryKeySelective(user);
+    }
+    public List<User> getUsersByuserId(Integer userId,String userName){
+        List<User> list=new ArrayList<User>();
+        list=userMapper.getUsersByuserId(userId,userName);
+        return  list;
+    }
+
+    @Override
+    public User getUsersByUserName(String userName) {
+        return userMapper.getUsersByUserName(userName);
+    }
+}

+ 81 - 0
src/main/java/com/honter/util/JwtToken.java

@@ -0,0 +1,81 @@
+package com.honter.util;
+
+import com.alibaba.fastjson.JSONObject;
+import com.auth0.jwt.JWT;
+import com.auth0.jwt.JWTVerifier;
+import com.auth0.jwt.algorithms.Algorithm;
+import com.auth0.jwt.exceptions.InvalidClaimException;
+import com.auth0.jwt.interfaces.Claim;
+import com.auth0.jwt.interfaces.DecodedJWT;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.stereotype.Component;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Created by admin on 2019/3/13.
+ */
+//@Component
+@Configuration
+public class JwtToken {
+//    @Value("${jwt.SECRET}")
+//    public  String SECRET;
+//
+//    @Value("${jwt.MINUTE}")
+//    public  Integer MINUTE;
+    private static String SECRET;
+    private static Integer MINUTE;
+    @Value("${jwt.SECRET}")
+    public void setSECRET(String SECRET){
+        JwtToken.SECRET=SECRET;
+    }
+    @Value("${jwt.MINUTE}")
+    public void setMINUTE(Integer MINUTE){
+        JwtToken.MINUTE=MINUTE;
+    }
+
+    /**
+     * 生成token
+     */
+    public static  String createToken(Map<String, Object> map) throws Exception{
+        //签发时间
+        Date iatDate=new Date();
+        //过期时间设置--1分钟
+        Calendar nowTime=Calendar.getInstance();
+        nowTime.add(Calendar.MINUTE,MINUTE);
+        Date expiresDate=nowTime.getTime();
+        Map<String, Object> mapHeader = new HashMap<String, Object>();
+        mapHeader.put("alg", "HS256");
+        mapHeader.put("typ", "JWT");
+        String token= JWT.create()
+                .withHeader(map)
+                .withClaim("claim", JSONObject.toJSON(map).toString())
+                .withExpiresAt(expiresDate)//设置过期时间,过期时间必须大于签发时间
+                .withIssuedAt(iatDate)//设置签发时间
+                .sign(Algorithm.HMAC256(SECRET.getBytes()));
+        return token;
+    }
+    /**
+     * 解密token
+     */
+    public static  Map<String, Object> verifyToken(String token) {
+        Map<String, Object> map = new HashMap<String, Object>();
+        String claimStr=null;
+        try {
+            JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET.getBytes())).build();
+            DecodedJWT jwt=verifier.verify(token);
+            claimStr=jwt.getClaim("claim").asString();
+            map=(Map) JSONObject.parse(claimStr);
+        } catch (InvalidClaimException e) {
+            map.put("claim","InvalidClaim");
+        } catch (Exception e) {
+            map.put("claim","error");
+        }
+        return map;
+    }
+}

File diff suppressed because it is too large
+ 69 - 0
src/main/java/com/honter/util/JwtUtil.java


+ 31 - 0
src/main/java/com/honter/util/SchedulerTask.java

@@ -0,0 +1,31 @@
+package com.honter.util;
+
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * Created by admin on 2018/8/9.
+ */
+@Component
+public class SchedulerTask {
+    private int count=0;
+    /**
+     * 每隔6秒执行定时任务
+     */
+    @Scheduled(cron="*/6 * * * * ?")
+    private void process(){
+        System.out.println("this is scheduler task runing "+(count++));
+    }
+    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
+    /**
+     *每隔6秒执行定时任务
+     */
+    @Scheduled(fixedRate = 6000)
+    public void reportCurrentTime() {
+        System.out.println("现在时间:" + dateFormat.format(new Date()));
+
+    }
+}

+ 5 - 0
src/main/resources/application-prod.properties

@@ -0,0 +1,5 @@
+spring.datasource.driver-class-name=com.mysql.jdbc.Driver
+spring.datasource.url=jdbc:mysql://rm-bp1l6z8z3gx8b8d668o.mysql.rds.aliyuncs.com:3306/myprod?useUnicode=true&amp;characterEncoding=utf8
+spring.datasource.username=root
+spring.datasource.password=02163856abcd@
+

+ 6 - 0
src/main/resources/application-test.properties

@@ -0,0 +1,6 @@
+#Êý¾Ý¿â
+spring.datasource.driver-class-name=com.mysql.jdbc.Driver
+spring.datasource.url=jdbc:mysql://rm-bp1l6z8z3gx8b8d668o.mysql.rds.aliyuncs.com:3306/mytest?useUnicode=true&amp;characterEncoding=utf8
+spring.datasource.username=root
+spring.datasource.password=02163856abcd@
+

+ 56 - 0
src/main/resources/application.properties

@@ -0,0 +1,56 @@
+server.port=1122
+server.context-path=/honter
+#引用配置文件test为测试环境,prod为生产环境
+spring.profiles.active=test
+#spring.profiles.active=prod
+#公共配置 sql,mysql,oracle
+spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
+#spring.datasource.driver-class-name=com.mysql.jdbc.Driver
+#spring.datasource.url=jdbc:mysql://rm-bp1l6z8z3gx8b8d668o.mysql.rds.aliyuncs.com:3306/mytest?useUnicode=true&amp;characterEncoding=utf8
+#spring.datasource.username=root
+#spring.datasource.password=02163856abcd@
+spring.datasource.filters=stat,wall,log4j
+spring.datasource.maxActive=100
+spring.datasource.initialSize=1
+spring.datasource.maxWait=60000
+spring.datasource.minIdle=1
+spring.datasource.timeBetweenEvictionRunsMillis=60000
+spring.datasource.minEvictableIdleTimeMillis=300000
+spring.datasource.validationQuery=select 'x'
+spring.datasource.testWhileIdle=true
+spring.datasource.testOnBorrow=false
+spring.datasource.testOnReturn=false
+spring.datasource.poolPreparedStatements=true
+spring.datasource.maxOpenPreparedStatements=50
+spring.datasource.logSlowSql=true
+#映射文件配置地址
+mybatis.mapper-locations=classpath:mapping/*.xml
+#扫描类
+mybatis.type-aliases-package=com.honter.model
+#分页查询配置
+pagehelper.helperDialect=mysql
+pagehelper.reasonable=true
+pagehelper.supportMethodsArguments=true
+pagehelper.params=count=countSql
+#tomcat做反向代理配置,发生反向代理的使用使用如nginx反向代理配置
+#server.tomcat.remote_ip_header=x-forwarded-for
+#server.tomcat.protocol_header=x-forwarded-proto
+#server.tomcat.port-header=X-Forwarded-Port
+#server.use-forward-headers=true
+#核心Logger(包含嵌入式容器、hibernate、spring)会输出更多内容,但是你自己应用的日志并不会输出为DEBUG级别
+#debug=true
+#日志文件
+logging.config=classpath:logging-config.xml
+#JwtToken参数,SECRET为密钥,MINUTE为过期时间单位分钟
+jwt.SECRET=79e7c69681b8270162386e6daa53d1dclihongtao
+jwt.MINUTE=1
+#ehcache缓存配置文件
+spring.cache.ehcache.config=ehcache-config.xml
+#springboot JWTSecurity参数,单位毫秒
+jwtspringboot.jwtTokenSecret = Sayo
+jwtspringboot.tokenExpiredMs = 9000000000000000000
+jwtspringboot.tokenRefreshMs = 120000
+#邮件发送常量参数smtp.163.com  smtp.aliyun.com  smtp.qq.com
+mailsend.EMAIL_OWNER_ADDR_HOST = smtp.aliyun.com
+mailsend.EMAIL_OWNER_ADDR = lihongtaolove@aliyun.com
+mailsend.EMAIL_OWNER_ADDR_PASS = 02163856abcd

+ 35 - 0
src/main/resources/application.yml

@@ -0,0 +1,35 @@
+#server:
+#  port: 1111
+#  context-path:/honter
+#spring:
+#    datasource:
+#        name: test
+#        url: jdbc:mysql://172.16.10.53:3307/l_superf10?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true
+#        username: root
+#        password: 123456
+
+#        type: com.alibaba.druid.pool.DruidDataSource
+#        driver-class-name: com.mysql.jdbc.Driver
+#        filters: stat,wall,log4j
+#        maxActive: 20
+#        initialSize: 1
+#        maxWait: 60000
+#        minIdle: 1
+#        timeBetweenEvictionRunsMillis: 60000
+#        minEvictableIdleTimeMillis: 300000
+#        validationQuery: select 'x'
+#        testWhileIdle: true
+#        testOnBorrow: false
+#        testOnReturn: false
+#        poolPreparedStatements: true
+#        maxOpenPreparedStatements: 20
+#        logSlowSql: true
+#mybatis:
+#  mapper-locations: classpath:mapping/*.xml
+#  type-aliases-package: com.honter.model
+##pagehelper
+#pagehelper:
+#    helperDialect: mysql
+#    reasonable: true
+#    supportMethodsArguments: true
+#    params: count=countSql

+ 121 - 0
src/main/resources/ehcache-config.xml

@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
+         updateCheck="false">
+    <diskStore path="/data/alldoEdu/cache"/>
+    <defaultCache
+            maxElementsInMemory="50000"
+            maxElementsOnDisk="100000"
+            eternal="false"
+            timeToIdleSeconds="1200"
+            timeToLiveSeconds="3600"
+            overflowToDisk="true"
+            memoryStoreEvictionPolicy="LRU"
+            diskPersistent="false"
+            diskExpiryThreadIntervalSeconds="120"
+    />
+
+    <!--用于基础模块-->
+    <cache name="appCache"
+           maxElementsInMemory="500"
+           maxElementsOnDisk="1000"
+           eternal="false"
+           timeToIdleSeconds="86400"
+           timeToLiveSeconds="86400"
+           overflowToDisk="true"
+           memoryStoreEvictionPolicy="LRU"
+           diskPersistent="false"
+           diskExpiryThreadIntervalSeconds="10"
+    />
+
+    <!--用于信息发布模块-->
+    <cache name="infoCache"
+           maxElementsInMemory="500"
+           maxElementsOnDisk="1000"
+           eternal="false"
+           timeToIdleSeconds="30"
+           timeToLiveSeconds="30"
+           overflowToDisk="true"
+           memoryStoreEvictionPolicy="LRU"
+           diskPersistent="false"
+           diskExpiryThreadIntervalSeconds="10"
+    />
+
+    <!--用于投教模块-->
+    <cache name="eduCache"
+           maxElementsInMemory="500"
+           maxElementsOnDisk="1000"
+           eternal="false"
+           timeToIdleSeconds="1200"
+           timeToLiveSeconds="3600"
+           overflowToDisk="true"
+           memoryStoreEvictionPolicy="LRU"
+           diskPersistent="false"
+           diskExpiryThreadIntervalSeconds="120"
+    />
+
+    <!--用于游戏模块-->
+    <cache name="gameCache"
+           maxElementsInMemory="500"
+           maxElementsOnDisk="1000"
+           eternal="false"
+           timeToIdleSeconds="180"
+           timeToLiveSeconds="300"
+           overflowToDisk="true"
+           memoryStoreEvictionPolicy="LRU"
+           diskPersistent="false"
+           diskExpiryThreadIntervalSeconds="120"
+    />
+
+    <!--用于游戏模块-高频-->
+    <cache name="gameHFCache"
+           maxElementsInMemory="500"
+           maxElementsOnDisk="1000"
+           eternal="false"
+           timeToIdleSeconds="5"
+           timeToLiveSeconds="10"
+           overflowToDisk="true"
+           memoryStoreEvictionPolicy="LRU"
+           diskPersistent="false"
+           diskExpiryThreadIntervalSeconds="120"
+    />
+    <!--
+
+    name:缓存名称。通常为缓存对象的类名(非严格标准)。
+
+    maxElementsInMemory:设置基于内存的缓存可存放对象的最大数目。
+
+    maxElementsOnDisk:设置基于硬盘的缓存可存放对象的最大数目。
+
+    eternal:如果为true,表示对象永远不会过期,此时会忽略timeToIdleSeconds和timeToLiveSeconds属性,默认为false;
+
+    timeToIdleSeconds: 设定允许对象处于空闲状态的最长时间,以秒为单位。
+    当对象自从最近一次被访问后,如果处于空闲状态的时间超过了timeToIdleSeconds属性值,这个对象就会过期。
+    当对象过期,EHCache将把它从缓存中清空。只有当eternal属性为false,该属性才有效。
+    如果该属性值为0,则表示对象可以无限期地处于空闲状态。
+
+    timeToLiveSeconds:设定对象允许存在于缓存中的最长时间,以秒为单位。
+    当对象自从被存放到缓存中后,如果处于缓存中的时间超过了 timeToLiveSeconds属性值,这个对象就会过期。
+    当对象过期,EHCache将把它从缓存中清除。只有当eternal属性为false,该属性才有效。
+    如果该属性值为0,则表示对象可以无限期地存在于缓存中。timeToLiveSeconds必须大于timeToIdleSeconds属性,才有意义。
+
+    overflowToDisk:如果为true,表示当基于内存的缓存中的对象数目达到了maxElementsInMemory界限后,
+    会把益出的对象写到基于硬盘的缓存中。注意:如果缓存的对象要写入到硬盘中的话,则该对象必须实现了Serializable接口才行。
+
+    memoryStoreEvictionPolicy:缓存对象清除策略。有三种:
+    1 FIFO ,first in first out ,这个是大家最熟的,先进先出,不多讲了
+    2 LFU , Less Frequently Used ,就是上面例子中使用的策略,直白一点就是讲一直以来最少被使用的。
+    如上面所讲,缓存的元素有一个hit 属性,hit 值最小的将会被清出缓存。
+    3 LRU ,Least Recently Used ,最近最少使用的,缓存的元素有一个时间戳,当缓存容量满了,
+    而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。
+
+    Ehcache有一个后台线程专门做Ellment失效监测以及清除工作。设置线程运行间隔时间,
+    可通过设置diskExpiryThreadIntervalSeconds属性来完成,此值不宜设置过低,否则会导致清理线程占用大量CPU资源。默认值是120秒
+
+    持久化可在Element的diskPersistent配置项中配置,如果配置为“false”或是“omitted”在CacheManager shutdown或是startup后,
+    用来缓存Element的文件将被清除掉。如果设置为“true”,data和index文件会被保存下来,对于新创建的CacheManager Element也是可用的。
+
+     -->
+
+
+</ehcache>

+ 36 - 0
src/main/resources/generator/generatorConfig.xml

@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE generatorConfiguration
+        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
+        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
+<generatorConfiguration>
+    <!-- 数据库驱动:选择你的本地硬盘上面的数据库驱动包-->
+    <classPathEntry  location="C:\Users\admin\.m2\repository\mysql\mysql-connector-java\5.1.46\mysql-connector-java-5.1.46.jar"/>
+    <context id="DB2Tables"  targetRuntime="MyBatis3">
+        <commentGenerator>
+            <property name="suppressDate" value="true"/>
+            <!-- 是否去除自动生成的注释 true:是 : false:否 -->
+            <property name="suppressAllComments" value="true"/>
+        </commentGenerator>
+        <!--数据库链接URL,用户名、密码 -->
+        <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://172.16.10.53:3307/l_superf10" userId="root" password="123456">
+        </jdbcConnection>
+        <javaTypeResolver>
+            <property name="forceBigDecimals" value="false"/>
+        </javaTypeResolver>
+        <!-- 生成模型的包名和位置-->
+        <javaModelGenerator targetPackage="com.honter.model" targetProject="src/main/java">
+            <property name="enableSubPackages" value="true"/>
+            <property name="trimStrings" value="true"/>
+        </javaModelGenerator>
+        <!-- 生成映射文件的包名和位置-->
+        <sqlMapGenerator targetPackage="mapping" targetProject="src/main/resources">
+            <property name="enableSubPackages" value="true"/>
+        </sqlMapGenerator>
+        <!-- 生成DAO的包名和位置-->
+        <javaClientGenerator type="XMLMAPPER" targetPackage="com.honter.mapper" targetProject="src/main/java">
+            <property name="enableSubPackages" value="true"/>
+        </javaClientGenerator>
+        <!-- 要生成的表 tableName是数据库中的表名或视图名 domainObjectName是实体类名-->
+        <table tableName="t_user" domainObjectName="User" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>
+    </context>
+</generatorConfiguration>

+ 189 - 0
src/main/resources/logging-config.xml

@@ -0,0 +1,189 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 -->
+<!-- scan:当此属性设置为true时,配置文档如果发生改变,将会被重新加载,默认值为true -->
+<!-- scanPeriod:设置监测配置文档是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。
+                 当scan为true时,此属性生效。默认的时间间隔为1分钟。 -->
+<!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->
+<configuration  scan="true" scanPeriod="10 seconds">
+    <contextName>logback</contextName>
+    <!-- name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义后,可以使“${}”来使用变量。 -->
+    <property name="log.path" value="/logs/springboot/" />
+
+    <!--0. 日志格式和颜色渲染 -->
+    <!-- 彩色日志依赖的渲染类 -->
+    <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
+    <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
+    <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
+    <!-- 彩色日志格式 -->
+    <property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
+
+    <!--1. 输出到控制台-->
+    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+        <!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息-->
+        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+            <level>info</level>
+        </filter>
+        <encoder>
+            <Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
+            <!-- 设置字符集 -->
+            <charset>UTF-8</charset>
+        </encoder>
+    </appender>
+
+    <!--2. 输出到文档-->
+    <!-- 2.1 level为 DEBUG 日志,时间滚动输出  -->
+    <appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 正在记录的日志文档的路径及文档名 -->
+        <file>${log.path}/web_debug.log</file>
+        <!--日志文档输出格式-->
+        <encoder>
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+            <charset>UTF-8</charset> <!-- 设置字符集 -->
+        </encoder>
+        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 日志归档 -->
+            <fileNamePattern>${log.path}/web-debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <maxFileSize>100MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+            <!--日志文档保留天数-->
+            <maxHistory>15</maxHistory>
+        </rollingPolicy>
+        <!-- 此日志文档只记录debug级别的 -->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>debug</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <!-- 2.2 level为 INFO 日志,时间滚动输出  -->
+    <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 正在记录的日志文档的路径及文档名 -->
+        <file>${log.path}/web_info.log</file>
+        <!--日志文档输出格式-->
+        <encoder>
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+            <charset>UTF-8</charset>
+        </encoder>
+        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 每天日志归档路径以及格式 -->
+            <fileNamePattern>${log.path}/web-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <maxFileSize>100MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+            <!--日志文档保留天数-->
+            <maxHistory>15</maxHistory>
+        </rollingPolicy>
+        <!-- 此日志文档只记录info级别的 -->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>info</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <!-- 2.3 level为 WARN 日志,时间滚动输出  -->
+    <appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 正在记录的日志文档的路径及文档名 -->
+        <file>${log.path}/web_warn.log</file>
+        <!--日志文档输出格式-->
+        <encoder>
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+            <charset>UTF-8</charset> <!-- 此处设置字符集 -->
+        </encoder>
+        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <fileNamePattern>${log.path}/web-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <maxFileSize>100MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+            <!--日志文档保留天数-->
+            <maxHistory>15</maxHistory>
+        </rollingPolicy>
+        <!-- 此日志文档只记录warn级别的 -->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>warn</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <!-- 2.4 level为 ERROR 日志,时间滚动输出  -->
+    <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 正在记录的日志文档的路径及文档名 -->
+        <file>${log.path}/web_error.log</file>
+        <!--日志文档输出格式-->
+        <encoder>
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+            <charset>UTF-8</charset> <!-- 此处设置字符集 -->
+        </encoder>
+        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <fileNamePattern>${log.path}/web-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <maxFileSize>100MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+            <!--日志文档保留天数-->
+            <maxHistory>15</maxHistory>
+        </rollingPolicy>
+        <!-- 此日志文档只记录ERROR级别的 -->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>ERROR</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <!--
+        <logger>用来设置某一个包或者具体的某一个类的日志打印级别、
+        以及指定<appender>。<logger>仅有一个name属性,
+        一个可选的level和一个可选的addtivity属性。
+        name:用来指定受此logger约束的某一个包或者具体的某一个类。
+        level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,
+              还有一个特俗值INHERITED或者同义词NULL,代表强制执行上级的级别。
+              如果未设置此属性,那么当前logger将会继承上级的级别。
+        addtivity:是否向上级logger传递打印信息。默认是true。
+        <logger name="org.springframework.web" level="info"/>
+        <logger name="org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor" level="INFO"/>
+    -->
+
+    <!--
+        使用mybatis的时候,sql语句是debug下才会打印,而这里我们只配置了info,所以想要查看sql语句的话,有以下两种操作:
+        第一种把<root level="info">改成<root level="DEBUG">这样就会打印sql,不过这样日志那边会出现很多其他消息
+        第二种就是单独给dao下目录配置debug模式,代码如下,这样配置sql语句会打印,其他还是正常info级别:
+        【logging.level.org.mybatis=debug logging.level.dao=debug】
+     -->
+
+    <!--
+        root节点是必选节点,用来指定最基础的日志输出级别,只有一个level属性
+        level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,
+        不能设置为INHERITED或者同义词NULL。默认是DEBUG
+        可以包含零个或多个元素,标识这个appender将会添加到这个logger。
+    -->
+
+    <!-- 4. 最终的策略 -->
+    <!-- 4.1 测试环境:打印控制台-->
+    <!--<springProfile name="test">-->
+        <!---->
+    <!--</springProfile>-->
+    <root level="info">
+        <appender-ref ref="CONSOLE" />
+        <appender-ref ref="DEBUG_FILE" />
+        <appender-ref ref="INFO_FILE" />
+        <appender-ref ref="WARN_FILE" />
+        <appender-ref ref="ERROR_FILE" />
+    </root>
+
+
+    <!--&lt;!&ndash; 4.2 生产环境:输出到文档&ndash;&gt;-->
+    <!--<springProfile name="prod">-->
+        <!--<root level="info">-->
+            <!--<appender-ref ref="ERROR_FILE" />-->
+            <!--<appender-ref ref="WARN_FILE" />-->
+        <!--</root>-->
+    <!--</springProfile>-->
+
+</configuration>

+ 103 - 0
src/main/resources/mapping/UserMapper.xml

@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="com.honter.mapper.UserMapper" >
+  <resultMap id="BaseResultMap" type="com.honter.model.User" >
+    <id column="user_id" property="userId" jdbcType="INTEGER" />
+    <result column="user_name" property="userName" jdbcType="VARCHAR" />
+    <result column="password" property="password" jdbcType="VARCHAR" />
+    <result column="phone" property="phone" jdbcType="VARCHAR" />
+  </resultMap>
+  <sql id="Base_Column_List" >
+    user_id, user_name, password, phone
+  </sql>
+  <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
+    select 
+    <include refid="Base_Column_List" />
+    from t_user
+    where user_id = #{userId,jdbcType=INTEGER}
+  </select>
+  <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer" >
+    delete from t_user
+    where user_id = #{userId,jdbcType=INTEGER}
+  </delete>
+  <insert id="insert" parameterType="com.honter.model.User" >
+    insert into t_user (user_id, user_name, password, 
+      phone)
+    values (#{userId,jdbcType=INTEGER}, #{userName,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, 
+      #{phone,jdbcType=VARCHAR})
+  </insert>
+  <!-- 插入数据之后返回主键 -->
+  <insert id="insertSelective" useGeneratedKeys="true" keyProperty="userId" parameterType="com.honter.model.User" >
+    insert into t_user
+    <trim prefix="(" suffix=")" suffixOverrides="," >
+      <if test="userId != null" >
+        user_id,
+      </if>
+      <if test="userName != null" >
+        user_name,
+      </if>
+      <if test="password != null" >
+        password,
+      </if>
+      <if test="phone != null" >
+        phone,
+      </if>
+    </trim>
+    <trim prefix="values (" suffix=")" suffixOverrides="," >
+      <if test="userId != null" >
+        #{userId,jdbcType=INTEGER},
+      </if>
+      <if test="userName != null" >
+        #{userName,jdbcType=VARCHAR},
+      </if>
+      <if test="password != null" >
+        #{password,jdbcType=VARCHAR},
+      </if>
+      <if test="phone != null" >
+        #{phone,jdbcType=VARCHAR},
+      </if>
+    </trim>
+  </insert>
+  <update id="updateByPrimaryKeySelective" parameterType="com.honter.model.User" >
+    update t_user
+    <set >
+      <if test="userName != null" >
+        user_name = #{userName,jdbcType=VARCHAR},
+      </if>
+      <if test="password != null" >
+        password = #{password,jdbcType=VARCHAR},
+      </if>
+      <if test="phone != null" >
+        phone = #{phone,jdbcType=VARCHAR},
+      </if>
+    </set>
+    where user_id = #{userId,jdbcType=INTEGER}
+  </update>
+  <update id="updateByPrimaryKey" parameterType="com.honter.model.User" >
+    update t_user
+    set user_name = #{userName,jdbcType=VARCHAR},
+      password = #{password,jdbcType=VARCHAR},
+      phone = #{phone,jdbcType=VARCHAR}
+    where user_id = #{userId,jdbcType=INTEGER}
+  </update>
+  <select id="getUsersByuserId" resultType="com.honter.model.User">
+    SELECT
+    user_id as userId, user_name as userName, password as password, phone as phone
+    FROM
+    t_user
+    WHERE 1=1
+    <if test="userId != null  and userId != ''" >
+      AND user_id = #{userId,jdbcType=INTEGER}
+    </if>
+    <if test="userName != null  and userName != ''" >
+      AND user_name = #{userName,jdbcType=VARCHAR}
+    </if>
+  </select>
+  <select id="getUsersByUserName" resultType="com.honter.model.User">
+    SELECT
+    user_id as userId, user_name as userName, password as password, phone as phone
+    FROM
+    t_user
+    WHERE  user_name = #{userName,jdbcType=VARCHAR}
+  </select>
+</mapper>

+ 77 - 0
src/test/java/com/honter/SpringbootApplicationTests.java

@@ -0,0 +1,77 @@
+package com.honter;
+
+import com.honter.mail.MailSend;
+import com.honter.mapper.UserMapper;
+import com.honter.model.User;
+import com.honter.service.UserService;
+import com.honter.serviceImpl.UserServiceImpl;
+import com.honter.util.JwtToken;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class SpringbootApplicationTests {
+//	@Autowired
+//	public  JwtToken jwtToken;
+	@Autowired
+	private UserMapper userMapper;
+	@Autowired
+	private UserService userService;
+	@Test
+	public void contextLoads() {
+		User user = userService.queryUserByUserId(1);
+		System.out.println(user.getPhone());
+	}
+	@Test
+	public void insertUser(){
+		User user=new User();
+		user.setPassword("fsssss");
+		user.setPhone("222222");
+		System.out.println(userService.insertUser(user));
+	}
+	@Test
+	public void updateUser(){
+		User user=new User();
+		user.setPhone("88888");
+		user.setUserId(12);
+		userService.updateUserByUserId(user);
+	}
+	@Test
+	public void getUsers() {
+		List<User> user = userService.getUsersByuserId(1,null);
+		System.out.println(user.size());
+	}
+	@Test
+	public void getUser() {
+		User user = userService.getUsersByUserName("恶委屈人情味");
+		System.out.println(user);
+	}
+	@Test
+	public void getJwtToken() throws Exception {
+		Map<String, Object> map = new HashMap<String, Object>();
+		map.put("province", "898765");
+		map.put("city", "898765");
+		map.put("appkey", "HMu1H/cmyKDOiHv41Y9lLROuOlOo+PPG8F4/RotRmNc=");
+		map.put("timestamp", new Date().getTime());
+		String token= JwtToken.createToken(map);
+		System.out.println(token);
+		Map<String, Object> claim=JwtToken.verifyToken("wwww");
+		System.out.println(claim);
+	}
+
+	@Test
+	public void mailsend() throws Exception {
+		MailSend.sendMail("吸引力", "li.hongtaolove@163.com", "spring boot 邮件测试");
+	}
+
+}