From 3de069db9b8abbf6593be8ba7c9916f8525db1d4 Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Tue, 20 Aug 2019 15:07:08 +0800 Subject: [PATCH 001/204] feat:springboot schedule task --- springboot-schedule-tast/.gitignore | 32 ++++ springboot-schedule-tast/build.gradle | 20 ++ .../gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 55190 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 + springboot-schedule-tast/gradlew | 172 ++++++++++++++++++ springboot-schedule-tast/gradlew.bat | 84 +++++++++ springboot-schedule-tast/settings.gradle | 1 + .../com/example/demo/DemoApplication.java | 14 ++ .../demo/scheduletask/ScheduledTasks.java | 58 ++++++ .../scheduletask/config/SchedulerConfig.java | 22 +++ .../src/main/resources/application.properties | 1 + .../main/resources/templates/hello/hello.html | 16 ++ .../example/demo/DemoApplicationTests.java | 16 ++ 13 files changed, 442 insertions(+) create mode 100644 springboot-schedule-tast/.gitignore create mode 100644 springboot-schedule-tast/build.gradle create mode 100644 springboot-schedule-tast/gradle/wrapper/gradle-wrapper.jar create mode 100644 springboot-schedule-tast/gradle/wrapper/gradle-wrapper.properties create mode 100755 springboot-schedule-tast/gradlew create mode 100644 springboot-schedule-tast/gradlew.bat create mode 100644 springboot-schedule-tast/settings.gradle create mode 100644 springboot-schedule-tast/src/main/java/com/example/demo/DemoApplication.java create mode 100644 springboot-schedule-tast/src/main/java/com/example/demo/scheduletask/ScheduledTasks.java create mode 100644 springboot-schedule-tast/src/main/java/com/example/demo/scheduletask/config/SchedulerConfig.java create mode 100644 springboot-schedule-tast/src/main/resources/application.properties create mode 100644 springboot-schedule-tast/src/main/resources/templates/hello/hello.html create mode 100644 springboot-schedule-tast/src/test/java/com/example/demo/DemoApplicationTests.java diff --git a/springboot-schedule-tast/.gitignore b/springboot-schedule-tast/.gitignore new file mode 100644 index 0000000..6c01878 --- /dev/null +++ b/springboot-schedule-tast/.gitignore @@ -0,0 +1,32 @@ +HELP.md +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/** +!**/src/test/** + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr +out/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ diff --git a/springboot-schedule-tast/build.gradle b/springboot-schedule-tast/build.gradle new file mode 100644 index 0000000..99b5f81 --- /dev/null +++ b/springboot-schedule-tast/build.gradle @@ -0,0 +1,20 @@ +plugins { + id 'org.springframework.boot' version '2.1.6.RELEASE' + id 'java' +} + +apply plugin: 'io.spring.dependency-management' + +group = 'com.example' +version = '0.0.1-SNAPSHOT' +sourceCompatibility = '1.8' + +repositories { + mavenCentral() +} + +dependencies { + implementation 'org.springframework.boot:spring-boot-starter-web' + compile 'org.springframework.boot:spring-boot-starter-thymeleaf' + testImplementation 'org.springframework.boot:spring-boot-starter-test' +} diff --git a/springboot-schedule-tast/gradle/wrapper/gradle-wrapper.jar b/springboot-schedule-tast/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..87b738cbd051603d91cc39de6cb000dd98fe6b02 GIT binary patch literal 55190 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 z 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 \(.*\)$') + if expr "$link" : '/.*' >/dev/null; then + PRG="$link" + else + PRG=$(dirname "$PRG")"/$link" + fi +done +SAVED="$(pwd)" +cd "$(dirname \"$PRG\")/" >/dev/null +APP_HOME="$(pwd -P)" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=$(basename "$0") + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn() { + echo "$*" +} + +die() { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$(uname)" in +CYGWIN*) + cygwin=true + ;; +Darwin*) + darwin=true + ;; +MINGW*) + msys=true + ;; +NONSTOP*) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +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 + if [ ! -x "$JAVACMD" ]; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ]; then + MAX_FD_LIMIT=$(ulimit -H -n) + if [ $? -eq 0 ]; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ]; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ]; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + APP_HOME=$(cygpath --path --mixed "$APP_HOME") + CLASSPATH=$(cygpath --path --mixed "$CLASSPATH") + JAVACMD=$(cygpath --unix "$JAVACMD") + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=$(find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null) + SEP="" + for dir in $ROOTDIRSRAW; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ]; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@"; do + CHECK=$(echo "$arg" | egrep -c "$OURCYGPATTERN" -) + CHECK2=$(echo "$arg" | egrep -c "^-") ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ]; then ### Added a condition + eval $(echo args$i)=$(cygpath --path --ignore --mixed "$arg") + else + eval $(echo args$i)="\"$arg\"" + fi + i=$((i + 1)) + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save() { + for i; do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/"; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/springboot-schedule-tast/gradlew.bat b/springboot-schedule-tast/gradlew.bat new file mode 100644 index 0000000..6d57edc --- /dev/null +++ b/springboot-schedule-tast/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/springboot-schedule-tast/settings.gradle b/springboot-schedule-tast/settings.gradle new file mode 100644 index 0000000..0a383dd --- /dev/null +++ b/springboot-schedule-tast/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'demo' diff --git a/springboot-schedule-tast/src/main/java/com/example/demo/DemoApplication.java b/springboot-schedule-tast/src/main/java/com/example/demo/DemoApplication.java new file mode 100644 index 0000000..7cfd6f9 --- /dev/null +++ b/springboot-schedule-tast/src/main/java/com/example/demo/DemoApplication.java @@ -0,0 +1,14 @@ +package com.example.demo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.scheduling.annotation.EnableScheduling; + +@SpringBootApplication +@EnableScheduling +public class DemoApplication { + + public static void main(String[] args) { + SpringApplication.run(DemoApplication.class, args); + } +} diff --git a/springboot-schedule-tast/src/main/java/com/example/demo/scheduletask/ScheduledTasks.java b/springboot-schedule-tast/src/main/java/com/example/demo/scheduletask/ScheduledTasks.java new file mode 100644 index 0000000..0e71e36 --- /dev/null +++ b/springboot-schedule-tast/src/main/java/com/example/demo/scheduletask/ScheduledTasks.java @@ -0,0 +1,58 @@ +package com.example.demo.scheduletask; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.concurrent.TimeUnit; + +/** + * @author shuang.kou + */ +@Component +public class ScheduledTasks { + private static final Logger log = LoggerFactory.getLogger(ScheduledTasks.class); + private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss"); + + /** + * fixedRate:固定速率执行。每5秒执行一次。 + */ + @Scheduled(fixedRate = 5000) + public void reportCurrentTimeWithFixedRate() { + log.info("Current Thread : {}", Thread.currentThread().getName()); + log.info("Current Thread : {}", Thread.currentThread().getName()); + log.info("Fixed Rate Task : The time is now {}", dateFormat.format(new Date())); + } + + /** + * fixedDelay:固定延迟执行。距离上一次调用成功后2秒才执。 + */ + @Scheduled(fixedDelay = 2000) + public void reportCurrentTimeWithFixedDelay() { + try { + TimeUnit.SECONDS.sleep(3); + log.info("Fixed Delay Task : The time is now {}", dateFormat.format(new Date())); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + /** + * initialDelay:初始延迟。任务的第一次执行将延迟5秒,然后将以5秒的固定间隔执行。 + */ + @Scheduled(initialDelay = 5000, fixedRate = 5000) + public void reportCurrentTimeWithInitialDelay() { + log.info("Fixed Rate Task with Initial Delay : The time is now {}", dateFormat.format(new Date())); + } + + /** + * + */ + @Scheduled(cron = "1-2 * * * * ? ") + public void reportCurrentTimeWithCronExpression() { + log.info("Cron Expression: The time is now {}", dateFormat.format(new Date())); + } +} diff --git a/springboot-schedule-tast/src/main/java/com/example/demo/scheduletask/config/SchedulerConfig.java b/springboot-schedule-tast/src/main/java/com/example/demo/scheduletask/config/SchedulerConfig.java new file mode 100644 index 0000000..e26b9e5 --- /dev/null +++ b/springboot-schedule-tast/src/main/java/com/example/demo/scheduletask/config/SchedulerConfig.java @@ -0,0 +1,22 @@ +package com.example.demo.scheduletask.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.SchedulingConfigurer; +import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; +import org.springframework.scheduling.config.ScheduledTaskRegistrar; + +@Configuration +public class SchedulerConfig implements SchedulingConfigurer { + private final int POOL_SIZE = 10; + + @Override + public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) { + ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler(); + + threadPoolTaskScheduler.setPoolSize(POOL_SIZE); + threadPoolTaskScheduler.setThreadNamePrefix("my-scheduled-task-pool-"); + threadPoolTaskScheduler.initialize(); + + scheduledTaskRegistrar.setTaskScheduler(threadPoolTaskScheduler); + } +} diff --git a/springboot-schedule-tast/src/main/resources/application.properties b/springboot-schedule-tast/src/main/resources/application.properties new file mode 100644 index 0000000..e15d9e6 --- /dev/null +++ b/springboot-schedule-tast/src/main/resources/application.properties @@ -0,0 +1 @@ +server.port=8999 diff --git a/springboot-schedule-tast/src/main/resources/templates/hello/hello.html b/springboot-schedule-tast/src/main/resources/templates/hello/hello.html new file mode 100644 index 0000000..a80c888 --- /dev/null +++ b/springboot-schedule-tast/src/main/resources/templates/hello/hello.html @@ -0,0 +1,16 @@ + + + + + + + + + Getting Started: Serving Web Content + + + +

+

+ + diff --git a/springboot-schedule-tast/src/test/java/com/example/demo/DemoApplicationTests.java b/springboot-schedule-tast/src/test/java/com/example/demo/DemoApplicationTests.java new file mode 100644 index 0000000..480d1ca --- /dev/null +++ b/springboot-schedule-tast/src/test/java/com/example/demo/DemoApplicationTests.java @@ -0,0 +1,16 @@ +package com.example.demo; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class DemoApplicationTests { + + @Test + public void contextLoads() { + } + +} From a99d001ff80545c87e12d2be86fceac7f279383e Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Tue, 20 Aug 2019 15:41:58 +0800 Subject: [PATCH 002/204] =?UTF-8?q?Create=205=E5=88=86=E9=92=9F=E6=90=9E?= =?UTF-8?q?=E6=87=82=E5=A6=82=E4=BD=95=E5=9C=A8Spring=20Boot=E4=B8=ADSched?= =?UTF-8?q?ule=20Tasks=20.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...Spring Boot\344\270\255Schedule Tasks .md" | 126 ++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 "md/5\345\210\206\351\222\237\346\220\236\346\207\202\345\246\202\344\275\225\345\234\250Spring Boot\344\270\255Schedule Tasks .md" diff --git "a/md/5\345\210\206\351\222\237\346\220\236\346\207\202\345\246\202\344\275\225\345\234\250Spring Boot\344\270\255Schedule Tasks .md" "b/md/5\345\210\206\351\222\237\346\220\236\346\207\202\345\246\202\344\275\225\345\234\250Spring Boot\344\270\255Schedule Tasks .md" new file mode 100644 index 0000000..549fe5c --- /dev/null +++ "b/md/5\345\210\206\351\222\237\346\220\236\346\207\202\345\246\202\344\275\225\345\234\250Spring Boot\344\270\255Schedule Tasks .md" @@ -0,0 +1,126 @@ +很多时候我们都需要为系统建立一个定时任务来帮我们做一些事情,SpringBoot 已经帮我们实现好了一个,我们只需要直接使用即可,当然你也可以不用 SpringBoot 自带的定时任务,整合 Quartz 很多时候也是一个不错的选择。 + +本文不涉及 SpringBoot 整合 Quartz 的内容,只演示了如何使用 SpringBoot 自带的实现定时任务的方式。 + +## Spring Schedule 实现定时任务 + +我们只需要 SpringBoot 项目最基本的依赖即可,所以这里就不贴配置文件了。 + +### 1. 创建一个 scheduled task + +我们使用 `@Scheduled` 注解就能很方便地创建一个定时任务,下面的代码中涵盖了 `@Scheduled `的常见用法,包括:固定速率执行、固定延迟执行、初始延迟执行、使用 Cron 表达式执行定时任务。 + +> Cron 表达式: 主要用于定时作业(定时任务)系统定义执行时间或执行频率的表达式,非常厉害,你可以通过 Cron 表达式进行设置定时任务每天或者每个月什么时候执行等等操作。 +> +> 推荐一个在线Cron表达式生成器:[http://cron.qqe2.com/](http://cron.qqe2.com/) + +```java +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.concurrent.TimeUnit; + +/** + * @author shuang.kou + */ +@Component +public class ScheduledTasks { + private static final Logger log = LoggerFactory.getLogger(ScheduledTasks.class); + private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss"); + + /** + * fixedRate:固定速率执行。每5秒执行一次。 + */ + @Scheduled(fixedRate = 5000) + public void reportCurrentTimeWithFixedRate() { + log.info("Current Thread : {}", Thread.currentThread().getName()); + log.info("Fixed Rate Task : The time is now {}", dateFormat.format(new Date())); + } + + /** + * fixedDelay:固定延迟执行。距离上一次调用成功后2秒才执。 + */ + @Scheduled(fixedDelay = 2000) + public void reportCurrentTimeWithFixedDelay() { + try { + TimeUnit.SECONDS.sleep(3); + log.info("Fixed Delay Task : The time is now {}", dateFormat.format(new Date())); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + /** + * initialDelay:初始延迟。任务的第一次执行将延迟5秒,然后将以5秒的固定间隔执行。 + */ + @Scheduled(initialDelay = 5000, fixedRate = 5000) + public void reportCurrentTimeWithInitialDelay() { + log.info("Fixed Rate Task with Initial Delay : The time is now {}", dateFormat.format(new Date())); + } + + /** + * cron:使用Cron表达式。 每分钟的1,2秒运行 + */ + @Scheduled(cron = "1-2 * * * * ? ") + public void reportCurrentTimeWithCronExpression() { + log.info("Cron Expression: The time is now {}", dateFormat.format(new Date())); + } +} + +``` + +###  2. 启动类上加上`@EnableScheduling`注解 + +在 SpringBoot 中我们只需要在启动类上加上`@EnableScheduling`便可以启动定时任务了。 + +```java +@SpringBootApplication +@EnableScheduling +public class DemoApplication { + + public static void main(String[] args) { + SpringApplication.run(DemoApplication.class, args); + } +} +``` + +### 3. 自定义线程池执行 scheduled task + +默认情况下,`@Scheduled`任务都在Spring创建的大小为1的默认线程池中执行,你可以通过在加了`@Scheduled`注解的方法里加上下面这段代码来验证。 + +```java +logger.info("Current Thread : {}", Thread.currentThread().getName()); +``` + +你会发现加上上面这段代码的定时任务,每次运行都会输出: + +``` +Current Thread : scheduling-1 +``` + +如果我们需要自定义线程池执行话只需要新加一个实现`SchedulingConfigurer`接口的 `configureTasks` 的类即可,这个类需要加上 `@Configuration` 注解。 + +```java +@Configuration +public class SchedulerConfig implements SchedulingConfigurer { + private final int POOL_SIZE = 10; + + @Override + public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) { + ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler(); + + threadPoolTaskScheduler.setPoolSize(POOL_SIZE); + threadPoolTaskScheduler.setThreadNamePrefix("my-scheduled-task-pool-"); + threadPoolTaskScheduler.initialize(); + + scheduledTaskRegistrar.setTaskScheduler(threadPoolTaskScheduler); + } +} +``` + +通过上面的验证的方式输出当前线程的名字会改变。 + From 2e039f1b8052673aa9406937cfe5947b4dd925e4 Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Tue, 20 Aug 2019 15:48:47 +0800 Subject: [PATCH 003/204] =?UTF-8?q?Delete=205=E5=88=86=E9=92=9F=E6=90=9E?= =?UTF-8?q?=E6=87=82=E5=A6=82=E4=BD=95=E5=9C=A8Spring=20Boot=E4=B8=ADSched?= =?UTF-8?q?ule=20Tasks=20.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...Spring Boot\344\270\255Schedule Tasks .md" | 126 ------------------ 1 file changed, 126 deletions(-) delete mode 100644 "md/5\345\210\206\351\222\237\346\220\236\346\207\202\345\246\202\344\275\225\345\234\250Spring Boot\344\270\255Schedule Tasks .md" diff --git "a/md/5\345\210\206\351\222\237\346\220\236\346\207\202\345\246\202\344\275\225\345\234\250Spring Boot\344\270\255Schedule Tasks .md" "b/md/5\345\210\206\351\222\237\346\220\236\346\207\202\345\246\202\344\275\225\345\234\250Spring Boot\344\270\255Schedule Tasks .md" deleted file mode 100644 index 549fe5c..0000000 --- "a/md/5\345\210\206\351\222\237\346\220\236\346\207\202\345\246\202\344\275\225\345\234\250Spring Boot\344\270\255Schedule Tasks .md" +++ /dev/null @@ -1,126 +0,0 @@ -很多时候我们都需要为系统建立一个定时任务来帮我们做一些事情,SpringBoot 已经帮我们实现好了一个,我们只需要直接使用即可,当然你也可以不用 SpringBoot 自带的定时任务,整合 Quartz 很多时候也是一个不错的选择。 - -本文不涉及 SpringBoot 整合 Quartz 的内容,只演示了如何使用 SpringBoot 自带的实现定时任务的方式。 - -## Spring Schedule 实现定时任务 - -我们只需要 SpringBoot 项目最基本的依赖即可,所以这里就不贴配置文件了。 - -### 1. 创建一个 scheduled task - -我们使用 `@Scheduled` 注解就能很方便地创建一个定时任务,下面的代码中涵盖了 `@Scheduled `的常见用法,包括:固定速率执行、固定延迟执行、初始延迟执行、使用 Cron 表达式执行定时任务。 - -> Cron 表达式: 主要用于定时作业(定时任务)系统定义执行时间或执行频率的表达式,非常厉害,你可以通过 Cron 表达式进行设置定时任务每天或者每个月什么时候执行等等操作。 -> -> 推荐一个在线Cron表达式生成器:[http://cron.qqe2.com/](http://cron.qqe2.com/) - -```java -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Component; - -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.concurrent.TimeUnit; - -/** - * @author shuang.kou - */ -@Component -public class ScheduledTasks { - private static final Logger log = LoggerFactory.getLogger(ScheduledTasks.class); - private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss"); - - /** - * fixedRate:固定速率执行。每5秒执行一次。 - */ - @Scheduled(fixedRate = 5000) - public void reportCurrentTimeWithFixedRate() { - log.info("Current Thread : {}", Thread.currentThread().getName()); - log.info("Fixed Rate Task : The time is now {}", dateFormat.format(new Date())); - } - - /** - * fixedDelay:固定延迟执行。距离上一次调用成功后2秒才执。 - */ - @Scheduled(fixedDelay = 2000) - public void reportCurrentTimeWithFixedDelay() { - try { - TimeUnit.SECONDS.sleep(3); - log.info("Fixed Delay Task : The time is now {}", dateFormat.format(new Date())); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - /** - * initialDelay:初始延迟。任务的第一次执行将延迟5秒,然后将以5秒的固定间隔执行。 - */ - @Scheduled(initialDelay = 5000, fixedRate = 5000) - public void reportCurrentTimeWithInitialDelay() { - log.info("Fixed Rate Task with Initial Delay : The time is now {}", dateFormat.format(new Date())); - } - - /** - * cron:使用Cron表达式。 每分钟的1,2秒运行 - */ - @Scheduled(cron = "1-2 * * * * ? ") - public void reportCurrentTimeWithCronExpression() { - log.info("Cron Expression: The time is now {}", dateFormat.format(new Date())); - } -} - -``` - -###  2. 启动类上加上`@EnableScheduling`注解 - -在 SpringBoot 中我们只需要在启动类上加上`@EnableScheduling`便可以启动定时任务了。 - -```java -@SpringBootApplication -@EnableScheduling -public class DemoApplication { - - public static void main(String[] args) { - SpringApplication.run(DemoApplication.class, args); - } -} -``` - -### 3. 自定义线程池执行 scheduled task - -默认情况下,`@Scheduled`任务都在Spring创建的大小为1的默认线程池中执行,你可以通过在加了`@Scheduled`注解的方法里加上下面这段代码来验证。 - -```java -logger.info("Current Thread : {}", Thread.currentThread().getName()); -``` - -你会发现加上上面这段代码的定时任务,每次运行都会输出: - -``` -Current Thread : scheduling-1 -``` - -如果我们需要自定义线程池执行话只需要新加一个实现`SchedulingConfigurer`接口的 `configureTasks` 的类即可,这个类需要加上 `@Configuration` 注解。 - -```java -@Configuration -public class SchedulerConfig implements SchedulingConfigurer { - private final int POOL_SIZE = 10; - - @Override - public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) { - ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler(); - - threadPoolTaskScheduler.setPoolSize(POOL_SIZE); - threadPoolTaskScheduler.setThreadNamePrefix("my-scheduled-task-pool-"); - threadPoolTaskScheduler.initialize(); - - scheduledTaskRegistrar.setTaskScheduler(threadPoolTaskScheduler); - } -} -``` - -通过上面的验证的方式输出当前线程的名字会改变。 - From eba4a738ecd03bac86c5821fe9bc07a135431b2a Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Tue, 20 Aug 2019 15:48:49 +0800 Subject: [PATCH 004/204] Create SpringBoot-ScheduleTasks .md --- md/SpringBoot-ScheduleTasks .md | 126 ++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 md/SpringBoot-ScheduleTasks .md diff --git a/md/SpringBoot-ScheduleTasks .md b/md/SpringBoot-ScheduleTasks .md new file mode 100644 index 0000000..549fe5c --- /dev/null +++ b/md/SpringBoot-ScheduleTasks .md @@ -0,0 +1,126 @@ +很多时候我们都需要为系统建立一个定时任务来帮我们做一些事情,SpringBoot 已经帮我们实现好了一个,我们只需要直接使用即可,当然你也可以不用 SpringBoot 自带的定时任务,整合 Quartz 很多时候也是一个不错的选择。 + +本文不涉及 SpringBoot 整合 Quartz 的内容,只演示了如何使用 SpringBoot 自带的实现定时任务的方式。 + +## Spring Schedule 实现定时任务 + +我们只需要 SpringBoot 项目最基本的依赖即可,所以这里就不贴配置文件了。 + +### 1. 创建一个 scheduled task + +我们使用 `@Scheduled` 注解就能很方便地创建一个定时任务,下面的代码中涵盖了 `@Scheduled `的常见用法,包括:固定速率执行、固定延迟执行、初始延迟执行、使用 Cron 表达式执行定时任务。 + +> Cron 表达式: 主要用于定时作业(定时任务)系统定义执行时间或执行频率的表达式,非常厉害,你可以通过 Cron 表达式进行设置定时任务每天或者每个月什么时候执行等等操作。 +> +> 推荐一个在线Cron表达式生成器:[http://cron.qqe2.com/](http://cron.qqe2.com/) + +```java +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.concurrent.TimeUnit; + +/** + * @author shuang.kou + */ +@Component +public class ScheduledTasks { + private static final Logger log = LoggerFactory.getLogger(ScheduledTasks.class); + private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss"); + + /** + * fixedRate:固定速率执行。每5秒执行一次。 + */ + @Scheduled(fixedRate = 5000) + public void reportCurrentTimeWithFixedRate() { + log.info("Current Thread : {}", Thread.currentThread().getName()); + log.info("Fixed Rate Task : The time is now {}", dateFormat.format(new Date())); + } + + /** + * fixedDelay:固定延迟执行。距离上一次调用成功后2秒才执。 + */ + @Scheduled(fixedDelay = 2000) + public void reportCurrentTimeWithFixedDelay() { + try { + TimeUnit.SECONDS.sleep(3); + log.info("Fixed Delay Task : The time is now {}", dateFormat.format(new Date())); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + /** + * initialDelay:初始延迟。任务的第一次执行将延迟5秒,然后将以5秒的固定间隔执行。 + */ + @Scheduled(initialDelay = 5000, fixedRate = 5000) + public void reportCurrentTimeWithInitialDelay() { + log.info("Fixed Rate Task with Initial Delay : The time is now {}", dateFormat.format(new Date())); + } + + /** + * cron:使用Cron表达式。 每分钟的1,2秒运行 + */ + @Scheduled(cron = "1-2 * * * * ? ") + public void reportCurrentTimeWithCronExpression() { + log.info("Cron Expression: The time is now {}", dateFormat.format(new Date())); + } +} + +``` + +###  2. 启动类上加上`@EnableScheduling`注解 + +在 SpringBoot 中我们只需要在启动类上加上`@EnableScheduling`便可以启动定时任务了。 + +```java +@SpringBootApplication +@EnableScheduling +public class DemoApplication { + + public static void main(String[] args) { + SpringApplication.run(DemoApplication.class, args); + } +} +``` + +### 3. 自定义线程池执行 scheduled task + +默认情况下,`@Scheduled`任务都在Spring创建的大小为1的默认线程池中执行,你可以通过在加了`@Scheduled`注解的方法里加上下面这段代码来验证。 + +```java +logger.info("Current Thread : {}", Thread.currentThread().getName()); +``` + +你会发现加上上面这段代码的定时任务,每次运行都会输出: + +``` +Current Thread : scheduling-1 +``` + +如果我们需要自定义线程池执行话只需要新加一个实现`SchedulingConfigurer`接口的 `configureTasks` 的类即可,这个类需要加上 `@Configuration` 注解。 + +```java +@Configuration +public class SchedulerConfig implements SchedulingConfigurer { + private final int POOL_SIZE = 10; + + @Override + public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) { + ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler(); + + threadPoolTaskScheduler.setPoolSize(POOL_SIZE); + threadPoolTaskScheduler.setThreadNamePrefix("my-scheduled-task-pool-"); + threadPoolTaskScheduler.initialize(); + + scheduledTaskRegistrar.setTaskScheduler(threadPoolTaskScheduler); + } +} +``` + +通过上面的验证的方式输出当前线程的名字会改变。 + From ffaee0257a9cebd42050857a6173f0980942005e Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Tue, 20 Aug 2019 15:48:51 +0800 Subject: [PATCH 005/204] Update README.md --- README.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a7a9d54..fd87004 100644 --- a/README.md +++ b/README.md @@ -2,17 +2,21 @@ SpringBoot和其他常用技术的整合,可能是你遇到的讲解最详细的学习案例,力争新手也能看懂并且能够在看完之后独立实践。基于最新的 SpringBoot2.0+,是你学习SpringBoot 的最佳指南。 +## springboot-schedule-tast(SpringBoot 定时任务) + +[5分钟搞懂如何在Spring Boot中Schedule Tasks](./md/SpringBoot-ScheduleTasks .md) + ## springboot-mybatis(SpringBoot+Mybatis 的最佳实践) -[优雅整合 SpringBoot+Mybatis,可能是你见过把 SpringBoot 整合 Mybatis 写的最详细的一篇文章](https://github.com/Snailclimb/springboot-integration-examples/blob/master/md/springboot-mybatis.md) +[优雅整合 SpringBoot+Mybatis,可能是你见过把 SpringBoot 整合 Mybatis 写的最详细的一篇文章](./md/springboot-mybatis.md) -[新手也能看懂,基于SpirngBoot2.0+ 的 SpringBoot+Mybatis 多数据源配置](https://github.com/Snailclimb/springboot-integration-examples/blob/master/md/springboot-mybatis-mutipledatasource.md) +[新手也能看懂,基于SpirngBoot2.0+ 的 SpringBoot+Mybatis 多数据源配置](./md/springboot-mybatis-mutipledatasource.md) ## springboot-oss(SpringBoot 整合 阿里云OSS 存储服务) -[SpringBoot 整合 阿里云OSS 存储服务,快来免费搭建一个自己的图床](https://github.com/Snailclimb/springboot-integration-examples/blob/master/md/springboot-oss.md) +[SpringBoot 整合 阿里云OSS 存储服务,快来免费搭建一个自己的图床](./md/springboot-oss.md) ## springboot-dubbo(使用SpringBoot+Dubbo 搭建一个分布式服务) -[超详细,新手都能看懂 !使用SpringBoot+Dubbo 搭建一个分布式服务](https://github.com/Snailclimb/springboot-integration-examples/blob/master/md/springboot-dubbo.md) +[超详细,新手都能看懂 !使用SpringBoot+Dubbo 搭建一个分布式服务](./md/springboot-dubbo.md) From 25c1f9eb815f095efc1637bc6be48f638e4bc635 Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Tue, 20 Aug 2019 15:50:08 +0800 Subject: [PATCH 006/204] Delete SpringBoot-ScheduleTasks .md --- md/SpringBoot-ScheduleTasks .md | 126 -------------------------------- 1 file changed, 126 deletions(-) delete mode 100644 md/SpringBoot-ScheduleTasks .md diff --git a/md/SpringBoot-ScheduleTasks .md b/md/SpringBoot-ScheduleTasks .md deleted file mode 100644 index 549fe5c..0000000 --- a/md/SpringBoot-ScheduleTasks .md +++ /dev/null @@ -1,126 +0,0 @@ -很多时候我们都需要为系统建立一个定时任务来帮我们做一些事情,SpringBoot 已经帮我们实现好了一个,我们只需要直接使用即可,当然你也可以不用 SpringBoot 自带的定时任务,整合 Quartz 很多时候也是一个不错的选择。 - -本文不涉及 SpringBoot 整合 Quartz 的内容,只演示了如何使用 SpringBoot 自带的实现定时任务的方式。 - -## Spring Schedule 实现定时任务 - -我们只需要 SpringBoot 项目最基本的依赖即可,所以这里就不贴配置文件了。 - -### 1. 创建一个 scheduled task - -我们使用 `@Scheduled` 注解就能很方便地创建一个定时任务,下面的代码中涵盖了 `@Scheduled `的常见用法,包括:固定速率执行、固定延迟执行、初始延迟执行、使用 Cron 表达式执行定时任务。 - -> Cron 表达式: 主要用于定时作业(定时任务)系统定义执行时间或执行频率的表达式,非常厉害,你可以通过 Cron 表达式进行设置定时任务每天或者每个月什么时候执行等等操作。 -> -> 推荐一个在线Cron表达式生成器:[http://cron.qqe2.com/](http://cron.qqe2.com/) - -```java -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Component; - -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.concurrent.TimeUnit; - -/** - * @author shuang.kou - */ -@Component -public class ScheduledTasks { - private static final Logger log = LoggerFactory.getLogger(ScheduledTasks.class); - private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss"); - - /** - * fixedRate:固定速率执行。每5秒执行一次。 - */ - @Scheduled(fixedRate = 5000) - public void reportCurrentTimeWithFixedRate() { - log.info("Current Thread : {}", Thread.currentThread().getName()); - log.info("Fixed Rate Task : The time is now {}", dateFormat.format(new Date())); - } - - /** - * fixedDelay:固定延迟执行。距离上一次调用成功后2秒才执。 - */ - @Scheduled(fixedDelay = 2000) - public void reportCurrentTimeWithFixedDelay() { - try { - TimeUnit.SECONDS.sleep(3); - log.info("Fixed Delay Task : The time is now {}", dateFormat.format(new Date())); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - /** - * initialDelay:初始延迟。任务的第一次执行将延迟5秒,然后将以5秒的固定间隔执行。 - */ - @Scheduled(initialDelay = 5000, fixedRate = 5000) - public void reportCurrentTimeWithInitialDelay() { - log.info("Fixed Rate Task with Initial Delay : The time is now {}", dateFormat.format(new Date())); - } - - /** - * cron:使用Cron表达式。 每分钟的1,2秒运行 - */ - @Scheduled(cron = "1-2 * * * * ? ") - public void reportCurrentTimeWithCronExpression() { - log.info("Cron Expression: The time is now {}", dateFormat.format(new Date())); - } -} - -``` - -###  2. 启动类上加上`@EnableScheduling`注解 - -在 SpringBoot 中我们只需要在启动类上加上`@EnableScheduling`便可以启动定时任务了。 - -```java -@SpringBootApplication -@EnableScheduling -public class DemoApplication { - - public static void main(String[] args) { - SpringApplication.run(DemoApplication.class, args); - } -} -``` - -### 3. 自定义线程池执行 scheduled task - -默认情况下,`@Scheduled`任务都在Spring创建的大小为1的默认线程池中执行,你可以通过在加了`@Scheduled`注解的方法里加上下面这段代码来验证。 - -```java -logger.info("Current Thread : {}", Thread.currentThread().getName()); -``` - -你会发现加上上面这段代码的定时任务,每次运行都会输出: - -``` -Current Thread : scheduling-1 -``` - -如果我们需要自定义线程池执行话只需要新加一个实现`SchedulingConfigurer`接口的 `configureTasks` 的类即可,这个类需要加上 `@Configuration` 注解。 - -```java -@Configuration -public class SchedulerConfig implements SchedulingConfigurer { - private final int POOL_SIZE = 10; - - @Override - public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) { - ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler(); - - threadPoolTaskScheduler.setPoolSize(POOL_SIZE); - threadPoolTaskScheduler.setThreadNamePrefix("my-scheduled-task-pool-"); - threadPoolTaskScheduler.initialize(); - - scheduledTaskRegistrar.setTaskScheduler(threadPoolTaskScheduler); - } -} -``` - -通过上面的验证的方式输出当前线程的名字会改变。 - From e3d314053bac97a20f9ab5912046e8784286ad38 Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Tue, 20 Aug 2019 15:50:11 +0800 Subject: [PATCH 007/204] Create SpringBoot-ScheduleTasks.md --- md/SpringBoot-ScheduleTasks.md | 126 +++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 md/SpringBoot-ScheduleTasks.md diff --git a/md/SpringBoot-ScheduleTasks.md b/md/SpringBoot-ScheduleTasks.md new file mode 100644 index 0000000..549fe5c --- /dev/null +++ b/md/SpringBoot-ScheduleTasks.md @@ -0,0 +1,126 @@ +很多时候我们都需要为系统建立一个定时任务来帮我们做一些事情,SpringBoot 已经帮我们实现好了一个,我们只需要直接使用即可,当然你也可以不用 SpringBoot 自带的定时任务,整合 Quartz 很多时候也是一个不错的选择。 + +本文不涉及 SpringBoot 整合 Quartz 的内容,只演示了如何使用 SpringBoot 自带的实现定时任务的方式。 + +## Spring Schedule 实现定时任务 + +我们只需要 SpringBoot 项目最基本的依赖即可,所以这里就不贴配置文件了。 + +### 1. 创建一个 scheduled task + +我们使用 `@Scheduled` 注解就能很方便地创建一个定时任务,下面的代码中涵盖了 `@Scheduled `的常见用法,包括:固定速率执行、固定延迟执行、初始延迟执行、使用 Cron 表达式执行定时任务。 + +> Cron 表达式: 主要用于定时作业(定时任务)系统定义执行时间或执行频率的表达式,非常厉害,你可以通过 Cron 表达式进行设置定时任务每天或者每个月什么时候执行等等操作。 +> +> 推荐一个在线Cron表达式生成器:[http://cron.qqe2.com/](http://cron.qqe2.com/) + +```java +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.concurrent.TimeUnit; + +/** + * @author shuang.kou + */ +@Component +public class ScheduledTasks { + private static final Logger log = LoggerFactory.getLogger(ScheduledTasks.class); + private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss"); + + /** + * fixedRate:固定速率执行。每5秒执行一次。 + */ + @Scheduled(fixedRate = 5000) + public void reportCurrentTimeWithFixedRate() { + log.info("Current Thread : {}", Thread.currentThread().getName()); + log.info("Fixed Rate Task : The time is now {}", dateFormat.format(new Date())); + } + + /** + * fixedDelay:固定延迟执行。距离上一次调用成功后2秒才执。 + */ + @Scheduled(fixedDelay = 2000) + public void reportCurrentTimeWithFixedDelay() { + try { + TimeUnit.SECONDS.sleep(3); + log.info("Fixed Delay Task : The time is now {}", dateFormat.format(new Date())); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + /** + * initialDelay:初始延迟。任务的第一次执行将延迟5秒,然后将以5秒的固定间隔执行。 + */ + @Scheduled(initialDelay = 5000, fixedRate = 5000) + public void reportCurrentTimeWithInitialDelay() { + log.info("Fixed Rate Task with Initial Delay : The time is now {}", dateFormat.format(new Date())); + } + + /** + * cron:使用Cron表达式。 每分钟的1,2秒运行 + */ + @Scheduled(cron = "1-2 * * * * ? ") + public void reportCurrentTimeWithCronExpression() { + log.info("Cron Expression: The time is now {}", dateFormat.format(new Date())); + } +} + +``` + +###  2. 启动类上加上`@EnableScheduling`注解 + +在 SpringBoot 中我们只需要在启动类上加上`@EnableScheduling`便可以启动定时任务了。 + +```java +@SpringBootApplication +@EnableScheduling +public class DemoApplication { + + public static void main(String[] args) { + SpringApplication.run(DemoApplication.class, args); + } +} +``` + +### 3. 自定义线程池执行 scheduled task + +默认情况下,`@Scheduled`任务都在Spring创建的大小为1的默认线程池中执行,你可以通过在加了`@Scheduled`注解的方法里加上下面这段代码来验证。 + +```java +logger.info("Current Thread : {}", Thread.currentThread().getName()); +``` + +你会发现加上上面这段代码的定时任务,每次运行都会输出: + +``` +Current Thread : scheduling-1 +``` + +如果我们需要自定义线程池执行话只需要新加一个实现`SchedulingConfigurer`接口的 `configureTasks` 的类即可,这个类需要加上 `@Configuration` 注解。 + +```java +@Configuration +public class SchedulerConfig implements SchedulingConfigurer { + private final int POOL_SIZE = 10; + + @Override + public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) { + ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler(); + + threadPoolTaskScheduler.setPoolSize(POOL_SIZE); + threadPoolTaskScheduler.setThreadNamePrefix("my-scheduled-task-pool-"); + threadPoolTaskScheduler.initialize(); + + scheduledTaskRegistrar.setTaskScheduler(threadPoolTaskScheduler); + } +} +``` + +通过上面的验证的方式输出当前线程的名字会改变。 + From 16c59eadd18809e21eb04c983927f63be989c2b5 Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Tue, 20 Aug 2019 15:50:12 +0800 Subject: [PATCH 008/204] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fd87004..56b0841 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ SpringBoot和其他常用技术的整合,可能是你遇到的讲解最详细的 ## springboot-schedule-tast(SpringBoot 定时任务) -[5分钟搞懂如何在Spring Boot中Schedule Tasks](./md/SpringBoot-ScheduleTasks .md) +[5分钟搞懂如何在Spring Boot中Schedule Tasks](./md/SpringBoot-ScheduleTasks.md) ## springboot-mybatis(SpringBoot+Mybatis 的最佳实践) From 6b66b48b7e762f9af2bccbb809389ebb0b320d83 Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Wed, 21 Aug 2019 15:57:34 +0800 Subject: [PATCH 009/204] Create springboot-handle-exception.md --- md/springboot-handle-exception.md | 267 ++++++++++++++++++++++++++++++ 1 file changed, 267 insertions(+) create mode 100644 md/springboot-handle-exception.md diff --git a/md/springboot-handle-exception.md b/md/springboot-handle-exception.md new file mode 100644 index 0000000..54623a4 --- /dev/null +++ b/md/springboot-handle-exception.md @@ -0,0 +1,267 @@ +### 1. 使用 **@ControllerAdvice**和**@ExceptionHandler** 处理全局异常 + +这是目前很常用的一种方式,非常推荐。测试代码中用到了 Junit 5,如果你新建项目验证下面的代码的话,记得添加上相关依赖。 + +**1. 新建异常信息实体类** + +非必要的类,主要用于包装将异常信息。 + +`src/main/java/com/twuc/webApp/exception/ErrorResponse.java` + +```java +/** + * @author shuang.kou + */ +public class ErrorResponse { + + private String message; + private String errorTypeName; + + public ErrorResponse(Exception e) { + this(e.getClass().getName(), e.getMessage()); + } + + public ErrorResponse(String errorTypeName, String message) { + this.errorTypeName = errorTypeName; + this.message = message; + } + ......省略getter/setter方法 +} +``` + +**2. 自定义异常类型** + +`src/main/java/com/twuc/webApp/exception/ResourceNotFoundException.java` + +一般我们处理的都是 `RuntimeException` ,所以如果你需要自定义异常类型的话直接集成这个类就可以了。 + +```java +/** + * @author shuang.kou + * 自定义异常类型 + */ +public class ResourceNotFoundException extends RuntimeException { + private String message; + + public ResourceNotFoundException() { + super(); + } + + public ResourceNotFoundException(String message) { + super(message); + this.message = message; + } + + @Override + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} +``` + +**3. 新建异常处理类** + +我们只需要在类上加上`@ControllerAdvice`注解这个类就成为了全局异常处理类,当然你也可以通过 `assignableTypes `指定特定的类,让异常处理类只处理特定类抛出的异常。 + +`src/main/java/com/twuc/webApp/exception/GlobalExceptionHandler.java` + +```java +/** + * @author shuang.kou + */ +@ControllerAdvice(assignableTypes = {ExceptionController.class}) +@ResponseBody +public class GlobalExceptionHandler { + + ErrorResponse illegalArgumentResponse = new ErrorResponse(new IllegalArgumentException("参数错误!")); + ErrorResponse resourseNotFoundResponse = new ErrorResponse(new ResourceNotFoundException("Sorry, the resourse not found!")); + + @ExceptionHandler(value = Exception.class)// 拦截所有异常, 这里只是为了演示,一般情况下一个方法特定处理一种异常 + public ResponseEntity exceptionHandler(Exception e) { + + if (e instanceof IllegalArgumentException) { + return ResponseEntity.status(400).body(illegalArgumentResponse); + } else if (e instanceof ResourceNotFoundException) { + return ResponseEntity.status(404).body(resourseNotFoundResponse); + } + return null; + } +} +``` + +**4. controller模拟抛出异常** + +`src/main/java/com/twuc/webApp/web/ExceptionController.java` + +```java +/** + * @author shuang.kou + */ +@RestController +@RequestMapping("/api") +public class ExceptionController { + + @GetMapping("/illegalArgumentException") + public void throwException() { + throw new IllegalArgumentException(); + } + + @GetMapping("/resourceNotFoundException") + public void throwException2() { + throw new ResourceNotFoundException(); + } +} +``` + +使用 Get 请求 [localhost:8080/api/resourceNotFoundException](localhost:8333/api/resourceNotFoundException) (curl -i -s -X GET url),服务端返回的 JSON 数据如下: + +```json +{ + "message": "Sorry, the resourse not found!", + "errorTypeName": "com.twuc.webApp.exception.ResourceNotFoundException" +} +``` + +**5. 编写测试类** + +MockMvc 由`org.springframework.boot.test`包提供,实现了对Http请求的模拟,一般用于我们测试 controller 层。 + +```java +/** + * @author shuang.kou + */ +@AutoConfigureMockMvc +@SpringBootTest +public class ExceptionTest { + @Autowired + MockMvc mockMvc; + + @Test + void should_return_400_if_param_not_valid() throws Exception { + mockMvc.perform(get("/api/illegalArgumentException")) + .andExpect(status().is(400)) + .andExpect(jsonPath("$.message").value("参数错误!")); + } + + @Test + void should_return_404_if_resourse_not_found() throws Exception { + mockMvc.perform(get("/api/resourceNotFoundException")) + .andExpect(status().is(404)) + .andExpect(jsonPath("$.message").value("Sorry, the resourse not found!")); + } +} +``` + +### 2. @ExceptionHandler 处理 Controller 级别的异常 + +我们刚刚也说了使用`@ControllerAdvice`注解 可以通过 `assignableTypes `指定特定的类,让异常处理类只处理特定类抛出的异常。所以这种处理异常的方式,实际上现在使用的比较少了。 + + 我们把下面这段代码移到 `src/main/java/com/twuc/webApp/exception/GlobalExceptionHandler.java` 中就可以了。 + +```java + @ExceptionHandler(value = Exception.class)// 拦截所有异常 + public ResponseEntity exceptionHandler(Exception e) { + + if (e instanceof IllegalArgumentException) { + return ResponseEntity.status(400).body(illegalArgumentResponse); + } else if (e instanceof ResourceNotFoundException) { + return ResponseEntity.status(404).body(resourseNotFoundResponse); + } + return null; + } +``` + +### 3. ResponseStatusException + +研究 ResponseStatusException 我们先来看看,通过 `ResponseStatus`注解简单处理异常的方法。 + +`src/main/java/com/twuc/webApp/exception/ResourceNotFoundException.java` + + ```java +@ResponseStatus(code = HttpStatus.NOT_FOUND) +public class ResourseNotFoundException2 extends RuntimeException { + + public ResourseNotFoundException2() { + } + + public ResourseNotFoundException2(String message) { + super(message); + } +} + ``` + + `src/main/java/com/twuc/webApp/web/ResponseStatusExceptionController.java` + +```java +@RestController +@RequestMapping("/api") +public class ResponseStatusExceptionController { + @GetMapping("/resourceNotFoundException2") + public void throwException3() { + throw new ResourseNotFoundException2("Sorry, the resourse not found!"); + } +} +``` + + 使用 Get 请求 [localhost:8080/api/resourceNotFoundException2](localhost:8333/api/resourceNotFoundException2) ,服务端返回的 JSON 数据如下: + +```json +{ + "timestamp": "2019-08-21T07:11:43.744+0000", + "status": 404, + "error": "Not Found", + "message": "Sorry, the resourse not found!", + "path": "/api/resourceNotFoundException2" +} +``` + +这种通过 `ResponseStatus`注解简单处理异常的方法是的好处是比较简单,但是一般我们不会这样做,通过`ResponseStatusException`会更加方便,可以避免我们额外的异常类。 + +```java + @GetMapping("/resourceNotFoundException2") + public void throwException3() { + throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Sorry, the resourse not found!", new ResourceNotFoundException()); + } +``` + + 使用 Get 请求 [localhost:8080/api/resourceNotFoundException2](localhost:8333/api/resourceNotFoundException2) ,服务端返回的 JSON 数据如下,和使用 `ResponseStatus` 实现的效果一样: + + ```json +{ + "timestamp": "2019-08-21T07:28:12.017+0000", + "status": 404, + "error": "Not Found", + "message": "Sorry, the resourse not found!", + "path": "/api/resourceNotFoundException3" +} + ``` + +`ResponseStatusException` 提供了三个构造方法: + +```java + public ResponseStatusException(HttpStatus status) { + this(status, null, null); + } + + public ResponseStatusException(HttpStatus status, @Nullable String reason) { + this(status, reason, null); + } + + public ResponseStatusException(HttpStatus status, @Nullable String reason, @Nullable Throwable cause) { + super(null, cause); + Assert.notNull(status, "HttpStatus is required"); + this.status = status; + this.reason = reason; + } + +``` + +构造函数中的参数解释如下: + +- status : http status +- reason :response 的消息内容 +- cause : 抛出的异常 \ No newline at end of file From 968abb1b4ea31f878013bf511eeac8dc8f767180 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Wed, 21 Aug 2019 16:03:02 +0800 Subject: [PATCH 010/204] Update README.md --- README.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/README.md b/README.md index 56b0841..adfc00a 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,3 @@ -# springboot-integration-examples - -SpringBoot和其他常用技术的整合,可能是你遇到的讲解最详细的学习案例,力争新手也能看懂并且能够在看完之后独立实践。基于最新的 SpringBoot2.0+,是你学习SpringBoot 的最佳指南。 - ## springboot-schedule-tast(SpringBoot 定时任务) [5分钟搞懂如何在Spring Boot中Schedule Tasks](./md/SpringBoot-ScheduleTasks.md) From 0798c199c14247145ace8e358406a719453fb3f8 Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Wed, 21 Aug 2019 16:17:24 +0800 Subject: [PATCH 011/204] feat:springboot handle exception --- springboot-handle-exception/.gitignore | 84 +++++++++ .../.idea/checkstyle-idea.xml | 16 ++ .../inspectionProfiles/Project_Default.xml | 36 ++++ springboot-handle-exception/.idea/misc.xml | 16 ++ springboot-handle-exception/.idea/vcs.xml | 6 + springboot-handle-exception/build.gradle | 30 +++ .../gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 55190 bytes .../gradle/wrapper/gradle-wrapper.properties | 5 + springboot-handle-exception/gradlew | 172 ++++++++++++++++++ springboot-handle-exception/gradlew.bat | 84 +++++++++ springboot-handle-exception/settings.gradle | 6 + .../com/twuc/webApp/WebAppApplication.java | 11 ++ .../twuc/webApp/exception/ErrorResponse.java | 46 +++++ .../exception/GlobalExceptionHandler.java | 29 +++ .../exception/ResourceNotFoundException.java | 27 +++ .../exception/ResourseNotFoundException2.java | 15 ++ .../twuc/webApp/web/ExceptionController.java | 24 +++ .../ResponseStatusExceptionController.java | 24 +++ .../src/main/resources/application.properties | 2 + .../com/twuc/webApp/web/ExceptionTest.java | 42 +++++ 20 files changed, 675 insertions(+) create mode 100644 springboot-handle-exception/.gitignore create mode 100644 springboot-handle-exception/.idea/checkstyle-idea.xml create mode 100644 springboot-handle-exception/.idea/inspectionProfiles/Project_Default.xml create mode 100644 springboot-handle-exception/.idea/misc.xml create mode 100644 springboot-handle-exception/.idea/vcs.xml create mode 100644 springboot-handle-exception/build.gradle create mode 100644 springboot-handle-exception/gradle/wrapper/gradle-wrapper.jar create mode 100644 springboot-handle-exception/gradle/wrapper/gradle-wrapper.properties create mode 100755 springboot-handle-exception/gradlew create mode 100644 springboot-handle-exception/gradlew.bat create mode 100644 springboot-handle-exception/settings.gradle create mode 100644 springboot-handle-exception/src/main/java/com/twuc/webApp/WebAppApplication.java create mode 100644 springboot-handle-exception/src/main/java/com/twuc/webApp/exception/ErrorResponse.java create mode 100644 springboot-handle-exception/src/main/java/com/twuc/webApp/exception/GlobalExceptionHandler.java create mode 100644 springboot-handle-exception/src/main/java/com/twuc/webApp/exception/ResourceNotFoundException.java create mode 100644 springboot-handle-exception/src/main/java/com/twuc/webApp/exception/ResourseNotFoundException2.java create mode 100644 springboot-handle-exception/src/main/java/com/twuc/webApp/web/ExceptionController.java create mode 100644 springboot-handle-exception/src/main/java/com/twuc/webApp/web/ResponseStatusExceptionController.java create mode 100644 springboot-handle-exception/src/main/resources/application.properties create mode 100644 springboot-handle-exception/src/test/java/com/twuc/webApp/web/ExceptionTest.java diff --git a/springboot-handle-exception/.gitignore b/springboot-handle-exception/.gitignore new file mode 100644 index 0000000..8844094 --- /dev/null +++ b/springboot-handle-exception/.gitignore @@ -0,0 +1,84 @@ +.gradle +/build/ + +# Ignore Gradle GUI config +gradle-app.setting + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar + +# Cache of project +.gradletasknamecache + +# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 +# gradle/wrapper/gradle-wrapper.properties + +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/modules.xml +# .idea/*.iml +# .idea/modules + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +# Mac-OS cache file +.DS_Store \ No newline at end of file diff --git a/springboot-handle-exception/.idea/checkstyle-idea.xml b/springboot-handle-exception/.idea/checkstyle-idea.xml new file mode 100644 index 0000000..96cfa21 --- /dev/null +++ b/springboot-handle-exception/.idea/checkstyle-idea.xml @@ -0,0 +1,16 @@ + + + + + + \ No newline at end of file diff --git a/springboot-handle-exception/.idea/inspectionProfiles/Project_Default.xml b/springboot-handle-exception/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..6560a98 --- /dev/null +++ b/springboot-handle-exception/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,36 @@ + + + + \ No newline at end of file diff --git a/springboot-handle-exception/.idea/misc.xml b/springboot-handle-exception/.idea/misc.xml new file mode 100644 index 0000000..ec8cefe --- /dev/null +++ b/springboot-handle-exception/.idea/misc.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/springboot-handle-exception/.idea/vcs.xml b/springboot-handle-exception/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/springboot-handle-exception/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/springboot-handle-exception/build.gradle b/springboot-handle-exception/build.gradle new file mode 100644 index 0000000..a00b816 --- /dev/null +++ b/springboot-handle-exception/build.gradle @@ -0,0 +1,30 @@ +plugins { + id 'org.springframework.boot' version '2.1.3.RELEASE' + id 'java' +} + +apply plugin: 'io.spring.dependency-management' + +group = 'com.twuc' +version = '0.0.1-SNAPSHOT' +sourceCompatibility = '1.8' + +repositories { + mavenCentral() +} + +dependencies { + implementation 'org.springframework.boot:spring-boot-starter-web' + testImplementation ('org.springframework.boot:spring-boot-starter-test') { + exclude group:'junit', module: 'junit' + } + testImplementation 'org.junit.jupiter:junit-jupiter:5.4.2' + testCompile group: 'org.junit.jupiter', name: 'junit-jupiter-params', version: '5.4.1' +} + +test { + useJUnitPlatform() + testLogging { + events 'passed', 'skipped', 'failed' + } +} \ No newline at end of file diff --git a/springboot-handle-exception/gradle/wrapper/gradle-wrapper.jar b/springboot-handle-exception/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..87b738cbd051603d91cc39de6cb000dd98fe6b02 GIT binary patch literal 55190 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 z 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 \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +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 + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/springboot-handle-exception/gradlew.bat b/springboot-handle-exception/gradlew.bat new file mode 100644 index 0000000..6d57edc --- /dev/null +++ b/springboot-handle-exception/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/springboot-handle-exception/settings.gradle b/springboot-handle-exception/settings.gradle new file mode 100644 index 0000000..235bf39 --- /dev/null +++ b/springboot-handle-exception/settings.gradle @@ -0,0 +1,6 @@ +pluginManagement { + repositories { + gradlePluginPortal() + } +} +rootProject.name = 'webApp' diff --git a/springboot-handle-exception/src/main/java/com/twuc/webApp/WebAppApplication.java b/springboot-handle-exception/src/main/java/com/twuc/webApp/WebAppApplication.java new file mode 100644 index 0000000..0dbe6c6 --- /dev/null +++ b/springboot-handle-exception/src/main/java/com/twuc/webApp/WebAppApplication.java @@ -0,0 +1,11 @@ +package com.twuc.webApp; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class WebAppApplication { + public static void main(String[] args) { + SpringApplication.run(WebAppApplication.class, args); + } +} diff --git a/springboot-handle-exception/src/main/java/com/twuc/webApp/exception/ErrorResponse.java b/springboot-handle-exception/src/main/java/com/twuc/webApp/exception/ErrorResponse.java new file mode 100644 index 0000000..05b920e --- /dev/null +++ b/springboot-handle-exception/src/main/java/com/twuc/webApp/exception/ErrorResponse.java @@ -0,0 +1,46 @@ +package com.twuc.webApp.exception; + +/** + * @author shuang.kou + */ +public class ErrorResponse { + + private String message; + private String errorTypeName; + + public ErrorResponse() { + } + + public ErrorResponse(Exception e) { + this(e.getClass().getName(), e.getMessage()); + } + + public ErrorResponse(String errorTypeName, String message) { + this.errorTypeName = errorTypeName; + this.message = message; + } + + public String getErrorTypeName() { + return errorTypeName; + } + + public void setErrorTypeName(String errorTypeName) { + this.errorTypeName = errorTypeName; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + @Override + public String toString() { + return "ErrorResponse{" + + "errorTypeName='" + errorTypeName + '\'' + + ", message='" + message + '\'' + + '}'; + } +} diff --git a/springboot-handle-exception/src/main/java/com/twuc/webApp/exception/GlobalExceptionHandler.java b/springboot-handle-exception/src/main/java/com/twuc/webApp/exception/GlobalExceptionHandler.java new file mode 100644 index 0000000..aa5b6fe --- /dev/null +++ b/springboot-handle-exception/src/main/java/com/twuc/webApp/exception/GlobalExceptionHandler.java @@ -0,0 +1,29 @@ +package com.twuc.webApp.exception; + +import com.twuc.webApp.web.ExceptionController; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseBody; + +/** + * @author shuang.kou + */ +@ControllerAdvice(assignableTypes = {ExceptionController.class}) +@ResponseBody +public class GlobalExceptionHandler { + + ErrorResponse illegalArgumentResponse = new ErrorResponse(new IllegalArgumentException("参数错误!")); + ErrorResponse resourseNotFoundResponse = new ErrorResponse(new ResourceNotFoundException("Sorry, the resourse not found!")); + + @ExceptionHandler(value = Exception.class)// 拦截所有异常 + public ResponseEntity exceptionHandler(Exception e) { + + if (e instanceof IllegalArgumentException) { + return ResponseEntity.status(400).body(illegalArgumentResponse); + } else if (e instanceof ResourceNotFoundException) { + return ResponseEntity.status(404).body(resourseNotFoundResponse); + } + return null; + } +} diff --git a/springboot-handle-exception/src/main/java/com/twuc/webApp/exception/ResourceNotFoundException.java b/springboot-handle-exception/src/main/java/com/twuc/webApp/exception/ResourceNotFoundException.java new file mode 100644 index 0000000..7cc8bed --- /dev/null +++ b/springboot-handle-exception/src/main/java/com/twuc/webApp/exception/ResourceNotFoundException.java @@ -0,0 +1,27 @@ +package com.twuc.webApp.exception; + +/** + * @author shuang.kou + * 自定义异常类型 + */ +public class ResourceNotFoundException extends RuntimeException { + private String message; + + public ResourceNotFoundException() { + super(); + } + + public ResourceNotFoundException(String message) { + super(message); + this.message = message; + } + + @Override + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/springboot-handle-exception/src/main/java/com/twuc/webApp/exception/ResourseNotFoundException2.java b/springboot-handle-exception/src/main/java/com/twuc/webApp/exception/ResourseNotFoundException2.java new file mode 100644 index 0000000..a967ec1 --- /dev/null +++ b/springboot-handle-exception/src/main/java/com/twuc/webApp/exception/ResourseNotFoundException2.java @@ -0,0 +1,15 @@ +package com.twuc.webApp.exception; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ResponseStatus(code = HttpStatus.NOT_FOUND) +public class ResourseNotFoundException2 extends RuntimeException { + + public ResourseNotFoundException2() { + } + + public ResourseNotFoundException2(String message) { + super(message); + } +} diff --git a/springboot-handle-exception/src/main/java/com/twuc/webApp/web/ExceptionController.java b/springboot-handle-exception/src/main/java/com/twuc/webApp/web/ExceptionController.java new file mode 100644 index 0000000..2637b8d --- /dev/null +++ b/springboot-handle-exception/src/main/java/com/twuc/webApp/web/ExceptionController.java @@ -0,0 +1,24 @@ +package com.twuc.webApp.web; + +import com.twuc.webApp.exception.ResourceNotFoundException; +import com.twuc.webApp.exception.ResourseNotFoundException2; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api") +public class ExceptionController { + + @GetMapping("/illegalArgumentException") + public void throwException() { + throw new IllegalArgumentException(); + } + + @GetMapping("/resourceNotFoundException") + public void throwException2() { + throw new ResourceNotFoundException(); + } + + +} diff --git a/springboot-handle-exception/src/main/java/com/twuc/webApp/web/ResponseStatusExceptionController.java b/springboot-handle-exception/src/main/java/com/twuc/webApp/web/ResponseStatusExceptionController.java new file mode 100644 index 0000000..cff50fc --- /dev/null +++ b/springboot-handle-exception/src/main/java/com/twuc/webApp/web/ResponseStatusExceptionController.java @@ -0,0 +1,24 @@ +package com.twuc.webApp.web; + + +import com.twuc.webApp.exception.ResourceNotFoundException; +import com.twuc.webApp.exception.ResourseNotFoundException2; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.server.ResponseStatusException; + +@RestController +@RequestMapping("/api") +public class ResponseStatusExceptionController { + @GetMapping("/resourceNotFoundException2") + public void throwException() { + throw new ResourseNotFoundException2("Sorry, the resourse not found!"); + } + + @GetMapping("/resourceNotFoundException3") + public void throwException1() { + throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Sorry, the resourse not found!", new ResourceNotFoundException()); + } +} diff --git a/springboot-handle-exception/src/main/resources/application.properties b/springboot-handle-exception/src/main/resources/application.properties new file mode 100644 index 0000000..eeb97b0 --- /dev/null +++ b/springboot-handle-exception/src/main/resources/application.properties @@ -0,0 +1,2 @@ + +server.port=8333 \ No newline at end of file diff --git a/springboot-handle-exception/src/test/java/com/twuc/webApp/web/ExceptionTest.java b/springboot-handle-exception/src/test/java/com/twuc/webApp/web/ExceptionTest.java new file mode 100644 index 0000000..b438e5f --- /dev/null +++ b/springboot-handle-exception/src/test/java/com/twuc/webApp/web/ExceptionTest.java @@ -0,0 +1,42 @@ +package com.twuc.webApp.web; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.HttpStatus; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.web.servlet.MockMvc; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@AutoConfigureMockMvc +@SpringBootTest +public class ExceptionTest { + @Autowired + MockMvc mockMvc; + + @Test + void should_return_400_if_param_not_valid() throws Exception { + mockMvc.perform(get("/api/illegalArgumentException")) + .andExpect(status().is(400)) + .andExpect(jsonPath("$.message").value("参数错误!")); + } + + @Test + void should_return_404_if_resourse_not_found() throws Exception { + mockMvc.perform(get("/api/resourceNotFoundException")) + .andExpect(status().is(404)) + .andExpect(jsonPath("$.message").value("Sorry, the resourse not found!")); + } + + @Test + void should_return_404_if_resourse_not_found2() throws Exception { + mockMvc.perform(get("/api/resourceNotFoundException2")) + .andExpect(status().isNotFound()) + .andExpect(jsonPath("$.message").value("Resourse Not Found")); + } +} From b5fe56831f869968c7848e076eb96df89635f5f9 Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Wed, 21 Aug 2019 16:26:15 +0800 Subject: [PATCH 012/204] Update README.md --- README.md | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index adfc00a..6782de2 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,33 @@ -## springboot-schedule-tast(SpringBoot 定时任务) + + +- [SpringBoot 定时任务](#springboot-定时任务) +- [SpringBoot 异常处理](#springboot-异常处理) +- [SpringBoot+Mybatis](#springbootmybatis) +- [SpringBoot+阿里云OSS 存储服务](#springboot阿里云oss-存储服务) +- [springboot-dubbo(使用SpringBoot+Dubbo 搭建一个分布式服务)](#springboot-dubbo使用springbootdubbo-搭建一个分布式服务) + + + +### SpringBoot 定时任务 [5分钟搞懂如何在Spring Boot中Schedule Tasks](./md/SpringBoot-ScheduleTasks.md) -## springboot-mybatis(SpringBoot+Mybatis 的最佳实践) +### SpringBoot 异常处理 + + +[SpringBoot 异常处理](./md/springboot-handle-exception.md) + +### SpringBoot+Mybatis -[优雅整合 SpringBoot+Mybatis,可能是你见过把 SpringBoot 整合 Mybatis 写的最详细的一篇文章](./md/springboot-mybatis.md) +[整合 SpringBoot+Mybatis](./md/springboot-mybatis.md) -[新手也能看懂,基于SpirngBoot2.0+ 的 SpringBoot+Mybatis 多数据源配置](./md/springboot-mybatis-mutipledatasource.md) +[简单地 SpirngBoot2.0+ 的 SpringBoot+Mybatis 多数据源配置](./md/springboot-mybatis-mutipledatasource.md) -## springboot-oss(SpringBoot 整合 阿里云OSS 存储服务) +### SpringBoot+阿里云OSS 存储服务 [SpringBoot 整合 阿里云OSS 存储服务,快来免费搭建一个自己的图床](./md/springboot-oss.md) -## springboot-dubbo(使用SpringBoot+Dubbo 搭建一个分布式服务) +### springboot-dubbo(使用SpringBoot+Dubbo 搭建一个分布式服务) [超详细,新手都能看懂 !使用SpringBoot+Dubbo 搭建一个分布式服务](./md/springboot-dubbo.md) From ae3f7f149f3b6519a1c6a58ef719d09148d08906 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Wed, 21 Aug 2019 16:27:06 +0800 Subject: [PATCH 013/204] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 6782de2..40534c5 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ + **目录:** + - [SpringBoot 定时任务](#springboot-定时任务) - [SpringBoot 异常处理](#springboot-异常处理) - [SpringBoot+Mybatis](#springbootmybatis) From bc6e758cb2f7c8b9553343c27faed7daa3c066a0 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Wed, 21 Aug 2019 16:27:46 +0800 Subject: [PATCH 014/204] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 40534c5..3e9505b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ - **目录:** + ### 目录 - [SpringBoot 定时任务](#springboot-定时任务) - [SpringBoot 异常处理](#springboot-异常处理) From f3d18e6644612d3650f4fe4d83772974efffa794 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Wed, 21 Aug 2019 16:31:37 +0800 Subject: [PATCH 015/204] Update springboot-handle-exception.md --- md/springboot-handle-exception.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/md/springboot-handle-exception.md b/md/springboot-handle-exception.md index 54623a4..41e91d0 100644 --- a/md/springboot-handle-exception.md +++ b/md/springboot-handle-exception.md @@ -1,4 +1,4 @@ -### 1. 使用 **@ControllerAdvice**和**@ExceptionHandler** 处理全局异常 +### 1. 使用 **@ControllerAdvice和**@ExceptionHandler处理全局异常 这是目前很常用的一种方式,非常推荐。测试代码中用到了 Junit 5,如果你新建项目验证下面的代码的话,记得添加上相关依赖。 @@ -264,4 +264,4 @@ public class ResponseStatusExceptionController { - status : http status - reason :response 的消息内容 -- cause : 抛出的异常 \ No newline at end of file +- cause : 抛出的异常 From 4fceb1b4b2a2cf55de376d3bd89624dd1ade7f85 Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Wed, 21 Aug 2019 21:41:40 +0800 Subject: [PATCH 016/204] Update springboot-handle-exception.md --- md/springboot-handle-exception.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/md/springboot-handle-exception.md b/md/springboot-handle-exception.md index 41e91d0..f06e05b 100644 --- a/md/springboot-handle-exception.md +++ b/md/springboot-handle-exception.md @@ -4,7 +4,7 @@ **1. 新建异常信息实体类** -非必要的类,主要用于包装将异常信息。 +非必要的类,主要用于包装异常信息。 `src/main/java/com/twuc/webApp/exception/ErrorResponse.java` @@ -65,7 +65,7 @@ public class ResourceNotFoundException extends RuntimeException { **3. 新建异常处理类** -我们只需要在类上加上`@ControllerAdvice`注解这个类就成为了全局异常处理类,当然你也可以通过 `assignableTypes `指定特定的类,让异常处理类只处理特定类抛出的异常。 +我们只需要在类上加上`@ControllerAdvice`注解这个类就成为了全局异常处理类,当然你也可以通过 `assignableTypes `指定特定的 `Controller `类,让异常处理类只处理特定类抛出的异常。 `src/main/java/com/twuc/webApp/exception/GlobalExceptionHandler.java` @@ -177,7 +177,7 @@ public class ExceptionTest { ### 3. ResponseStatusException -研究 ResponseStatusException 我们先来看看,通过 `ResponseStatus`注解简单处理异常的方法。 +研究 ResponseStatusException 我们先来看看,通过 `ResponseStatus`注解简单处理异常的方法(将异常映射为状态码)。 `src/main/java/com/twuc/webApp/exception/ResourceNotFoundException.java` From 893d557773ca73a965aa6666b8788aece2f405be Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Wed, 21 Aug 2019 21:51:41 +0800 Subject: [PATCH 017/204] Create .name --- springboot-handle-exception/.idea/.name | 1 + 1 file changed, 1 insertion(+) create mode 100644 springboot-handle-exception/.idea/.name diff --git a/springboot-handle-exception/.idea/.name b/springboot-handle-exception/.idea/.name new file mode 100644 index 0000000..52b95b2 --- /dev/null +++ b/springboot-handle-exception/.idea/.name @@ -0,0 +1 @@ +webApp \ No newline at end of file From 6a17001153860c35a8b299782656a7074da698ba Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Wed, 21 Aug 2019 21:51:44 +0800 Subject: [PATCH 018/204] Update vcs.xml --- springboot-handle-exception/.idea/vcs.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/springboot-handle-exception/.idea/vcs.xml b/springboot-handle-exception/.idea/vcs.xml index 35eb1dd..62bd7a0 100644 --- a/springboot-handle-exception/.idea/vcs.xml +++ b/springboot-handle-exception/.idea/vcs.xml @@ -2,5 +2,6 @@ + \ No newline at end of file From 8c135735299a912ae3db549b54b4a3eda3b97c70 Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Sat, 24 Aug 2019 16:15:44 +0800 Subject: [PATCH 019/204] Create AsyncScheduledTasks.java --- .../com/example/demo/AsyncScheduledTasks.java | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 springboot-schedule-tast/src/main/java/com/example/demo/AsyncScheduledTasks.java diff --git a/springboot-schedule-tast/src/main/java/com/example/demo/AsyncScheduledTasks.java b/springboot-schedule-tast/src/main/java/com/example/demo/AsyncScheduledTasks.java new file mode 100644 index 0000000..014813a --- /dev/null +++ b/springboot-schedule-tast/src/main/java/com/example/demo/AsyncScheduledTasks.java @@ -0,0 +1,57 @@ +package com.example.demo; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.scheduling.annotation.Async; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.concurrent.TimeUnit; + +/** + * @author shuang.kou + */ +@Component +@EnableAsync +public class AsyncScheduledTasks { + private static final Logger log = LoggerFactory.getLogger(AsyncScheduledTasks.class); + private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss"); + private List index = Arrays.asList(6, 6, 2, 3); + int i = 0; + /** + * fixedDelay:固定延迟执行。距离上一次调用成功后2秒才执。 + */ + @Async + @Scheduled(fixedDelay = 2000) + public void reportCurrentTimeWithFixedDelay() { + log.info("Current Thread : {}", Thread.currentThread().getName()); + try { + TimeUnit.SECONDS.sleep(3); + log.info("Fixed Delay Task : The time is now {}", dateFormat.format(new Date())); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + //@Async + @Scheduled(fixedRate = 5000) + public void reportCurrentTimeWithFixedRate() { + if (i == 0) { + log.info("start time is {}", dateFormat.format(new Date())); + } + if (i < 5) { + try { + TimeUnit.SECONDS.sleep(index.get(i)); + log.info("Fixed Rate Task : The time is now {}", dateFormat.format(new Date())); + } catch (InterruptedException e) { + e.printStackTrace(); + } + i++; + } + } +} From 3785eb6f8e304b8ed06572ef782d040141bbc7f9 Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Sat, 24 Aug 2019 16:15:46 +0800 Subject: [PATCH 020/204] Update ScheduledTasks.java --- .../java/com/example/demo/scheduletask/ScheduledTasks.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/springboot-schedule-tast/src/main/java/com/example/demo/scheduletask/ScheduledTasks.java b/springboot-schedule-tast/src/main/java/com/example/demo/scheduletask/ScheduledTasks.java index 0e71e36..f3d7c77 100644 --- a/springboot-schedule-tast/src/main/java/com/example/demo/scheduletask/ScheduledTasks.java +++ b/springboot-schedule-tast/src/main/java/com/example/demo/scheduletask/ScheduledTasks.java @@ -2,7 +2,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.scheduling.annotation.Async; +import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; import org.springframework.stereotype.Component; import java.text.SimpleDateFormat; @@ -13,6 +16,7 @@ * @author shuang.kou */ @Component +@EnableAsync public class ScheduledTasks { private static final Logger log = LoggerFactory.getLogger(ScheduledTasks.class); private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss"); @@ -20,9 +24,10 @@ public class ScheduledTasks { /** * fixedRate:固定速率执行。每5秒执行一次。 */ + @Async @Scheduled(fixedRate = 5000) public void reportCurrentTimeWithFixedRate() { - log.info("Current Thread : {}", Thread.currentThread().getName()); + log.info("Current Thread : {}", Thread.currentThread().getName()); log.info("Fixed Rate Task : The time is now {}", dateFormat.format(new Date())); } From 9d6a1faa6bfc34474d8ca5b5e0499db6e7187193 Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Sat, 24 Aug 2019 16:15:55 +0800 Subject: [PATCH 021/204] Update SpringBoot-ScheduleTasks.md --- md/SpringBoot-ScheduleTasks.md | 91 ++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/md/SpringBoot-ScheduleTasks.md b/md/SpringBoot-ScheduleTasks.md index 549fe5c..da776e4 100644 --- a/md/SpringBoot-ScheduleTasks.md +++ b/md/SpringBoot-ScheduleTasks.md @@ -73,6 +73,48 @@ public class ScheduledTasks { ``` +关于 fixedRate 这里其实有个坑,假如我们有这样一种情况:我们某个方法的定时器设定的固定速率是每5秒执行一次。这个方法现在要执行下面四个任务,四个任务的耗时是:6 s、6s、 2s、 3s,请问这些任务默认情况下(单线程)将如何被执行? + +我们写一段简单的程序验证: + +```java + private static final Logger log = LoggerFactory.getLogger(AsyncScheduledTasks.class); + private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss"); + private List index = Arrays.asList(6, 6, 2, 3); + int i = 0; + @Scheduled(fixedRate = 5000) + public void reportCurrentTimeWithFixedRate() { + if (i == 0) { + log.info("Start time is {}", dateFormat.format(new Date())); + } + if (i < 5) { + try { + TimeUnit.SECONDS.sleep(index.get(i)); + log.info("Fixed Rate Task : The time is now {}", dateFormat.format(new Date())); + } catch (InterruptedException e) { + e.printStackTrace(); + } + i++; + } + } +``` + +运行程序输出如下: + +```java +Start time is 20:58:33 +Fixed Rate Task : The time is now 20:58:39 +Fixed Rate Task : The time is now 20:58:45 +Fixed Rate Task : The time is now 20:58:47 +Fixed Rate Task : The time is now 20:58:51 +``` + + 看下面的运行任务示意图应该很好理解了。 + +![](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-7/fixdrate-single-thread.png) + +如果我们将这个方法改为并行运行,运行结果就截然不同了。 + ###  2. 启动类上加上`@EnableScheduling`注解 在 SpringBoot 中我们只需要在启动类上加上`@EnableScheduling`便可以启动定时任务了。 @@ -124,3 +166,52 @@ public class SchedulerConfig implements SchedulingConfigurer { 通过上面的验证的方式输出当前线程的名字会改变。 +### 4. @EnableAsync 和 @Async 使定时任务并行执行 + +如果你想要你的代码并行执行的话,还可以通过`@EnableAsync` 和 @`Async `这两个注解实现 + +```java +@Component +@EnableAsync +public class AsyncScheduledTasks { + private static final Logger log = LoggerFactory.getLogger(AsyncScheduledTasks.class); + private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss"); + + /** + * fixedDelay:固定延迟执行。距离上一次调用成功后2秒才执。 + */ + //@Async + @Scheduled(fixedDelay = 2000) + public void reportCurrentTimeWithFixedDelay() { + try { + TimeUnit.SECONDS.sleep(3); + log.info("Fixed Delay Task : The time is now {}", dateFormat.format(new Date())); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} +``` + +运行程序输出如下,`reportCurrentTimeWithFixedDelay()` 方法会每5秒执行一次,因为我们说过了`@Scheduled`任务都在Spring创建的大小为1的默认线程池中执行。 + +``` +Current Thread : scheduling-1 +Fixed Delay Task : The time is now 14:24:23 +Current Thread : scheduling-1 +Fixed Delay Task : The time is now 14:24:28 +Current Thread : scheduling-1 +Fixed Delay Task : The time is now 14:24:33 +``` + +`reportCurrentTimeWithFixedDelay()` 方法上加上 `@Async` 注解后输出如下,`reportCurrentTimeWithFixedDelay()` 方法会每 2 秒执行一次。 + +``` +Current Thread : task-1 +Fixed Delay Task : The time is now 14:27:32 +Current Thread : task-2 +Fixed Delay Task : The time is now 14:27:34 +Current Thread : task-3 +Fixed Delay Task : The time is now 14:27:36 +``` + From 8746b3d1772c8a5803622dd124ece8b9b8ba4ada Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Sat, 24 Aug 2019 16:15:59 +0800 Subject: [PATCH 022/204] Create RestControllerVSController.md --- md/RestControllerVSController.md | 145 +++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 md/RestControllerVSController.md diff --git a/md/RestControllerVSController.md b/md/RestControllerVSController.md new file mode 100644 index 0000000..de9de0c --- /dev/null +++ b/md/RestControllerVSController.md @@ -0,0 +1,145 @@ +周末的时候分享了一个技术session,讲到了@RestController 和 @Controller,当时没有太讲清楚,因为 team 里很多同事之前不是做 Java的,所以对这两个东西不太熟悉,于是写了篇文章整理了一下。 + +## @RestController vs @Controller + +### Controller 返回一个页面 + +单独使用 `@Controller` 不加 `@ResponseBody`的话一般使用在要返回一个视图的情况,这种情况属于比较传统的Spring MVC 的应用,对应于前后端不分离的情况。 + +![SpringMVC 传统工作流程](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-7/SpringMVC传统工作流程.png) + +### @RestController 返回JSON 或 XML 形式数据 + +但`@RestController`只返回对象,对象数据直接以 JSON 或 XML 形式写入 HTTP 响应(Response)中,这种情况属于 RESTful Web服务,这也是目前日常开发所接触的最常用的情况(前后端分离)。 + +![SpringMVC+RestController](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-7/SpringMVCRestController.png) + +### @Controller +@ResponseBody 返回JSON 或 XML 形式数据 + +如果你需要在Spring4之前开发 RESTful Web服务的话,你需要使用`@Controller` 并结合`@ResponseBody`注解,也就是说`@Controller` +`@ResponseBody`= `@RestController`(Spring 4 之后新加的注解)。 + +> `@ResponseBody` 注解的作用是将 `Controller` 的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到HTTP 响应(Response)对象的 body 中,通常用来返回 JSON 或者 XML 数据,返回 JSON 数据的情况比较多。 + +![Spring3.xMVC RESTfulWeb服务工作流程](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-7/Spring3.xMVCRESTfulWeb服务工作流程.png) + +Reference: + +- https://dzone.com/articles/spring-framework-restcontroller-vs-controller(图片来源) +- https://javarevisited.blogspot.com/2017/08/difference-between-restcontroller-and-controller-annotations-spring-mvc-rest.html?m=1 + +### 示例1: @Controller 返回一个页面 + +当我们需要直接在后端返回一个页面的时候,Spring 推荐使用 Thymeleaf 模板引擎。Spring MVC中`@Controller`中的方法可以直接返回模板名称,接下来 Thymeleaf 模板引擎会自动进行渲染,模板中的表达式支持Spring表达式语言(Spring EL)。**如果需要用到 Thymeleaf 模板引擎,注意添加依赖!不然会报错。** + +Gradle: + +```groovy + compile 'org.springframework.boot:spring-boot-starter-thymeleaf' +``` + +Maven: + +```xml + + org.springframework.boot + spring-boot-starter-thymeleaf + +``` + +`src/main/java/com/example/demo/controller/HelloController.java` + +```java +@Controller +public class HelloController { + @GetMapping("/hello") + public String greeting(@RequestParam(name = "name", required = false, defaultValue = "World") String name, Model model) { + model.addAttribute("name", name); + return "hello"; + } +} +``` +`src/main/resources/templates/hello.html` + +Spring 会去 resources 目录下 templates 目录下找,所以建议把页面放在 resources/templates 目录下 + +```html + + + + Getting Started: Serving Web Content + + + +

+ + +``` + +访问:http://localhost:8999/hello?name=team-c ,你将看到下面的内容 + +``` +Hello, team-c! +``` + +如果要对页面在templates目录下的hello文件夹中的话,返回页面的时候像下面这样写就可以了。 + +`src/main/resources/templates/hello/hello.html` + +```java + return "hello/hello"; +``` + +### 示例2: @Controller+@ResponseBody 返回 JSON 格式数据 + +**SpringBoot 默认集成了 jackson ,对于此需求你不需要添加任何相关依赖。** + +`src/main/java/com/example/demo/controller/Person.java` + +```java +public class Person { + private String name; + private Integer age; + ...... + 省略getter/setter ,有参和无参的construtor方法 +} + +``` + +`src/main/java/com/example/demo/controller/HelloController.java` + +```java +@Controller +public class HelloController { + @PostMapping("/hello") + @ResponseBody + public Person greeting(@RequestBody Person person) { + return person; + } + +} +``` + +使用 post 请求访问 http://localhost:8080/hello ,body 中附带以下参数,后端会以json 格式将 person 对象返回。 + +```json +{ + "name": "teamc", + "age": 1 +} +``` + +### 示例3: @RestController 返回 JSON 格式数据 + +只需要将`HelloController`改为如下形式: + +```java +@RestController +public class HelloController { + @PostMapping("/hello") + public Person greeting(@RequestBody Person person) { + return person; + } + +} +``` + From a6b39ea17363a5fe1251aad2214d2a22c023b824 Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Sat, 24 Aug 2019 16:31:06 +0800 Subject: [PATCH 023/204] Update README.md --- README.md | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 3e9505b..282b93d 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,21 @@ - +### 目录 - ### 目录 - -- [SpringBoot 定时任务](#springboot-定时任务) -- [SpringBoot 异常处理](#springboot-异常处理) -- [SpringBoot+Mybatis](#springbootmybatis) -- [SpringBoot+阿里云OSS 存储服务](#springboot阿里云oss-存储服务) -- [springboot-dubbo(使用SpringBoot+Dubbo 搭建一个分布式服务)](#springboot-dubbo使用springbootdubbo-搭建一个分布式服务) +- [重要知识点](#重要知识点) +- [实例](#实例) + - [SpringBoot 定时任务](#springboot-定时任务) + - [SpringBoot 异常处理](#springboot-异常处理) + - [SpringBoot+Mybatis](#springbootmybatis) + - [SpringBoot+阿里云OSS 存储服务](#springboot阿里云oss-存储服务) + - [springboot-dubbo(使用SpringBoot+Dubbo 搭建一个分布式服务)](#springboot-dubbo使用springbootdubbo-搭建一个分布式服务) +## 重要知识点 + +- [RestController VS Controller](./md/RestControllerVSController.md) + +## 实例 + ### SpringBoot 定时任务 [5分钟搞懂如何在Spring Boot中Schedule Tasks](./md/SpringBoot-ScheduleTasks.md) @@ -31,5 +37,4 @@ ### springboot-dubbo(使用SpringBoot+Dubbo 搭建一个分布式服务) -[超详细,新手都能看懂 !使用SpringBoot+Dubbo 搭建一个分布式服务](./md/springboot-dubbo.md) - +[超详细,新手都能看懂 !使用SpringBoot+Dubbo 搭建一个分布式服务](./md/springboot-dubbo.md) \ No newline at end of file From d95a14752b90ea13f61d6146d4e19f19614be6e8 Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Sun, 8 Sep 2019 16:21:45 +0800 Subject: [PATCH 024/204] =?UTF-8?q?Create=20=E5=85=B3=E4=BA=8ESpring?= =?UTF-8?q?=E4=B8=AD=E7=9A=84=E5=8F=82=E6=95=B0=E6=A0=A1=E9=AA=8C=E7=9A=84?= =?UTF-8?q?=E4=B8=80=E7=82=B9=E6=80=9D=E8=80=83.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...00\347\202\271\346\200\235\350\200\203.md" | 348 ++++++++++++++++++ 1 file changed, 348 insertions(+) create mode 100644 "md/\345\205\263\344\272\216Spring\344\270\255\347\232\204\345\217\202\346\225\260\346\240\241\351\252\214\347\232\204\344\270\200\347\202\271\346\200\235\350\200\203.md" diff --git "a/md/\345\205\263\344\272\216Spring\344\270\255\347\232\204\345\217\202\346\225\260\346\240\241\351\252\214\347\232\204\344\270\200\347\202\271\346\200\235\350\200\203.md" "b/md/\345\205\263\344\272\216Spring\344\270\255\347\232\204\345\217\202\346\225\260\346\240\241\351\252\214\347\232\204\344\270\200\347\202\271\346\200\235\350\200\203.md" new file mode 100644 index 0000000..381b8c9 --- /dev/null +++ "b/md/\345\205\263\344\272\216Spring\344\270\255\347\232\204\345\217\202\346\225\260\346\240\241\351\252\214\347\232\204\344\270\200\347\202\271\346\200\235\350\200\203.md" @@ -0,0 +1,348 @@ +数据的校验的重要性就不用说了,即使在前端对数据进行校验的情况下,我们还是要对传入后端的数据再进行一遍校验,避免用户绕过浏览器直接通过一些 HTTP 工具直接向后端请求一些违法数据。 + +## 基础知识和依赖 + +### 相关依赖 + +如果开发普通 Java 程序的的话,你需要可能需要像下面这样依赖: + +```xml + + org.hibernate.validator + hibernate-validator + 6.0.9.Final + + + javax.el + javax.el-api + 3.0.0 + + + org.glassfish.web + javax.el + 2.2.6 + +``` + +使用 Spring Boot 程序的话只需要`spring-boot-starter-web` 就够了,它的子依赖包含了我们所需要的东西。 + +> spring-boot-devtools 是为了热部署使用。热部署可以简单的这样理解:我们修改程序代码后不需要重新启动程序,就可以获取到最新的代码,更新程序对外的行为。 SpringBoot 提供了 spring-boot-devtools 实现简单的热部署 + +```xml + + + org.springframework.boot + spring-boot-starter-web + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + +``` + +### 示例用到的实体类 + +```java +@Data +@AllArgsConstructor +@NoArgsConstructor +public class Person { + + @NotNull(message = "classId 不能为空") + private String classId; + + @Size(max = 33) + @NotNull(message = "name 不能为空") + private String name; + + @Pattern(regexp = "((^Man$|^Woman$|^UGM$))", message = "sex 值不在可选范围") + @NotNull(message = "sex 不能为空") + private String sex; + + @Email(message = "email 格式不正确") + @NotNull(message = "email 不能为空") + private String email; + +} +``` + +> 正则表达式说明: +> +> ``` +> - ^string : 匹配以 string 开头的字符串 +> - string$ :匹配以 string 结尾的字符串 +> - ^string$ :精确匹配 string 字符串 +> - ((^Man$|^Woman$|^UGM$)) : 值只能在 Man,Woman,UGM 这三个值中选择 +> ``` + +下面这部分校验注解说明内容参考自:https://www.cnkirito.moe/spring-validation/ ,感谢@[徐靖峰](https://github.com/lexburner)。 + +**JSR提供的校验注解**: + + +- `@Null` 被注释的元素必须为 null +- `@NotNull` 被注释的元素必须不为 null +- `@AssertTrue` 被注释的元素必须为 true +- `@AssertFalse` 被注释的元素必须为 false +- `@Min(value) ` 被注释的元素必须是一个数字,其值必须大于等于指定的最小值 +- `@Max(value) ` 被注释的元素必须是一个数字,其值必须小于等于指定的最大值 +- `@DecimalMin(value) ` 被注释的元素必须是一个数字,其值必须大于等于指定的最小值 +- `@DecimalMax(value)` 被注释的元素必须是一个数字,其值必须小于等于指定的最大值 +- `@Size(max=, min=) ` 被注释的元素的大小必须在指定的范围内 +- `@Digits (integer, fraction) ` 被注释的元素必须是一个数字,其值必须在可接受的范围内 +- `@Past ` 被注释的元素必须是一个过去的日期 +- `@Future` 被注释的元素必须是一个将来的日期 +- `@Pattern(regex=,flag=) ` 被注释的元素必须符合指定的正则表达式 + + +**Hibernate Validator提供的校验注解**: + + +- `@NotBlank(message =) ` 验证字符串非null,且长度必须大于0 +- `@Email` 被注释的元素必须是电子邮箱地址 +- `@Length(min=,max=) ` 被注释的字符串的大小必须在指定的范围内 +- `@NotEmpty ` 被注释的字符串的必须非空 +- `@Range(min=,max=,message=)` 被注释的元素必须在合适的范围内 + +## 验证请求体(RequestBody) + +### Controller + +我们在需要验证的参数上加上了`@Valid`注解,如果验证失败,它将抛出`MethodArgumentNotValidException`。默认情况下,Spring会将此异常转换为HTTP状态400(错误请求)。 + +```java + +@RestController +@RequestMapping("/api") +public class PersonController { + + @PostMapping("/person") + public ResponseEntity getPerson(@RequestBody @Valid Person person) { + return ResponseEntity.ok().body(person); + } +} +``` + +### ExceptionHandler + +自定义异常处理器可以帮助我们捕获异常,并进行一些简单的处理。 + +```java +@ControllerAdvice(assignableTypes = {PersonController.class}) +public class GlobalExceptionHandler { + @ExceptionHandler(MethodArgumentNotValidException.class) + public ResponseEntity> handleValidationExceptions( + MethodArgumentNotValidException ex) { + Map errors = new HashMap<>(); + ex.getBindingResult().getAllErrors().forEach((error) -> { + String fieldName = ((FieldError) error).getField(); + String errorMessage = error.getDefaultMessage(); + errors.put(fieldName, errorMessage); + }); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errors); + } +} +``` + +### 通过测试验证 + +下面我通过 MockMvc 模拟请求 Controller 的方式来验证是否生效,当然你也可以通过 Postman 这种工具来验证。 + +我们试一下所有参数输入正确的情况。 + +```java +@RunWith(SpringRunner.class) +@SpringBootTest +@AutoConfigureMockMvc +public class PersonControllerTest { + @Autowired + private MockMvc mockMvc; + + @Autowired + private ObjectMapper objectMapper; + + @Test + public void should_get_person_correctly() throws Exception { + Person person = new Person(); + person.setName("SnailClimb"); + person.setSex("Man"); + person.setClassId("82938390"); + person.setEmail("Snailclimb@qq.com"); + + mockMvc.perform(post("/api/person") + .contentType(MediaType.APPLICATION_JSON_UTF8) + .content(objectMapper.writeValueAsString(person))) + .andExpect(MockMvcResultMatchers.jsonPath("name").value("SnailClimb")) + .andExpect(MockMvcResultMatchers.jsonPath("classId").value("82938390")) + .andExpect(MockMvcResultMatchers.jsonPath("sex").value("Man")) + .andExpect(MockMvcResultMatchers.jsonPath("email").value("Snailclimb@qq.com")); + } +} +``` + +验证出现参数不合法的情况抛出异常并且可以正确被捕获。 + +```java + @Test + public void should_check_person_value() throws Exception { + Person person = new Person(); + person.setSex("Man22"); + person.setClassId("82938390"); + person.setEmail("SnailClimb"); + + mockMvc.perform(post("/api/person") + .contentType(MediaType.APPLICATION_JSON_UTF8) + .content(objectMapper.writeValueAsString(person))) + .andExpect(MockMvcResultMatchers.jsonPath("sex").value("sex 值不在可选范围")) + .andExpect(MockMvcResultMatchers.jsonPath("name").value("name 不能为空")) + .andExpect(MockMvcResultMatchers.jsonPath("email").value("email 格式不正确")); + } +``` + +使用 Postman 验证结果如下: + +![Postman 验证结果](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-7/postman-validation.png) + +## 验证请求参数(Path Variables 和 Request Parameters) + +### Controller + +**一定一定不要忘记在类上加上 `Validated` 注解了,这个参数可以告诉 Spring 去校验方法参数。** + +```java +@RestController +@RequestMapping("/api") +@Validated +public class PersonController { + + @GetMapping("/person/{id}") + public ResponseEntity getPersonByID(@Valid @PathVariable("id") @Max(value = 5,message = "超过 id 的范围了") Integer id) { + return ResponseEntity.ok().body(id); + } + + @PutMapping("/person") + public ResponseEntity getPersonByName(@Valid @RequestParam("name") @Size(max = 6,message = "超过 name 的范围了") String name) { + return ResponseEntity.ok().body(name); + } +} + +``` + +### ExceptionHandler + +异常处理handler: + +```java + @ExceptionHandler(ConstraintViolationException.class) + ResponseEntity handleConstraintViolationException(ConstraintViolationException e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage()); + } +``` + +### 通过测试验证 + +```java + @Test + public void should_check_param_value() throws Exception { + + mockMvc.perform(get("/api/person/6") + .contentType(MediaType.APPLICATION_JSON_UTF8)) + .andExpect(status().isBadRequest()) + .andExpect(content().string("getPersonByID.id: 超过 id 的范围了")); + } + + @Test + public void should_check_param_value2() throws Exception { + + mockMvc.perform(put("/api/person") + .param("name","snailclimbsnailclimb") + .contentType(MediaType.APPLICATION_JSON_UTF8)) + .andExpect(status().isBadRequest()) + .andExpect(content().string("getPersonByName.name: 超过 name 的范围了")); + } +``` + +## 验证Service 中的方法 + +我们还可以验证任何Spring组件的输入,而不是验证控制器级别的输入。为此,我们使用`@Validated`和`@Valid`注释的组合。 + +```java +@Service +@Validated +public class PersonService { + + public void validatePerson(@Valid Person person){ + // do something + } +} +``` + +**通过测试验证:** + +```java +@RunWith(SpringRunner.class) +@SpringBootTest +@AutoConfigureMockMvc +public class PersonServiceTest { + @Autowired + private PersonService service; + + @Test(expected = ConstraintViolationException.class) + public void should_throw_exception_when_person_is_not_valid() { + Person person = new Person(); + person.setSex("Man22"); + person.setClassId("82938390"); + person.setEmail("SnailClimb"); + service.validatePerson(person); + } + +} +``` + + + +## Validator 编程方式手动进行参数验证 + +某些场景下可能会需要我们手动校验并获得校验结果。 + +```java + @Test + public void check_person_manually() { + + ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); + Validator validator = factory.getValidator(); + Person person = new Person(); + person.setSex("Man22"); + person.setClassId("82938390"); + person.setEmail("SnailClimb"); + Set> violations = validator.validate(person); + //output: + //email 格式不正确 + //name 不能为空 + //sex 值不在可选范围 + for (ConstraintViolation constraintViolation : violations) { + System.out.println(constraintViolation.getMessage()); + } + } +``` + +上面我们是通过 `Validator` 工厂类获得的 `Validator` 示例,当然你也可以通过 `@Autowired` 直接注入的方式。 + +```java +@Autowired +Validator validate +``` + + + +## 参考 + +- https://reflectoring.io/bean-validation-with-spring-boot/ +- https://www.cnkirito.moe/spring-validation/ \ No newline at end of file From 377bdfa009f7b8a2e0caea740043e81f84f92e68 Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Sun, 8 Sep 2019 16:24:02 +0800 Subject: [PATCH 025/204] =?UTF-8?q?Update=20=E5=85=B3=E4=BA=8ESpring?= =?UTF-8?q?=E4=B8=AD=E7=9A=84=E5=8F=82=E6=95=B0=E6=A0=A1=E9=AA=8C=E7=9A=84?= =?UTF-8?q?=E4=B8=80=E7=82=B9=E6=80=9D=E8=80=83.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...32\204\344\270\200\347\202\271\346\200\235\350\200\203.md" | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git "a/md/\345\205\263\344\272\216Spring\344\270\255\347\232\204\345\217\202\346\225\260\346\240\241\351\252\214\347\232\204\344\270\200\347\202\271\346\200\235\350\200\203.md" "b/md/\345\205\263\344\272\216Spring\344\270\255\347\232\204\345\217\202\346\225\260\346\240\241\351\252\214\347\232\204\344\270\200\347\202\271\346\200\235\350\200\203.md" index 381b8c9..50e390b 100644 --- "a/md/\345\205\263\344\272\216Spring\344\270\255\347\232\204\345\217\202\346\225\260\346\240\241\351\252\214\347\232\204\344\270\200\347\202\271\346\200\235\350\200\203.md" +++ "b/md/\345\205\263\344\272\216Spring\344\270\255\347\232\204\345\217\202\346\225\260\346\240\241\351\252\214\347\232\204\344\270\200\347\202\271\346\200\235\350\200\203.md" @@ -269,9 +269,9 @@ public class PersonController { } ``` -## 验证Service 中的方法 +## 验证 Service 中的方法 -我们还可以验证任何Spring组件的输入,而不是验证控制器级别的输入。为此,我们使用`@Validated`和`@Valid`注释的组合。 +我们还可以验证任何Spring组件的输入,而不是验证控制器级别的输入,我们可以使用`@Validated`和`@Valid`注释的组合来实现这一需求。 ```java @Service From 8ae8b613288e47c493bddb6d0c0b26dcf22676c8 Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Sun, 8 Sep 2019 16:34:35 +0800 Subject: [PATCH 026/204] =?UTF-8?q?Update=20=E5=85=B3=E4=BA=8ESpring?= =?UTF-8?q?=E4=B8=AD=E7=9A=84=E5=8F=82=E6=95=B0=E6=A0=A1=E9=AA=8C=E7=9A=84?= =?UTF-8?q?=E4=B8=80=E7=82=B9=E6=80=9D=E8=80=83.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...04\344\270\200\347\202\271\346\200\235\350\200\203.md" | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git "a/md/\345\205\263\344\272\216Spring\344\270\255\347\232\204\345\217\202\346\225\260\346\240\241\351\252\214\347\232\204\344\270\200\347\202\271\346\200\235\350\200\203.md" "b/md/\345\205\263\344\272\216Spring\344\270\255\347\232\204\345\217\202\346\225\260\346\240\241\351\252\214\347\232\204\344\270\200\347\202\271\346\200\235\350\200\203.md" index 50e390b..6249b3a 100644 --- "a/md/\345\205\263\344\272\216Spring\344\270\255\347\232\204\345\217\202\346\225\260\346\240\241\351\252\214\347\232\204\344\270\200\347\202\271\346\200\235\350\200\203.md" +++ "b/md/\345\205\263\344\272\216Spring\344\270\255\347\232\204\345\217\202\346\225\260\346\240\241\351\252\214\347\232\204\344\270\200\347\202\271\346\200\235\350\200\203.md" @@ -1,5 +1,13 @@ +## TODO + +1. 自定以验证器(Implementing A Custom Validator) +2. Using Validation Groups to Validate Objects Differently for Different Use Cases +3. 原理分析 + 数据的校验的重要性就不用说了,即使在前端对数据进行校验的情况下,我们还是要对传入后端的数据再进行一遍校验,避免用户绕过浏览器直接通过一些 HTTP 工具直接向后端请求一些违法数据。 +下面我如何在 Java 程序中尤其是 Spring 程序中优雅地的进行参数验证。 + ## 基础知识和依赖 ### 相关依赖 From dcbaeecd61a289cf10a5879ba7ef9799f5f1f54f Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Sun, 8 Sep 2019 23:03:42 +0800 Subject: [PATCH 027/204] Update README.md --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 282b93d..cd71aaa 100644 --- a/README.md +++ b/README.md @@ -8,8 +8,6 @@ - [SpringBoot+阿里云OSS 存储服务](#springboot阿里云oss-存储服务) - [springboot-dubbo(使用SpringBoot+Dubbo 搭建一个分布式服务)](#springboot-dubbo使用springbootdubbo-搭建一个分布式服务) - - ## 重要知识点 - [RestController VS Controller](./md/RestControllerVSController.md) From b9d4ecf1fe59302f71e94c780868601794bab0ae Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Tue, 10 Sep 2019 14:33:55 +0800 Subject: [PATCH 028/204] =?UTF-8?q?Update=20=E5=85=B3=E4=BA=8ESpring?= =?UTF-8?q?=E4=B8=AD=E7=9A=84=E5=8F=82=E6=95=B0=E6=A0=A1=E9=AA=8C=E7=9A=84?= =?UTF-8?q?=E4=B8=80=E7=82=B9=E6=80=9D=E8=80=83.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...4\344\270\200\347\202\271\346\200\235\350\200\203.md" | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git "a/md/\345\205\263\344\272\216Spring\344\270\255\347\232\204\345\217\202\346\225\260\346\240\241\351\252\214\347\232\204\344\270\200\347\202\271\346\200\235\350\200\203.md" "b/md/\345\205\263\344\272\216Spring\344\270\255\347\232\204\345\217\202\346\225\260\346\240\241\351\252\214\347\232\204\344\270\200\347\202\271\346\200\235\350\200\203.md" index 6249b3a..7a7aed9 100644 --- "a/md/\345\205\263\344\272\216Spring\344\270\255\347\232\204\345\217\202\346\225\260\346\240\241\351\252\214\347\232\204\344\270\200\347\202\271\346\200\235\350\200\203.md" +++ "b/md/\345\205\263\344\272\216Spring\344\270\255\347\232\204\345\217\202\346\225\260\346\240\241\351\252\214\347\232\204\344\270\200\347\202\271\346\200\235\350\200\203.md" @@ -1,8 +1,7 @@ ## TODO -1. 自定以验证器(Implementing A Custom Validator) -2. Using Validation Groups to Validate Objects Differently for Different Use Cases -3. 原理分析 +1. Using Validation Groups to Validate Objects Differently for Different Use Cases +2. 原理分析 数据的校验的重要性就不用说了,即使在前端对数据进行校验的情况下,我们还是要对传入后端的数据再进行一遍校验,避免用户绕过浏览器直接通过一些 HTTP 工具直接向后端请求一些违法数据。 @@ -348,7 +347,9 @@ public class PersonServiceTest { Validator validate ``` - +## 自定以验证器 + + ## 参考 From 0079d4b2f42da1b0ce1e701b4757b1094ead7f3f Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Tue, 10 Sep 2019 16:23:17 +0800 Subject: [PATCH 029/204] =?UTF-8?q?Update=20=E5=85=B3=E4=BA=8ESpring?= =?UTF-8?q?=E4=B8=AD=E7=9A=84=E5=8F=82=E6=95=B0=E6=A0=A1=E9=AA=8C=E7=9A=84?= =?UTF-8?q?=E4=B8=80=E7=82=B9=E6=80=9D=E8=80=83.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...00\347\202\271\346\200\235\350\200\203.md" | 116 +++++++++++++++++- 1 file changed, 114 insertions(+), 2 deletions(-) diff --git "a/md/\345\205\263\344\272\216Spring\344\270\255\347\232\204\345\217\202\346\225\260\346\240\241\351\252\214\347\232\204\344\270\200\347\202\271\346\200\235\350\200\203.md" "b/md/\345\205\263\344\272\216Spring\344\270\255\347\232\204\345\217\202\346\225\260\346\240\241\351\252\214\347\232\204\344\270\200\347\202\271\346\200\235\350\200\203.md" index 7a7aed9..85f5027 100644 --- "a/md/\345\205\263\344\272\216Spring\344\270\255\347\232\204\345\217\202\346\225\260\346\240\241\351\252\214\347\232\204\344\270\200\347\202\271\346\200\235\350\200\203.md" +++ "b/md/\345\205\263\344\272\216Spring\344\270\255\347\232\204\345\217\202\346\225\260\346\240\241\351\252\214\347\232\204\344\270\200\347\202\271\346\200\235\350\200\203.md" @@ -280,6 +280,8 @@ public class PersonController { 我们还可以验证任何Spring组件的输入,而不是验证控制器级别的输入,我们可以使用`@Validated`和`@Valid`注释的组合来实现这一需求。 +**一定一定不要忘记在类上加上 `Validated` 注解了,这个参数可以告诉 Spring 去校验方法参数。** + ```java @Service @Validated @@ -313,8 +315,6 @@ public class PersonServiceTest { } ``` - - ## Validator 编程方式手动进行参数验证 某些场景下可能会需要我们手动校验并获得校验结果。 @@ -349,7 +349,119 @@ Validator validate ## 自定以验证器 +如果自带的校验注解无法满足你的需求的话,你还可以自定义实现注解。比如我们的Person类多了一个 region 字段,region 字段只能是`China`、`China-Taiwan`、`China-HongKong`这三个中的一个。 + +第一步你需要创建一个注解: + +```java +@Target({FIELD}) +@Retention(RUNTIME) +@Constraint(validatedBy = RegionValidator.class) +@Documented +public @interface Region { + + String message() default "Region 值不在可选范围内"; + + Class[] groups() default {}; + + Class[] payload() default {}; +} +``` + +第二步你需要实现 `ConstraintValidator`接口,并重写`isValid` 方法: + +```java +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; +import java.util.HashSet; + +public class RegionValidator implements ConstraintValidator { + + @Override + public boolean isValid(String value, ConstraintValidatorContext context) { + HashSet regions = new HashSet<>(); + regions.add("China"); + regions.add("China-Taiwan"); + regions.add("China-HongKong"); + return regions.contains(value); + } +} + +``` + +现在你就可以使用这个注解: + +```java + @Region + private String region; +``` + +## 使用验证组 + +很多时候我们需要使用到验证组,这样说可能不太清楚,说简单点就是对对象操作的不同方法有不同的验证规则,示例如下。 + +先创建两个接口: + +```java +public interface AddPersonGroup { +} +public interface DeletePersonGroup { +} +``` +我们可以这样去使用验证组 + +```java +@NotNull(groups = DeletePersonGroup.class) +@Null(groups = AddPersonGroup.class) +private String group; +``` + +```java +@Service +@Validated +public class PersonService { + + public void validatePerson(@Valid Person person) { + // do something + } + + @Validated(AddPersonGroup.class) + public void validatePersonGroupForAdd(@Valid Person person) { + // do something + } + + @Validated(DeletePersonGroup.class) + public void validatePersonGroupForDelete(@Valid Person person) { + // do something + } + +} +``` + +通过测试验证: + +```java + @Test(expected = ConstraintViolationException.class) + public void should_check_person_with_groups() { + Person person = new Person(); + person.setSex("Man22"); + person.setClassId("82938390"); + person.setEmail("SnailClimb"); + person.setGroup("group1"); + service.validatePersonGroupForAdd(person); + } + + @Test(expected = ConstraintViolationException.class) + public void should_check_person_with_groups2() { + Person person = new Person(); + person.setSex("Man22"); + person.setClassId("82938390"); + person.setEmail("SnailClimb"); + service.validatePersonGroupForDelete(person); + } +``` +使用验证组这种方式的时候一定要小心,这是一种反模式,还会造成代码逻辑性变差。 ## 参考 From bd2aae00668abc81968a76701a6bc12779dac21f Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Tue, 10 Sep 2019 16:33:42 +0800 Subject: [PATCH 030/204] =?UTF-8?q?Update=20=E5=85=B3=E4=BA=8ESpring?= =?UTF-8?q?=E4=B8=AD=E7=9A=84=E5=8F=82=E6=95=B0=E6=A0=A1=E9=AA=8C=E7=9A=84?= =?UTF-8?q?=E4=B8=80=E7=82=B9=E6=80=9D=E8=80=83.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...00\347\202\271\346\200\235\350\200\203.md" | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git "a/md/\345\205\263\344\272\216Spring\344\270\255\347\232\204\345\217\202\346\225\260\346\240\241\351\252\214\347\232\204\344\270\200\347\202\271\346\200\235\350\200\203.md" "b/md/\345\205\263\344\272\216Spring\344\270\255\347\232\204\345\217\202\346\225\260\346\240\241\351\252\214\347\232\204\344\270\200\347\202\271\346\200\235\350\200\203.md" index 85f5027..496d932 100644 --- "a/md/\345\205\263\344\272\216Spring\344\270\255\347\232\204\345\217\202\346\225\260\346\240\241\351\252\214\347\232\204\344\270\200\347\202\271\346\200\235\350\200\203.md" +++ "b/md/\345\205\263\344\272\216Spring\344\270\255\347\232\204\345\217\202\346\225\260\346\240\241\351\252\214\347\232\204\344\270\200\347\202\271\346\200\235\350\200\203.md" @@ -1,11 +1,6 @@ -## TODO - -1. Using Validation Groups to Validate Objects Differently for Different Use Cases -2. 原理分析 - 数据的校验的重要性就不用说了,即使在前端对数据进行校验的情况下,我们还是要对传入后端的数据再进行一遍校验,避免用户绕过浏览器直接通过一些 HTTP 工具直接向后端请求一些违法数据。 -下面我如何在 Java 程序中尤其是 Spring 程序中优雅地的进行参数验证。 +下面我会通过实例程序演示如何在 Java 程序中尤其是 Spring 程序中优雅地的进行参数验证。 ## 基础知识和依赖 @@ -31,9 +26,7 @@ ``` -使用 Spring Boot 程序的话只需要`spring-boot-starter-web` 就够了,它的子依赖包含了我们所需要的东西。 - -> spring-boot-devtools 是为了热部署使用。热部署可以简单的这样理解:我们修改程序代码后不需要重新启动程序,就可以获取到最新的代码,更新程序对外的行为。 SpringBoot 提供了 spring-boot-devtools 实现简单的热部署 +使用 Spring Boot 程序的话只需要`spring-boot-starter-web` 就够了,它的子依赖包含了我们所需要的东西。除了这个依赖,下面的演示还用到了 lombok ,所以不要忘记添加上相关依赖。 ```xml @@ -54,7 +47,9 @@ ``` -### 示例用到的实体类 +### 实体类 + +下面这个是示例用到的实体类。 ```java @Data @@ -122,7 +117,7 @@ public class Person { ### Controller -我们在需要验证的参数上加上了`@Valid`注解,如果验证失败,它将抛出`MethodArgumentNotValidException`。默认情况下,Spring会将此异常转换为HTTP状态400(错误请求)。 +我们在需要验证的参数上加上了`@Valid`注解,如果验证失败,它将抛出`MethodArgumentNotValidException`。默认情况下,Spring会将此异常转换为HTTP Status 400(错误请求)。 ```java @@ -139,7 +134,7 @@ public class PersonController { ### ExceptionHandler -自定义异常处理器可以帮助我们捕获异常,并进行一些简单的处理。 +自定义异常处理器可以帮助我们捕获异常,并进行一些简单的处理。如果对于下面的处理异常的代码不太理解的话,可以查看这篇文章 [《SpringBoot 处理异常的几种常见姿势》](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247485568&idx=2&sn=c5ba880fd0c5d82e39531fa42cb036ac&chksm=cea2474bf9d5ce5dcbc6a5f6580198fdce4bc92ef577579183a729cb5d1430e4994720d59b34&token=1924773784&lang=zh_CN#rd)。 ```java @ControllerAdvice(assignableTypes = {PersonController.class}) @@ -340,14 +335,14 @@ public class PersonServiceTest { } ``` -上面我们是通过 `Validator` 工厂类获得的 `Validator` 示例,当然你也可以通过 `@Autowired` 直接注入的方式。 +上面我们是通过 `Validator` 工厂类获得的 `Validator` 示例,当然你也可以通过 `@Autowired` 直接注入的方式。但是在非 Spring Component 类中使用这种方式的话,只能通过工厂类来获得 `Validator`。 ```java @Autowired Validator validate ``` -## 自定以验证器 +## 自定以 Validator 如果自带的校验注解无法满足你的需求的话,你还可以自定义实现注解。比如我们的Person类多了一个 region 字段,region 字段只能是`China`、`China-Taiwan`、`China-HongKong`这三个中的一个。 @@ -463,6 +458,10 @@ public class PersonService { 使用验证组这种方式的时候一定要小心,这是一种反模式,还会造成代码逻辑性变差。 +## TODO + +- [ ] 原理分析 + ## 参考 - https://reflectoring.io/bean-validation-with-spring-boot/ From e8754c92c8ec4217c01c04b5f4857758fe94db66 Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Tue, 10 Sep 2019 16:37:40 +0800 Subject: [PATCH 031/204] =?UTF-8?q?Update=20=E5=85=B3=E4=BA=8ESpring?= =?UTF-8?q?=E4=B8=AD=E7=9A=84=E5=8F=82=E6=95=B0=E6=A0=A1=E9=AA=8C=E7=9A=84?= =?UTF-8?q?=E4=B8=80=E7=82=B9=E6=80=9D=E8=80=83.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...00\347\202\271\346\200\235\350\200\203.md" | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git "a/md/\345\205\263\344\272\216Spring\344\270\255\347\232\204\345\217\202\346\225\260\346\240\241\351\252\214\347\232\204\344\270\200\347\202\271\346\200\235\350\200\203.md" "b/md/\345\205\263\344\272\216Spring\344\270\255\347\232\204\345\217\202\346\225\260\346\240\241\351\252\214\347\232\204\344\270\200\347\202\271\346\200\235\350\200\203.md" index 496d932..0a5b7b8 100644 --- "a/md/\345\205\263\344\272\216Spring\344\270\255\347\232\204\345\217\202\346\225\260\346\240\241\351\252\214\347\232\204\344\270\200\347\202\271\346\200\235\350\200\203.md" +++ "b/md/\345\205\263\344\272\216Spring\344\270\255\347\232\204\345\217\202\346\225\260\346\240\241\351\252\214\347\232\204\344\270\200\347\202\271\346\200\235\350\200\203.md" @@ -113,9 +113,11 @@ public class Person { - `@NotEmpty ` 被注释的字符串的必须非空 - `@Range(min=,max=,message=)` 被注释的元素必须在合适的范围内 -## 验证请求体(RequestBody) +## 验证Controller的输入 -### Controller +### 验证请求体(RequestBody) + +**Controller:** 我们在需要验证的参数上加上了`@Valid`注解,如果验证失败,它将抛出`MethodArgumentNotValidException`。默认情况下,Spring会将此异常转换为HTTP Status 400(错误请求)。 @@ -132,7 +134,7 @@ public class PersonController { } ``` -### ExceptionHandler +**ExceptionHandler:** 自定义异常处理器可以帮助我们捕获异常,并进行一些简单的处理。如果对于下面的处理异常的代码不太理解的话,可以查看这篇文章 [《SpringBoot 处理异常的几种常见姿势》](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247485568&idx=2&sn=c5ba880fd0c5d82e39531fa42cb036ac&chksm=cea2474bf9d5ce5dcbc6a5f6580198fdce4bc92ef577579183a729cb5d1430e4994720d59b34&token=1924773784&lang=zh_CN#rd)。 @@ -153,7 +155,7 @@ public class GlobalExceptionHandler { } ``` -### 通过测试验证 +**通过测试验证:** 下面我通过 MockMvc 模拟请求 Controller 的方式来验证是否生效,当然你也可以通过 Postman 这种工具来验证。 @@ -212,9 +214,9 @@ public class PersonControllerTest { ![Postman 验证结果](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-7/postman-validation.png) -## 验证请求参数(Path Variables 和 Request Parameters) +### 验证请求参数(Path Variables 和 Request Parameters) -### Controller +**Controller:** **一定一定不要忘记在类上加上 `Validated` 注解了,这个参数可以告诉 Spring 去校验方法参数。** @@ -237,9 +239,7 @@ public class PersonController { ``` -### ExceptionHandler - -异常处理handler: +**ExceptionHandler:** ```java @ExceptionHandler(ConstraintViolationException.class) @@ -248,7 +248,7 @@ public class PersonController { } ``` -### 通过测试验证 +**通过测试验证:** ```java @Test From 84748f57d040342ece69ba7bdc132ddfcf8c6275 Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Tue, 10 Sep 2019 16:51:00 +0800 Subject: [PATCH 032/204] =?UTF-8?q?Update=20=E5=85=B3=E4=BA=8ESpring?= =?UTF-8?q?=E4=B8=AD=E7=9A=84=E5=8F=82=E6=95=B0=E6=A0=A1=E9=AA=8C=E7=9A=84?= =?UTF-8?q?=E4=B8=80=E7=82=B9=E6=80=9D=E8=80=83.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...7\232\204\344\270\200\347\202\271\346\200\235\350\200\203.md" | 1 + 1 file changed, 1 insertion(+) diff --git "a/md/\345\205\263\344\272\216Spring\344\270\255\347\232\204\345\217\202\346\225\260\346\240\241\351\252\214\347\232\204\344\270\200\347\202\271\346\200\235\350\200\203.md" "b/md/\345\205\263\344\272\216Spring\344\270\255\347\232\204\345\217\202\346\225\260\346\240\241\351\252\214\347\232\204\344\270\200\347\202\271\346\200\235\350\200\203.md" index 0a5b7b8..42ec3c1 100644 --- "a/md/\345\205\263\344\272\216Spring\344\270\255\347\232\204\345\217\202\346\225\260\346\240\241\351\252\214\347\232\204\344\270\200\347\202\271\346\200\235\350\200\203.md" +++ "b/md/\345\205\263\344\272\216Spring\344\270\255\347\232\204\345\217\202\346\225\260\346\240\241\351\252\214\347\232\204\344\270\200\347\202\271\346\200\235\350\200\203.md" @@ -460,6 +460,7 @@ public class PersonService { ## TODO +- [ ] JPA 数据库级别参数约束验证 - [ ] 原理分析 ## 参考 From 1fdfa0a5a93aa200ed12f1f3eee10b1f028c57a0 Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Tue, 10 Sep 2019 17:03:05 +0800 Subject: [PATCH 033/204] Create spring-bean-validation.md --- md/spring-bean-validation.md | 482 +++++++++++++++++++++++++++++++++++ 1 file changed, 482 insertions(+) create mode 100644 md/spring-bean-validation.md diff --git a/md/spring-bean-validation.md b/md/spring-bean-validation.md new file mode 100644 index 0000000..d88bcfa --- /dev/null +++ b/md/spring-bean-validation.md @@ -0,0 +1,482 @@ +数据的校验的重要性就不用说了,即使在前端对数据进行校验的情况下,我们还是要对传入后端的数据再进行一遍校验,避免用户绕过浏览器直接通过一些 HTTP 工具直接向后端请求一些违法数据。 + +下面我会通过实例程序演示如何在 Java 程序中尤其是 Spring 程序中优雅地的进行参数验证。 + +- [基础知识和依赖](#基础知识和依赖) + - [相关依赖](#相关依赖) + - [实体类](#实体类) +- [验证Controller的输入](#验证controller的输入) + - [验证请求体(RequestBody)](#验证请求体requestbody) + - [验证请求参数(Path Variables 和 Request Parameters)](#验证请求参数path-variables-和-request-parameters) +- [验证 Service 中的方法](#验证-service-中的方法) +- [Validator 编程方式手动进行参数验证](#validator-编程方式手动进行参数验证) +- [自定以 Validator](#自定以-validator) +- [使用验证组](#使用验证组) +- [TODO](#todo) +- [参考](#参考) + +## 基础知识和依赖 + +### 相关依赖 + +如果开发普通 Java 程序的的话,你需要可能需要像下面这样依赖: + +```xml + + org.hibernate.validator + hibernate-validator + 6.0.9.Final + + + javax.el + javax.el-api + 3.0.0 + + + org.glassfish.web + javax.el + 2.2.6 + +``` + +使用 Spring Boot 程序的话只需要`spring-boot-starter-web` 就够了,它的子依赖包含了我们所需要的东西。除了这个依赖,下面的演示还用到了 lombok ,所以不要忘记添加上相关依赖。 + +```xml + + + org.springframework.boot + spring-boot-starter-web + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + +``` + +### 实体类 + +下面这个是示例用到的实体类。 + +```java +@Data +@AllArgsConstructor +@NoArgsConstructor +public class Person { + + @NotNull(message = "classId 不能为空") + private String classId; + + @Size(max = 33) + @NotNull(message = "name 不能为空") + private String name; + + @Pattern(regexp = "((^Man$|^Woman$|^UGM$))", message = "sex 值不在可选范围") + @NotNull(message = "sex 不能为空") + private String sex; + + @Email(message = "email 格式不正确") + @NotNull(message = "email 不能为空") + private String email; + +} +``` + +> 正则表达式说明: +> +> ``` +> - ^string : 匹配以 string 开头的字符串 +> - string$ :匹配以 string 结尾的字符串 +> - ^string$ :精确匹配 string 字符串 +> - ((^Man$|^Woman$|^UGM$)) : 值只能在 Man,Woman,UGM 这三个值中选择 +> ``` + +下面这部分校验注解说明内容参考自:https://www.cnkirito.moe/spring-validation/ ,感谢@[徐靖峰](https://github.com/lexburner)。 + +**JSR提供的校验注解**: + + +- `@Null` 被注释的元素必须为 null +- `@NotNull` 被注释的元素必须不为 null +- `@AssertTrue` 被注释的元素必须为 true +- `@AssertFalse` 被注释的元素必须为 false +- `@Min(value) ` 被注释的元素必须是一个数字,其值必须大于等于指定的最小值 +- `@Max(value) ` 被注释的元素必须是一个数字,其值必须小于等于指定的最大值 +- `@DecimalMin(value) ` 被注释的元素必须是一个数字,其值必须大于等于指定的最小值 +- `@DecimalMax(value)` 被注释的元素必须是一个数字,其值必须小于等于指定的最大值 +- `@Size(max=, min=) ` 被注释的元素的大小必须在指定的范围内 +- `@Digits (integer, fraction) ` 被注释的元素必须是一个数字,其值必须在可接受的范围内 +- `@Past ` 被注释的元素必须是一个过去的日期 +- `@Future` 被注释的元素必须是一个将来的日期 +- `@Pattern(regex=,flag=) ` 被注释的元素必须符合指定的正则表达式 + + +**Hibernate Validator提供的校验注解**: + + +- `@NotBlank(message =) ` 验证字符串非null,且长度必须大于0 +- `@Email` 被注释的元素必须是电子邮箱地址 +- `@Length(min=,max=) ` 被注释的字符串的大小必须在指定的范围内 +- `@NotEmpty ` 被注释的字符串的必须非空 +- `@Range(min=,max=,message=)` 被注释的元素必须在合适的范围内 + +## 验证Controller的输入 + +### 验证请求体(RequestBody) + +**Controller:** + +我们在需要验证的参数上加上了`@Valid`注解,如果验证失败,它将抛出`MethodArgumentNotValidException`。默认情况下,Spring会将此异常转换为HTTP Status 400(错误请求)。 + +```java + +@RestController +@RequestMapping("/api") +public class PersonController { + + @PostMapping("/person") + public ResponseEntity getPerson(@RequestBody @Valid Person person) { + return ResponseEntity.ok().body(person); + } +} +``` + +**ExceptionHandler:** + +自定义异常处理器可以帮助我们捕获异常,并进行一些简单的处理。如果对于下面的处理异常的代码不太理解的话,可以查看这篇文章 [《SpringBoot 处理异常的几种常见姿势》](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247485568&idx=2&sn=c5ba880fd0c5d82e39531fa42cb036ac&chksm=cea2474bf9d5ce5dcbc6a5f6580198fdce4bc92ef577579183a729cb5d1430e4994720d59b34&token=1924773784&lang=zh_CN#rd)。 + +```java +@ControllerAdvice(assignableTypes = {PersonController.class}) +public class GlobalExceptionHandler { + @ExceptionHandler(MethodArgumentNotValidException.class) + public ResponseEntity> handleValidationExceptions( + MethodArgumentNotValidException ex) { + Map errors = new HashMap<>(); + ex.getBindingResult().getAllErrors().forEach((error) -> { + String fieldName = ((FieldError) error).getField(); + String errorMessage = error.getDefaultMessage(); + errors.put(fieldName, errorMessage); + }); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errors); + } +} +``` + +**通过测试验证:** + +下面我通过 MockMvc 模拟请求 Controller 的方式来验证是否生效,当然你也可以通过 Postman 这种工具来验证。 + +我们试一下所有参数输入正确的情况。 + +```java +@RunWith(SpringRunner.class) +@SpringBootTest +@AutoConfigureMockMvc +public class PersonControllerTest { + @Autowired + private MockMvc mockMvc; + + @Autowired + private ObjectMapper objectMapper; + + @Test + public void should_get_person_correctly() throws Exception { + Person person = new Person(); + person.setName("SnailClimb"); + person.setSex("Man"); + person.setClassId("82938390"); + person.setEmail("Snailclimb@qq.com"); + + mockMvc.perform(post("/api/person") + .contentType(MediaType.APPLICATION_JSON_UTF8) + .content(objectMapper.writeValueAsString(person))) + .andExpect(MockMvcResultMatchers.jsonPath("name").value("SnailClimb")) + .andExpect(MockMvcResultMatchers.jsonPath("classId").value("82938390")) + .andExpect(MockMvcResultMatchers.jsonPath("sex").value("Man")) + .andExpect(MockMvcResultMatchers.jsonPath("email").value("Snailclimb@qq.com")); + } +} +``` + +验证出现参数不合法的情况抛出异常并且可以正确被捕获。 + +```java + @Test + public void should_check_person_value() throws Exception { + Person person = new Person(); + person.setSex("Man22"); + person.setClassId("82938390"); + person.setEmail("SnailClimb"); + + mockMvc.perform(post("/api/person") + .contentType(MediaType.APPLICATION_JSON_UTF8) + .content(objectMapper.writeValueAsString(person))) + .andExpect(MockMvcResultMatchers.jsonPath("sex").value("sex 值不在可选范围")) + .andExpect(MockMvcResultMatchers.jsonPath("name").value("name 不能为空")) + .andExpect(MockMvcResultMatchers.jsonPath("email").value("email 格式不正确")); + } +``` + +使用 Postman 验证结果如下: + +![Postman 验证结果](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-7/postman-validation.png) + +### 验证请求参数(Path Variables 和 Request Parameters) + +**Controller:** + +**一定一定不要忘记在类上加上 `Validated` 注解了,这个参数可以告诉 Spring 去校验方法参数。** + +```java +@RestController +@RequestMapping("/api") +@Validated +public class PersonController { + + @GetMapping("/person/{id}") + public ResponseEntity getPersonByID(@Valid @PathVariable("id") @Max(value = 5,message = "超过 id 的范围了") Integer id) { + return ResponseEntity.ok().body(id); + } + + @PutMapping("/person") + public ResponseEntity getPersonByName(@Valid @RequestParam("name") @Size(max = 6,message = "超过 name 的范围了") String name) { + return ResponseEntity.ok().body(name); + } +} + +``` + +**ExceptionHandler:** + +```java + @ExceptionHandler(ConstraintViolationException.class) + ResponseEntity handleConstraintViolationException(ConstraintViolationException e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage()); + } +``` + +**通过测试验证:** + +```java + @Test + public void should_check_param_value() throws Exception { + + mockMvc.perform(get("/api/person/6") + .contentType(MediaType.APPLICATION_JSON_UTF8)) + .andExpect(status().isBadRequest()) + .andExpect(content().string("getPersonByID.id: 超过 id 的范围了")); + } + + @Test + public void should_check_param_value2() throws Exception { + + mockMvc.perform(put("/api/person") + .param("name","snailclimbsnailclimb") + .contentType(MediaType.APPLICATION_JSON_UTF8)) + .andExpect(status().isBadRequest()) + .andExpect(content().string("getPersonByName.name: 超过 name 的范围了")); + } +``` + +## 验证 Service 中的方法 + +我们还可以验证任何Spring组件的输入,而不是验证控制器级别的输入,我们可以使用`@Validated`和`@Valid`注释的组合来实现这一需求。 + +**一定一定不要忘记在类上加上 `Validated` 注解了,这个参数可以告诉 Spring 去校验方法参数。** + +```java +@Service +@Validated +public class PersonService { + + public void validatePerson(@Valid Person person){ + // do something + } +} +``` + +**通过测试验证:** + +```java +@RunWith(SpringRunner.class) +@SpringBootTest +@AutoConfigureMockMvc +public class PersonServiceTest { + @Autowired + private PersonService service; + + @Test(expected = ConstraintViolationException.class) + public void should_throw_exception_when_person_is_not_valid() { + Person person = new Person(); + person.setSex("Man22"); + person.setClassId("82938390"); + person.setEmail("SnailClimb"); + service.validatePerson(person); + } + +} +``` + +## Validator 编程方式手动进行参数验证 + +某些场景下可能会需要我们手动校验并获得校验结果。 + +```java + @Test + public void check_person_manually() { + + ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); + Validator validator = factory.getValidator(); + Person person = new Person(); + person.setSex("Man22"); + person.setClassId("82938390"); + person.setEmail("SnailClimb"); + Set> violations = validator.validate(person); + //output: + //email 格式不正确 + //name 不能为空 + //sex 值不在可选范围 + for (ConstraintViolation constraintViolation : violations) { + System.out.println(constraintViolation.getMessage()); + } + } +``` + +上面我们是通过 `Validator` 工厂类获得的 `Validator` 示例,当然你也可以通过 `@Autowired` 直接注入的方式。但是在非 Spring Component 类中使用这种方式的话,只能通过工厂类来获得 `Validator`。 + +```java +@Autowired +Validator validate +``` + +## 自定以 Validator + +如果自带的校验注解无法满足你的需求的话,你还可以自定义实现注解。比如我们的Person类多了一个 region 字段,region 字段只能是`China`、`China-Taiwan`、`China-HongKong`这三个中的一个。 + +第一步你需要创建一个注解: + +```java +@Target({FIELD}) +@Retention(RUNTIME) +@Constraint(validatedBy = RegionValidator.class) +@Documented +public @interface Region { + + String message() default "Region 值不在可选范围内"; + + Class[] groups() default {}; + + Class[] payload() default {}; +} +``` + +第二步你需要实现 `ConstraintValidator`接口,并重写`isValid` 方法: + +```java +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; +import java.util.HashSet; + +public class RegionValidator implements ConstraintValidator { + + @Override + public boolean isValid(String value, ConstraintValidatorContext context) { + HashSet regions = new HashSet<>(); + regions.add("China"); + regions.add("China-Taiwan"); + regions.add("China-HongKong"); + return regions.contains(value); + } +} + +``` + +现在你就可以使用这个注解: + +```java + @Region + private String region; +``` + +## 使用验证组 + +很多时候我们需要使用到验证组,这样说可能不太清楚,说简单点就是对对象操作的不同方法有不同的验证规则,示例如下。 + +先创建两个接口: + +```java +public interface AddPersonGroup { +} +public interface DeletePersonGroup { +} +``` +我们可以这样去使用验证组 + +```java +@NotNull(groups = DeletePersonGroup.class) +@Null(groups = AddPersonGroup.class) +private String group; +``` + +```java +@Service +@Validated +public class PersonService { + + public void validatePerson(@Valid Person person) { + // do something + } + + @Validated(AddPersonGroup.class) + public void validatePersonGroupForAdd(@Valid Person person) { + // do something + } + + @Validated(DeletePersonGroup.class) + public void validatePersonGroupForDelete(@Valid Person person) { + // do something + } + +} +``` + +通过测试验证: + +```java + @Test(expected = ConstraintViolationException.class) + public void should_check_person_with_groups() { + Person person = new Person(); + person.setSex("Man22"); + person.setClassId("82938390"); + person.setEmail("SnailClimb"); + person.setGroup("group1"); + service.validatePersonGroupForAdd(person); + } + + @Test(expected = ConstraintViolationException.class) + public void should_check_person_with_groups2() { + Person person = new Person(); + person.setSex("Man22"); + person.setClassId("82938390"); + person.setEmail("SnailClimb"); + service.validatePersonGroupForDelete(person); + } +``` + +使用验证组这种方式的时候一定要小心,这是一种反模式,还会造成代码逻辑性变差。 + +## TODO + +- [ ] JPA 数据库级别参数约束验证 +- [ ] 原理分析 + +## 参考 + +- https://reflectoring.io/bean-validation-with-spring-boot/ +- https://www.cnkirito.moe/spring-validation// \ No newline at end of file From 74fbdd6dc829b28d4411849dceb260deaf5e0637 Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Tue, 10 Sep 2019 17:03:07 +0800 Subject: [PATCH 034/204] =?UTF-8?q?Delete=20=E5=85=B3=E4=BA=8ESpring?= =?UTF-8?q?=E4=B8=AD=E7=9A=84=E5=8F=82=E6=95=B0=E6=A0=A1=E9=AA=8C=E7=9A=84?= =?UTF-8?q?=E4=B8=80=E7=82=B9=E6=80=9D=E8=80=83.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...00\347\202\271\346\200\235\350\200\203.md" | 469 ------------------ 1 file changed, 469 deletions(-) delete mode 100644 "md/\345\205\263\344\272\216Spring\344\270\255\347\232\204\345\217\202\346\225\260\346\240\241\351\252\214\347\232\204\344\270\200\347\202\271\346\200\235\350\200\203.md" diff --git "a/md/\345\205\263\344\272\216Spring\344\270\255\347\232\204\345\217\202\346\225\260\346\240\241\351\252\214\347\232\204\344\270\200\347\202\271\346\200\235\350\200\203.md" "b/md/\345\205\263\344\272\216Spring\344\270\255\347\232\204\345\217\202\346\225\260\346\240\241\351\252\214\347\232\204\344\270\200\347\202\271\346\200\235\350\200\203.md" deleted file mode 100644 index 42ec3c1..0000000 --- "a/md/\345\205\263\344\272\216Spring\344\270\255\347\232\204\345\217\202\346\225\260\346\240\241\351\252\214\347\232\204\344\270\200\347\202\271\346\200\235\350\200\203.md" +++ /dev/null @@ -1,469 +0,0 @@ -数据的校验的重要性就不用说了,即使在前端对数据进行校验的情况下,我们还是要对传入后端的数据再进行一遍校验,避免用户绕过浏览器直接通过一些 HTTP 工具直接向后端请求一些违法数据。 - -下面我会通过实例程序演示如何在 Java 程序中尤其是 Spring 程序中优雅地的进行参数验证。 - -## 基础知识和依赖 - -### 相关依赖 - -如果开发普通 Java 程序的的话,你需要可能需要像下面这样依赖: - -```xml - - org.hibernate.validator - hibernate-validator - 6.0.9.Final - - - javax.el - javax.el-api - 3.0.0 - - - org.glassfish.web - javax.el - 2.2.6 - -``` - -使用 Spring Boot 程序的话只需要`spring-boot-starter-web` 就够了,它的子依赖包含了我们所需要的东西。除了这个依赖,下面的演示还用到了 lombok ,所以不要忘记添加上相关依赖。 - -```xml - - - org.springframework.boot - spring-boot-starter-web - - - org.projectlombok - lombok - true - - - org.springframework.boot - spring-boot-starter-test - test - - -``` - -### 实体类 - -下面这个是示例用到的实体类。 - -```java -@Data -@AllArgsConstructor -@NoArgsConstructor -public class Person { - - @NotNull(message = "classId 不能为空") - private String classId; - - @Size(max = 33) - @NotNull(message = "name 不能为空") - private String name; - - @Pattern(regexp = "((^Man$|^Woman$|^UGM$))", message = "sex 值不在可选范围") - @NotNull(message = "sex 不能为空") - private String sex; - - @Email(message = "email 格式不正确") - @NotNull(message = "email 不能为空") - private String email; - -} -``` - -> 正则表达式说明: -> -> ``` -> - ^string : 匹配以 string 开头的字符串 -> - string$ :匹配以 string 结尾的字符串 -> - ^string$ :精确匹配 string 字符串 -> - ((^Man$|^Woman$|^UGM$)) : 值只能在 Man,Woman,UGM 这三个值中选择 -> ``` - -下面这部分校验注解说明内容参考自:https://www.cnkirito.moe/spring-validation/ ,感谢@[徐靖峰](https://github.com/lexburner)。 - -**JSR提供的校验注解**: - - -- `@Null` 被注释的元素必须为 null -- `@NotNull` 被注释的元素必须不为 null -- `@AssertTrue` 被注释的元素必须为 true -- `@AssertFalse` 被注释的元素必须为 false -- `@Min(value) ` 被注释的元素必须是一个数字,其值必须大于等于指定的最小值 -- `@Max(value) ` 被注释的元素必须是一个数字,其值必须小于等于指定的最大值 -- `@DecimalMin(value) ` 被注释的元素必须是一个数字,其值必须大于等于指定的最小值 -- `@DecimalMax(value)` 被注释的元素必须是一个数字,其值必须小于等于指定的最大值 -- `@Size(max=, min=) ` 被注释的元素的大小必须在指定的范围内 -- `@Digits (integer, fraction) ` 被注释的元素必须是一个数字,其值必须在可接受的范围内 -- `@Past ` 被注释的元素必须是一个过去的日期 -- `@Future` 被注释的元素必须是一个将来的日期 -- `@Pattern(regex=,flag=) ` 被注释的元素必须符合指定的正则表达式 - - -**Hibernate Validator提供的校验注解**: - - -- `@NotBlank(message =) ` 验证字符串非null,且长度必须大于0 -- `@Email` 被注释的元素必须是电子邮箱地址 -- `@Length(min=,max=) ` 被注释的字符串的大小必须在指定的范围内 -- `@NotEmpty ` 被注释的字符串的必须非空 -- `@Range(min=,max=,message=)` 被注释的元素必须在合适的范围内 - -## 验证Controller的输入 - -### 验证请求体(RequestBody) - -**Controller:** - -我们在需要验证的参数上加上了`@Valid`注解,如果验证失败,它将抛出`MethodArgumentNotValidException`。默认情况下,Spring会将此异常转换为HTTP Status 400(错误请求)。 - -```java - -@RestController -@RequestMapping("/api") -public class PersonController { - - @PostMapping("/person") - public ResponseEntity getPerson(@RequestBody @Valid Person person) { - return ResponseEntity.ok().body(person); - } -} -``` - -**ExceptionHandler:** - -自定义异常处理器可以帮助我们捕获异常,并进行一些简单的处理。如果对于下面的处理异常的代码不太理解的话,可以查看这篇文章 [《SpringBoot 处理异常的几种常见姿势》](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247485568&idx=2&sn=c5ba880fd0c5d82e39531fa42cb036ac&chksm=cea2474bf9d5ce5dcbc6a5f6580198fdce4bc92ef577579183a729cb5d1430e4994720d59b34&token=1924773784&lang=zh_CN#rd)。 - -```java -@ControllerAdvice(assignableTypes = {PersonController.class}) -public class GlobalExceptionHandler { - @ExceptionHandler(MethodArgumentNotValidException.class) - public ResponseEntity> handleValidationExceptions( - MethodArgumentNotValidException ex) { - Map errors = new HashMap<>(); - ex.getBindingResult().getAllErrors().forEach((error) -> { - String fieldName = ((FieldError) error).getField(); - String errorMessage = error.getDefaultMessage(); - errors.put(fieldName, errorMessage); - }); - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errors); - } -} -``` - -**通过测试验证:** - -下面我通过 MockMvc 模拟请求 Controller 的方式来验证是否生效,当然你也可以通过 Postman 这种工具来验证。 - -我们试一下所有参数输入正确的情况。 - -```java -@RunWith(SpringRunner.class) -@SpringBootTest -@AutoConfigureMockMvc -public class PersonControllerTest { - @Autowired - private MockMvc mockMvc; - - @Autowired - private ObjectMapper objectMapper; - - @Test - public void should_get_person_correctly() throws Exception { - Person person = new Person(); - person.setName("SnailClimb"); - person.setSex("Man"); - person.setClassId("82938390"); - person.setEmail("Snailclimb@qq.com"); - - mockMvc.perform(post("/api/person") - .contentType(MediaType.APPLICATION_JSON_UTF8) - .content(objectMapper.writeValueAsString(person))) - .andExpect(MockMvcResultMatchers.jsonPath("name").value("SnailClimb")) - .andExpect(MockMvcResultMatchers.jsonPath("classId").value("82938390")) - .andExpect(MockMvcResultMatchers.jsonPath("sex").value("Man")) - .andExpect(MockMvcResultMatchers.jsonPath("email").value("Snailclimb@qq.com")); - } -} -``` - -验证出现参数不合法的情况抛出异常并且可以正确被捕获。 - -```java - @Test - public void should_check_person_value() throws Exception { - Person person = new Person(); - person.setSex("Man22"); - person.setClassId("82938390"); - person.setEmail("SnailClimb"); - - mockMvc.perform(post("/api/person") - .contentType(MediaType.APPLICATION_JSON_UTF8) - .content(objectMapper.writeValueAsString(person))) - .andExpect(MockMvcResultMatchers.jsonPath("sex").value("sex 值不在可选范围")) - .andExpect(MockMvcResultMatchers.jsonPath("name").value("name 不能为空")) - .andExpect(MockMvcResultMatchers.jsonPath("email").value("email 格式不正确")); - } -``` - -使用 Postman 验证结果如下: - -![Postman 验证结果](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-7/postman-validation.png) - -### 验证请求参数(Path Variables 和 Request Parameters) - -**Controller:** - -**一定一定不要忘记在类上加上 `Validated` 注解了,这个参数可以告诉 Spring 去校验方法参数。** - -```java -@RestController -@RequestMapping("/api") -@Validated -public class PersonController { - - @GetMapping("/person/{id}") - public ResponseEntity getPersonByID(@Valid @PathVariable("id") @Max(value = 5,message = "超过 id 的范围了") Integer id) { - return ResponseEntity.ok().body(id); - } - - @PutMapping("/person") - public ResponseEntity getPersonByName(@Valid @RequestParam("name") @Size(max = 6,message = "超过 name 的范围了") String name) { - return ResponseEntity.ok().body(name); - } -} - -``` - -**ExceptionHandler:** - -```java - @ExceptionHandler(ConstraintViolationException.class) - ResponseEntity handleConstraintViolationException(ConstraintViolationException e) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage()); - } -``` - -**通过测试验证:** - -```java - @Test - public void should_check_param_value() throws Exception { - - mockMvc.perform(get("/api/person/6") - .contentType(MediaType.APPLICATION_JSON_UTF8)) - .andExpect(status().isBadRequest()) - .andExpect(content().string("getPersonByID.id: 超过 id 的范围了")); - } - - @Test - public void should_check_param_value2() throws Exception { - - mockMvc.perform(put("/api/person") - .param("name","snailclimbsnailclimb") - .contentType(MediaType.APPLICATION_JSON_UTF8)) - .andExpect(status().isBadRequest()) - .andExpect(content().string("getPersonByName.name: 超过 name 的范围了")); - } -``` - -## 验证 Service 中的方法 - -我们还可以验证任何Spring组件的输入,而不是验证控制器级别的输入,我们可以使用`@Validated`和`@Valid`注释的组合来实现这一需求。 - -**一定一定不要忘记在类上加上 `Validated` 注解了,这个参数可以告诉 Spring 去校验方法参数。** - -```java -@Service -@Validated -public class PersonService { - - public void validatePerson(@Valid Person person){ - // do something - } -} -``` - -**通过测试验证:** - -```java -@RunWith(SpringRunner.class) -@SpringBootTest -@AutoConfigureMockMvc -public class PersonServiceTest { - @Autowired - private PersonService service; - - @Test(expected = ConstraintViolationException.class) - public void should_throw_exception_when_person_is_not_valid() { - Person person = new Person(); - person.setSex("Man22"); - person.setClassId("82938390"); - person.setEmail("SnailClimb"); - service.validatePerson(person); - } - -} -``` - -## Validator 编程方式手动进行参数验证 - -某些场景下可能会需要我们手动校验并获得校验结果。 - -```java - @Test - public void check_person_manually() { - - ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); - Validator validator = factory.getValidator(); - Person person = new Person(); - person.setSex("Man22"); - person.setClassId("82938390"); - person.setEmail("SnailClimb"); - Set> violations = validator.validate(person); - //output: - //email 格式不正确 - //name 不能为空 - //sex 值不在可选范围 - for (ConstraintViolation constraintViolation : violations) { - System.out.println(constraintViolation.getMessage()); - } - } -``` - -上面我们是通过 `Validator` 工厂类获得的 `Validator` 示例,当然你也可以通过 `@Autowired` 直接注入的方式。但是在非 Spring Component 类中使用这种方式的话,只能通过工厂类来获得 `Validator`。 - -```java -@Autowired -Validator validate -``` - -## 自定以 Validator - -如果自带的校验注解无法满足你的需求的话,你还可以自定义实现注解。比如我们的Person类多了一个 region 字段,region 字段只能是`China`、`China-Taiwan`、`China-HongKong`这三个中的一个。 - -第一步你需要创建一个注解: - -```java -@Target({FIELD}) -@Retention(RUNTIME) -@Constraint(validatedBy = RegionValidator.class) -@Documented -public @interface Region { - - String message() default "Region 值不在可选范围内"; - - Class[] groups() default {}; - - Class[] payload() default {}; -} -``` - -第二步你需要实现 `ConstraintValidator`接口,并重写`isValid` 方法: - -```java -import javax.validation.ConstraintValidator; -import javax.validation.ConstraintValidatorContext; -import java.util.HashSet; - -public class RegionValidator implements ConstraintValidator { - - @Override - public boolean isValid(String value, ConstraintValidatorContext context) { - HashSet regions = new HashSet<>(); - regions.add("China"); - regions.add("China-Taiwan"); - regions.add("China-HongKong"); - return regions.contains(value); - } -} - -``` - -现在你就可以使用这个注解: - -```java - @Region - private String region; -``` - -## 使用验证组 - -很多时候我们需要使用到验证组,这样说可能不太清楚,说简单点就是对对象操作的不同方法有不同的验证规则,示例如下。 - -先创建两个接口: - -```java -public interface AddPersonGroup { -} -public interface DeletePersonGroup { -} -``` -我们可以这样去使用验证组 - -```java -@NotNull(groups = DeletePersonGroup.class) -@Null(groups = AddPersonGroup.class) -private String group; -``` - -```java -@Service -@Validated -public class PersonService { - - public void validatePerson(@Valid Person person) { - // do something - } - - @Validated(AddPersonGroup.class) - public void validatePersonGroupForAdd(@Valid Person person) { - // do something - } - - @Validated(DeletePersonGroup.class) - public void validatePersonGroupForDelete(@Valid Person person) { - // do something - } - -} -``` - -通过测试验证: - -```java - @Test(expected = ConstraintViolationException.class) - public void should_check_person_with_groups() { - Person person = new Person(); - person.setSex("Man22"); - person.setClassId("82938390"); - person.setEmail("SnailClimb"); - person.setGroup("group1"); - service.validatePersonGroupForAdd(person); - } - - @Test(expected = ConstraintViolationException.class) - public void should_check_person_with_groups2() { - Person person = new Person(); - person.setSex("Man22"); - person.setClassId("82938390"); - person.setEmail("SnailClimb"); - service.validatePersonGroupForDelete(person); - } -``` - -使用验证组这种方式的时候一定要小心,这是一种反模式,还会造成代码逻辑性变差。 - -## TODO - -- [ ] JPA 数据库级别参数约束验证 -- [ ] 原理分析 - -## 参考 - -- https://reflectoring.io/bean-validation-with-spring-boot/ -- https://www.cnkirito.moe/spring-validation/ \ No newline at end of file From 2ce59dbff539b48d7d153b8985881da72e3d3a16 Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Tue, 10 Sep 2019 17:03:09 +0800 Subject: [PATCH 035/204] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index cd71aaa..1561f28 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ ## 重要知识点 - [RestController VS Controller](./md/RestControllerVSController.md) +- [关于Spring中的参数校验的一点思考](./md/spring-bean-validation) ## 实例 From fa38e6b047f81f6f0c1533b5c323d76f96a7a82f Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Tue, 10 Sep 2019 17:25:14 +0800 Subject: [PATCH 036/204] feat:spring bean validation --- bean-validation-demo/.gitignore | 31 ++ .../.mvn/wrapper/MavenWrapperDownloader.java | 114 +++++++ .../.mvn/wrapper/maven-wrapper.jar | Bin 0 -> 48337 bytes .../.mvn/wrapper/maven-wrapper.properties | 1 + bean-validation-demo/mvnw | 298 ++++++++++++++++++ bean-validation-demo/mvnw.cmd | 161 ++++++++++ bean-validation-demo/pom.xml | 54 ++++ .../BeanValidationDemoApplication.java | 13 + .../constants/Constants.java | 5 + .../controller/HelloWorldController.java | 19 ++ .../controller/PersonController.java | 41 +++ .../beanvalidationdemo/entity/Person.java | 42 +++ .../beanvalidationdemo/entity/Region.java | 26 ++ .../entity/RegionValidator.java | 17 + .../exception/GlobalExceptionHandler.java | 33 ++ .../service/AddPersonGroup.java | 4 + .../service/DeletePersonGroup.java | 4 + .../service/PersonService.java | 27 ++ .../src/main/resources/application.properties | 0 .../HelloWorldControllerTest.java | 28 ++ .../PersonControllerTest.java | 115 +++++++ .../beanvalidationdemo/PersonServiceTest.java | 47 +++ 22 files changed, 1080 insertions(+) create mode 100644 bean-validation-demo/.gitignore create mode 100644 bean-validation-demo/.mvn/wrapper/MavenWrapperDownloader.java create mode 100644 bean-validation-demo/.mvn/wrapper/maven-wrapper.jar create mode 100644 bean-validation-demo/.mvn/wrapper/maven-wrapper.properties create mode 100755 bean-validation-demo/mvnw create mode 100644 bean-validation-demo/mvnw.cmd create mode 100644 bean-validation-demo/pom.xml create mode 100644 bean-validation-demo/src/main/java/com/example/beanvalidationdemo/BeanValidationDemoApplication.java create mode 100644 bean-validation-demo/src/main/java/com/example/beanvalidationdemo/constants/Constants.java create mode 100644 bean-validation-demo/src/main/java/com/example/beanvalidationdemo/controller/HelloWorldController.java create mode 100644 bean-validation-demo/src/main/java/com/example/beanvalidationdemo/controller/PersonController.java create mode 100644 bean-validation-demo/src/main/java/com/example/beanvalidationdemo/entity/Person.java create mode 100644 bean-validation-demo/src/main/java/com/example/beanvalidationdemo/entity/Region.java create mode 100644 bean-validation-demo/src/main/java/com/example/beanvalidationdemo/entity/RegionValidator.java create mode 100644 bean-validation-demo/src/main/java/com/example/beanvalidationdemo/exception/GlobalExceptionHandler.java create mode 100644 bean-validation-demo/src/main/java/com/example/beanvalidationdemo/service/AddPersonGroup.java create mode 100644 bean-validation-demo/src/main/java/com/example/beanvalidationdemo/service/DeletePersonGroup.java create mode 100644 bean-validation-demo/src/main/java/com/example/beanvalidationdemo/service/PersonService.java create mode 100644 bean-validation-demo/src/main/resources/application.properties create mode 100644 bean-validation-demo/src/test/java/com/example/beanvalidationdemo/HelloWorldControllerTest.java create mode 100644 bean-validation-demo/src/test/java/com/example/beanvalidationdemo/PersonControllerTest.java create mode 100644 bean-validation-demo/src/test/java/com/example/beanvalidationdemo/PersonServiceTest.java diff --git a/bean-validation-demo/.gitignore b/bean-validation-demo/.gitignore new file mode 100644 index 0000000..a2a3040 --- /dev/null +++ b/bean-validation-demo/.gitignore @@ -0,0 +1,31 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/** +!**/src/test/** + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ + +### VS Code ### +.vscode/ diff --git a/bean-validation-demo/.mvn/wrapper/MavenWrapperDownloader.java b/bean-validation-demo/.mvn/wrapper/MavenWrapperDownloader.java new file mode 100644 index 0000000..7f91a56 --- /dev/null +++ b/bean-validation-demo/.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 + + https://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +*/ + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.URL; +import java.nio.channels.Channels; +import java.nio.channels.ReadableByteChannel; +import java.util.Properties; + +public class MavenWrapperDownloader { + + /** + * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. + */ + private static final String DEFAULT_DOWNLOAD_URL = + "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"; + + /** + * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to + * use instead of the default one. + */ + private static final String MAVEN_WRAPPER_PROPERTIES_PATH = + ".mvn/wrapper/maven-wrapper.properties"; + + /** + * Path where the maven-wrapper.jar will be saved to. + */ + private static final String MAVEN_WRAPPER_JAR_PATH = + ".mvn/wrapper/maven-wrapper.jar"; + + /** + * Name of the property which should be used to override the default download url for the wrapper. + */ + private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; + + public static void main(String args[]) { + System.out.println("- Downloader started"); + File baseDirectory = new File(args[0]); + System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); + + // If the maven-wrapper.properties exists, read it and check if it contains a custom + // wrapperUrl parameter. + File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); + String url = DEFAULT_DOWNLOAD_URL; + if (mavenWrapperPropertyFile.exists()) { + FileInputStream mavenWrapperPropertyFileInputStream = null; + try { + mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); + Properties mavenWrapperProperties = new Properties(); + mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); + url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); + } catch (IOException e) { + System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); + } finally { + try { + if (mavenWrapperPropertyFileInputStream != null) { + mavenWrapperPropertyFileInputStream.close(); + } + } catch (IOException e) { + // Ignore ... + } + } + } + System.out.println("- Downloading from: : " + url); + + File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); + if (!outputFile.getParentFile().exists()) { + if (!outputFile.getParentFile().mkdirs()) { + System.out.println( + "- ERROR creating output direcrory '" + outputFile.getParentFile().getAbsolutePath() + "'"); + } + } + System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); + try { + downloadFileFromURL(url, outputFile); + System.out.println("Done"); + System.exit(0); + } catch (Throwable e) { + System.out.println("- Error downloading"); + e.printStackTrace(); + System.exit(1); + } + } + + private static void downloadFileFromURL(String urlString, File destination) throws Exception { + URL website = new URL(urlString); + ReadableByteChannel rbc; + rbc = Channels.newChannel(website.openStream()); + FileOutputStream fos = new FileOutputStream(destination); + fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); + fos.close(); + rbc.close(); + } + +} diff --git a/bean-validation-demo/.mvn/wrapper/maven-wrapper.jar b/bean-validation-demo/.mvn/wrapper/maven-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..01e67997377a393fd672c7dcde9dccbedf0cb1e9 GIT binary patch literal 48337 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 \(.*\)$') + 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 "$@" diff --git a/bean-validation-demo/mvnw.cmd b/bean-validation-demo/mvnw.cmd new file mode 100644 index 0000000..fef5a8f --- /dev/null +++ b/bean-validation-demo/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 https://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven2 Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" +FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + echo Found %WRAPPER_JAR% +) else ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')" + echo Finished downloading %WRAPPER_JAR% +) +@REM End of extension + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% diff --git a/bean-validation-demo/pom.xml b/bean-validation-demo/pom.xml new file mode 100644 index 0000000..d5779cb --- /dev/null +++ b/bean-validation-demo/pom.xml @@ -0,0 +1,54 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.1.8.RELEASE + + + com.example + bean-validation-demo + 0.0.1-SNAPSHOT + bean-validation-demo + Demo project for Spring Boot + + + 1.8 + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/bean-validation-demo/src/main/java/com/example/beanvalidationdemo/BeanValidationDemoApplication.java b/bean-validation-demo/src/main/java/com/example/beanvalidationdemo/BeanValidationDemoApplication.java new file mode 100644 index 0000000..3f934bc --- /dev/null +++ b/bean-validation-demo/src/main/java/com/example/beanvalidationdemo/BeanValidationDemoApplication.java @@ -0,0 +1,13 @@ +package com.example.beanvalidationdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class BeanValidationDemoApplication { + + public static void main(String[] args) { + SpringApplication.run(BeanValidationDemoApplication.class, args); + } + +} diff --git a/bean-validation-demo/src/main/java/com/example/beanvalidationdemo/constants/Constants.java b/bean-validation-demo/src/main/java/com/example/beanvalidationdemo/constants/Constants.java new file mode 100644 index 0000000..8c20af3 --- /dev/null +++ b/bean-validation-demo/src/main/java/com/example/beanvalidationdemo/constants/Constants.java @@ -0,0 +1,5 @@ +package com.example.beanvalidationdemo.constants; + +public final class Constants { + public static final String sexs = "((^Man$|^Woman$|^UGM$))"; +} diff --git a/bean-validation-demo/src/main/java/com/example/beanvalidationdemo/controller/HelloWorldController.java b/bean-validation-demo/src/main/java/com/example/beanvalidationdemo/controller/HelloWorldController.java new file mode 100644 index 0000000..8742cbf --- /dev/null +++ b/bean-validation-demo/src/main/java/com/example/beanvalidationdemo/controller/HelloWorldController.java @@ -0,0 +1,19 @@ +package com.example.beanvalidationdemo.controller; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @author shuang.kou + * 验证基本环境搭建是否正确 + */ +@RestController +@RequestMapping("/api") +public class HelloWorldController { + + @GetMapping("/hello") + public String hello() { + return "Hello"; + } +} diff --git a/bean-validation-demo/src/main/java/com/example/beanvalidationdemo/controller/PersonController.java b/bean-validation-demo/src/main/java/com/example/beanvalidationdemo/controller/PersonController.java new file mode 100644 index 0000000..1b22d08 --- /dev/null +++ b/bean-validation-demo/src/main/java/com/example/beanvalidationdemo/controller/PersonController.java @@ -0,0 +1,41 @@ +package com.example.beanvalidationdemo.controller; + +import com.example.beanvalidationdemo.entity.Person; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.BindingResult; +import org.springframework.validation.Errors; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.Mapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import javax.validation.Valid; +import javax.validation.constraints.Max; +import javax.validation.constraints.Size; + +@RestController +@RequestMapping("/api") +@Validated +public class PersonController { + + @PostMapping("/person") + public ResponseEntity getPerson(@RequestBody @Valid Person person) { + return ResponseEntity.ok().body(person); + } + + @GetMapping("/person/{id}") + public ResponseEntity getPersonByID(@Valid @PathVariable("id") @Max(value = 5, message = "超过 id 的范围了") Integer id) { + return ResponseEntity.ok().body(id); + } + + @PutMapping("/person") + public ResponseEntity getPersonByName(@Valid @RequestParam("name") @Size(max = 6, message = "超过 name 的范围了") String name) { + return ResponseEntity.ok().body(name); + } +} diff --git a/bean-validation-demo/src/main/java/com/example/beanvalidationdemo/entity/Person.java b/bean-validation-demo/src/main/java/com/example/beanvalidationdemo/entity/Person.java new file mode 100644 index 0000000..03073f0 --- /dev/null +++ b/bean-validation-demo/src/main/java/com/example/beanvalidationdemo/entity/Person.java @@ -0,0 +1,42 @@ +package com.example.beanvalidationdemo.entity; + +import com.example.beanvalidationdemo.constants.Constants; +import com.example.beanvalidationdemo.service.AddPersonGroup; +import com.example.beanvalidationdemo.service.DeletePersonGroup; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.Email; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Null; +import javax.validation.constraints.Pattern; +import javax.validation.constraints.Size; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class Person { + + @NotNull(message = "classId 不能为空") + private String classId; + + @Size(max = 33) + @NotNull(message = "name 不能为空") + private String name; + + @Pattern(regexp = Constants.sexs, message = "sex 值不在可选范围") + @NotNull(message = "sex 不能为空") + private String sex; + + @Email(message = "email 格式不正确") + @NotNull(message = "email 不能为空") + private String email; + + @Region + private String region; + + @NotNull(groups = DeletePersonGroup.class) + @Null(groups = AddPersonGroup.class) + private String group; +} diff --git a/bean-validation-demo/src/main/java/com/example/beanvalidationdemo/entity/Region.java b/bean-validation-demo/src/main/java/com/example/beanvalidationdemo/entity/Region.java new file mode 100644 index 0000000..9419fdf --- /dev/null +++ b/bean-validation-demo/src/main/java/com/example/beanvalidationdemo/entity/Region.java @@ -0,0 +1,26 @@ +package com.example.beanvalidationdemo.entity; + +import javax.validation.Constraint; +import javax.validation.Payload; +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * @author shuang.kou + */ +@Target({FIELD}) +@Retention(RUNTIME) +@Constraint(validatedBy = RegionValidator.class) +@Documented +public @interface Region { + + String message() default "Region 值不在可选范围内"; + + Class[] groups() default {}; + + Class[] payload() default {}; +} diff --git a/bean-validation-demo/src/main/java/com/example/beanvalidationdemo/entity/RegionValidator.java b/bean-validation-demo/src/main/java/com/example/beanvalidationdemo/entity/RegionValidator.java new file mode 100644 index 0000000..37d22cf --- /dev/null +++ b/bean-validation-demo/src/main/java/com/example/beanvalidationdemo/entity/RegionValidator.java @@ -0,0 +1,17 @@ +package com.example.beanvalidationdemo.entity; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; +import java.util.HashSet; + +public class RegionValidator implements ConstraintValidator { + + @Override + public boolean isValid(String value, ConstraintValidatorContext context) { + HashSet regions = new HashSet<>(); + regions.add("China"); + regions.add("China-Taiwan"); + regions.add("China-HongKong"); + return regions.contains(value); + } +} diff --git a/bean-validation-demo/src/main/java/com/example/beanvalidationdemo/exception/GlobalExceptionHandler.java b/bean-validation-demo/src/main/java/com/example/beanvalidationdemo/exception/GlobalExceptionHandler.java new file mode 100644 index 0000000..c4f4e0a --- /dev/null +++ b/bean-validation-demo/src/main/java/com/example/beanvalidationdemo/exception/GlobalExceptionHandler.java @@ -0,0 +1,33 @@ +package com.example.beanvalidationdemo.exception; + +import com.example.beanvalidationdemo.controller.PersonController; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.FieldError; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; + +import javax.validation.ConstraintViolationException; +import java.util.HashMap; +import java.util.Map; + +@ControllerAdvice(assignableTypes = {PersonController.class}) +public class GlobalExceptionHandler { + @ExceptionHandler(MethodArgumentNotValidException.class) + public ResponseEntity> handleValidationExceptions( + MethodArgumentNotValidException ex) { + Map errors = new HashMap<>(); + ex.getBindingResult().getAllErrors().forEach((error) -> { + String fieldName = ((FieldError) error).getField(); + String errorMessage = error.getDefaultMessage(); + errors.put(fieldName, errorMessage); + }); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errors); + } + + @ExceptionHandler(ConstraintViolationException.class) + ResponseEntity handleConstraintViolationException(ConstraintViolationException e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage()); + } +} diff --git a/bean-validation-demo/src/main/java/com/example/beanvalidationdemo/service/AddPersonGroup.java b/bean-validation-demo/src/main/java/com/example/beanvalidationdemo/service/AddPersonGroup.java new file mode 100644 index 0000000..1f2950d --- /dev/null +++ b/bean-validation-demo/src/main/java/com/example/beanvalidationdemo/service/AddPersonGroup.java @@ -0,0 +1,4 @@ +package com.example.beanvalidationdemo.service; + +public interface AddPersonGroup { +} diff --git a/bean-validation-demo/src/main/java/com/example/beanvalidationdemo/service/DeletePersonGroup.java b/bean-validation-demo/src/main/java/com/example/beanvalidationdemo/service/DeletePersonGroup.java new file mode 100644 index 0000000..92f6713 --- /dev/null +++ b/bean-validation-demo/src/main/java/com/example/beanvalidationdemo/service/DeletePersonGroup.java @@ -0,0 +1,4 @@ +package com.example.beanvalidationdemo.service; + +public interface DeletePersonGroup { +} diff --git a/bean-validation-demo/src/main/java/com/example/beanvalidationdemo/service/PersonService.java b/bean-validation-demo/src/main/java/com/example/beanvalidationdemo/service/PersonService.java new file mode 100644 index 0000000..99856bf --- /dev/null +++ b/bean-validation-demo/src/main/java/com/example/beanvalidationdemo/service/PersonService.java @@ -0,0 +1,27 @@ +package com.example.beanvalidationdemo.service; + +import com.example.beanvalidationdemo.entity.Person; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.validation.Valid; + +@Service +@Validated +public class PersonService { + + public void validatePerson(@Valid Person person) { + // do something + } + + @Validated(AddPersonGroup.class) + public void validatePersonGroupForAdd(@Valid Person person) { + // do something + } + + @Validated(DeletePersonGroup.class) + public void validatePersonGroupForDelete(@Valid Person person) { + // do something + } + +} diff --git a/bean-validation-demo/src/main/resources/application.properties b/bean-validation-demo/src/main/resources/application.properties new file mode 100644 index 0000000..e69de29 diff --git a/bean-validation-demo/src/test/java/com/example/beanvalidationdemo/HelloWorldControllerTest.java b/bean-validation-demo/src/test/java/com/example/beanvalidationdemo/HelloWorldControllerTest.java new file mode 100644 index 0000000..ea998ca --- /dev/null +++ b/bean-validation-demo/src/test/java/com/example/beanvalidationdemo/HelloWorldControllerTest.java @@ -0,0 +1,28 @@ +package com.example.beanvalidationdemo; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; + +/** + * 验证基本的项目基本环境是否有问题 + */ +@RunWith(SpringRunner.class) +@SpringBootTest +@AutoConfigureMockMvc +public class HelloWorldControllerTest { + @Autowired + private MockMvc mockMvc; + + @Test + public void should_get_hello() throws Exception { + mockMvc.perform(get("/api/hello")).andExpect(content().string("Hello")); + } +} diff --git a/bean-validation-demo/src/test/java/com/example/beanvalidationdemo/PersonControllerTest.java b/bean-validation-demo/src/test/java/com/example/beanvalidationdemo/PersonControllerTest.java new file mode 100644 index 0000000..2d0378a --- /dev/null +++ b/bean-validation-demo/src/test/java/com/example/beanvalidationdemo/PersonControllerTest.java @@ -0,0 +1,115 @@ +package com.example.beanvalidationdemo; + + +import com.example.beanvalidationdemo.entity.Person; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.result.MockMvcResultMatchers; + +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.Validator; +import javax.validation.ValidatorFactory; +import java.util.Set; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@RunWith(SpringRunner.class) +@SpringBootTest +@AutoConfigureMockMvc +public class PersonControllerTest { + @Autowired + private MockMvc mockMvc; + + @Autowired + private ObjectMapper objectMapper; + + @Test + public void should_get_person() throws Exception { + Person person = new Person(); + person.setName("SnailClimb"); + person.setSex("Man"); + person.setClassId("82938390"); + person.setEmail("Snailclimb@qq.com"); + person.setRegion("China"); + + mockMvc.perform(post("/api/person") + .contentType(MediaType.APPLICATION_JSON_UTF8) + .content(objectMapper.writeValueAsString(person))) + .andExpect(MockMvcResultMatchers.jsonPath("name").value("SnailClimb")) + .andExpect(MockMvcResultMatchers.jsonPath("classId").value("82938390")) + .andExpect(MockMvcResultMatchers.jsonPath("sex").value("Man")) + .andExpect(MockMvcResultMatchers.jsonPath("email").value("Snailclimb@qq.com")); + ; + } + + @Test + public void should_check_person_value() throws Exception { + Person person = new Person(); + person.setSex("Man22"); + person.setClassId("82938390"); + person.setEmail("SnailClimb"); + person.setRegion("BeiGuo"); + + mockMvc.perform(post("/api/person") + .contentType(MediaType.APPLICATION_JSON_UTF8) + .content(objectMapper.writeValueAsString(person))) + .andExpect(MockMvcResultMatchers.jsonPath("sex").value("sex 值不在可选范围")) + .andExpect(MockMvcResultMatchers.jsonPath("name").value("name 不能为空")) + .andExpect(MockMvcResultMatchers.jsonPath("email").value("email 格式不正确")) + .andExpect(MockMvcResultMatchers.jsonPath("region").value("Region 值不在可选范围内")); + ; + } + + @Test + public void should_check_param_value() throws Exception { + + mockMvc.perform(get("/api/person/6") + .contentType(MediaType.APPLICATION_JSON_UTF8)) + .andExpect(status().isBadRequest()) + .andExpect(content().string("getPersonByID.id: 超过 id 的范围了")); + } + + @Test + public void should_check_param_value2() throws Exception { + + mockMvc.perform(put("/api/person") + .param("name", "snailclimbsnailclimb") + .contentType(MediaType.APPLICATION_JSON_UTF8)) + .andExpect(status().isBadRequest()) + .andExpect(content().string("getPersonByName.name: 超过 name 的范围了")); + } + + /** + * 手动校验对象,很多场景下需要使用这种方式 + */ + @Test + public void check_person_manually() { + + ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); + Validator validator = factory.getValidator(); + Person person = new Person(); + person.setSex("Man22"); + person.setClassId("82938390"); + person.setEmail("SnailClimb"); + Set> violations = validator.validate(person); + //output: + //email 格式不正确 + //name 不能为空 + //sex 值不在可选范围 + for (ConstraintViolation constraintViolation : violations) { + System.out.println(constraintViolation.getMessage()); + } + } +} diff --git a/bean-validation-demo/src/test/java/com/example/beanvalidationdemo/PersonServiceTest.java b/bean-validation-demo/src/test/java/com/example/beanvalidationdemo/PersonServiceTest.java new file mode 100644 index 0000000..377d7e1 --- /dev/null +++ b/bean-validation-demo/src/test/java/com/example/beanvalidationdemo/PersonServiceTest.java @@ -0,0 +1,47 @@ +package com.example.beanvalidationdemo; + +import com.example.beanvalidationdemo.entity.Person; +import com.example.beanvalidationdemo.service.PersonService; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import javax.validation.ConstraintViolationException; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class PersonServiceTest { + @Autowired + private PersonService service; + + @Test(expected = ConstraintViolationException.class) + public void should_throw_exception_when_person_is_not_valid() { + Person person = new Person(); + person.setSex("Man22"); + person.setClassId("82938390"); + person.setEmail("SnailClimb"); + service.validatePerson(person); + } + + @Test(expected = ConstraintViolationException.class) + public void should_check_person_with_groups() { + Person person = new Person(); + person.setSex("Man22"); + person.setClassId("82938390"); + person.setEmail("SnailClimb"); + person.setGroup("group1"); + service.validatePersonGroupForAdd(person); + } + + @Test(expected = ConstraintViolationException.class) + public void should_check_person_with_groups2() { + Person person = new Person(); + person.setSex("Man22"); + person.setClassId("82938390"); + person.setEmail("SnailClimb"); + service.validatePersonGroupForDelete(person); + } + +} From f1985b88f183a2e341e773a85bddc7032efe656c Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Tue, 10 Sep 2019 17:34:48 +0800 Subject: [PATCH 037/204] Create spring-boot-devtools.md --- md/spring-boot-devtools.md | 63 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 md/spring-boot-devtools.md diff --git a/md/spring-boot-devtools.md b/md/spring-boot-devtools.md new file mode 100644 index 0000000..16c910e --- /dev/null +++ b/md/spring-boot-devtools.md @@ -0,0 +1,63 @@ +后端开发中热部署有很多方式,但是在开发 SpringBoot 项目有一种 Spring Boot 给我们提供好的很方便的一种方式,配置起来也很简单。 + +> 热部署可以简单的这样理解:我们修改程序代码后不需要重新启动程序,就可以获取到最新的代码,更新程序对外的行为。 + +热部署在我们日常开发可以为我们节省很多时间,通常我们在开发后端的过程中,当我们修改了后端代码之后都需要重启一下项目,这为我们浪费了时间,特别是在项目比较庞大,需要耗费大量时间的启动的时候。**这种方式好像消耗性能挺大的,也需要慎重使用。** + +下面介绍一下如何通过 SpringBoot 提供的 spring-boot-devtools 实现简单的热部署。 + +**依赖:** + +Maven: + +```xml + + org.springframework.boot + spring-boot-devtools + runtime + true + +``` + +```xml + + org.springframework.boot + spring-boot-maven-plugin + +``` + +Gradle: + +```groovy + +configurations { + developmentOnly + runtimeClasspath { + extendsFrom developmentOnly + } +} +dependencies { + developmentOnly("org.springframework.boot:spring-boot-devtools") +} + +``` + + + +**添加配置:** + +ctrl+,(Win) / cmd+(Mac)打开项目配置: + +输入 Compiler , 并且勾选上 Build project automatically + +![dev-tools-idea1](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-7/dev-tools-idea1.png) + +输入快捷键 ctrl + shift + alt + / (Win)cmd+option+shift+/(Mac),并且选择 Registry + +![dev-tools-idea2](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-7/dev-tools-idea2.png) + +然后勾选上 Compiler autoMake allow when app running + +![dev-tools-idea3](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-7/dev-tools-idea3.png) + +很简单,这样你每次修改程序之后就不用重新启动了。 \ No newline at end of file From c70fd9e82fddedbdfc7881675689e39f4fac1ecb Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Tue, 10 Sep 2019 17:34:50 +0800 Subject: [PATCH 038/204] Update README.md --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 1561f28..6badbe6 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ - [重要知识点](#重要知识点) - [实例](#实例) + - [SpringBoot 热部署](#springboot-热部署) - [SpringBoot 定时任务](#springboot-定时任务) - [SpringBoot 异常处理](#springboot-异常处理) - [SpringBoot+Mybatis](#springbootmybatis) @@ -15,6 +16,10 @@ ## 实例 +### SpringBoot 热部署 + +[SpringBoot 使用 spring-boot-devtools 热部署](./md/spring-boot-devtools.md) + ### SpringBoot 定时任务 [5分钟搞懂如何在Spring Boot中Schedule Tasks](./md/SpringBoot-ScheduleTasks.md) From 451ab21f9293e764db2b179284631103312794dc Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Wed, 11 Sep 2019 21:08:24 +0800 Subject: [PATCH 039/204] Update spring-bean-validation.md --- md/spring-bean-validation.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/md/spring-bean-validation.md b/md/spring-bean-validation.md index d88bcfa..e633351 100644 --- a/md/spring-bean-validation.md +++ b/md/spring-bean-validation.md @@ -1,5 +1,7 @@ 数据的校验的重要性就不用说了,即使在前端对数据进行校验的情况下,我们还是要对传入后端的数据再进行一遍校验,避免用户绕过浏览器直接通过一些 HTTP 工具直接向后端请求一些违法数据。 +最近工作中很多地方需要对参数做一些校验,刚开始的时候除了Controller层接受的对象我是直接通过一些 Spring 提供好的注解来实现校验比如`@Valid`、`@NotNull` 等等,在一些需要对参数做校验的其他地方我都是通过手动编程if else判断的方式来实现。后面重构代码发现有更好的方式来满足我的需求,然后花了半天时间对这部分内容做了一个简单的总结,希望可以对不了解这部分知识的朋友有帮助。 + 下面我会通过实例程序演示如何在 Java 程序中尤其是 Spring 程序中优雅地的进行参数验证。 - [基础知识和依赖](#基础知识和依赖) From 2963360a5ca974700a12152b9d2aee9850c06604 Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Tue, 24 Sep 2019 22:07:54 +0800 Subject: [PATCH 040/204] Spring Security --- README.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6badbe6..1a6f13f 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ [SpringBoot 使用 spring-boot-devtools 热部署](./md/spring-boot-devtools.md) -### SpringBoot 定时任务 +### SpringBoot 定时任务 [5分钟搞懂如何在Spring Boot中Schedule Tasks](./md/SpringBoot-ScheduleTasks.md) @@ -39,6 +39,11 @@ [SpringBoot 整合 阿里云OSS 存储服务,快来免费搭建一个自己的图床](./md/springboot-oss.md) -### springboot-dubbo(使用SpringBoot+Dubbo 搭建一个分布式服务) +### SpringBoot+Dubbo + +[超详细,新手都能看懂 !使用SpringBoot+Dubbo 搭建一个分布式服务](./md/springboot-dubbo.md) + +### Spring Security + +[从零入门 !Spring Security With JWT(含权限验证)](https://github.com/Snailclimb/spring-security-jwt-guide) -[超详细,新手都能看懂 !使用SpringBoot+Dubbo 搭建一个分布式服务](./md/springboot-dubbo.md) \ No newline at end of file From 22295370c50dcacd1c16d32736cc3ea80938ec21 Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Tue, 24 Sep 2019 22:08:32 +0800 Subject: [PATCH 041/204] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1a6f13f..56cf064 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ [超详细,新手都能看懂 !使用SpringBoot+Dubbo 搭建一个分布式服务](./md/springboot-dubbo.md) -### Spring Security +### Spring Security With JWT [从零入门 !Spring Security With JWT(含权限验证)](https://github.com/Snailclimb/spring-security-jwt-guide) From 917db9721ce52203bb1280af3479e3769df05a9b Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Thu, 26 Sep 2019 09:24:16 +0800 Subject: [PATCH 042/204] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 56cf064..ff7750f 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +**如果国内访问缓慢的话,可以通过码云查看:** https://gitee.com/SnailClimb/springboot-guide + ### 目录 - [重要知识点](#重要知识点) From 4bcef35b27915564f780b5a6a5a8ecc5655026d0 Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Sat, 28 Sep 2019 16:34:13 +0800 Subject: [PATCH 043/204] Update README.md --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index ff7750f..e863ee1 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +![logo](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-7/spring-boot-guide.png) + **如果国内访问缓慢的话,可以通过码云查看:** https://gitee.com/SnailClimb/springboot-guide ### 目录 @@ -49,3 +51,6 @@ [从零入门 !Spring Security With JWT(含权限验证)](https://github.com/Snailclimb/spring-security-jwt-guide) +## 说明 + + 项目 logo 由 [logoly](https://logoly.pro/#/) 生成。 \ No newline at end of file From 30b3bc3696e200d3de1c3bb39b0e9c4f3b57cf12 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 1 Oct 2019 14:58:07 +0800 Subject: [PATCH 044/204] Update README.md --- README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e863ee1..26617f8 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,8 @@ -![logo](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-7/spring-boot-guide.png) +

+ + + +

**如果国内访问缓慢的话,可以通过码云查看:** https://gitee.com/SnailClimb/springboot-guide @@ -53,4 +57,4 @@ ## 说明 - 项目 logo 由 [logoly](https://logoly.pro/#/) 生成。 \ No newline at end of file + 项目 logo 由 [logoly](https://logoly.pro/#/) 生成。 From 65989cfcbb542c61517c33c1e8d3657d3c25e91a Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Tue, 1 Oct 2019 15:04:44 +0800 Subject: [PATCH 045/204] feat:spring boot future --- async-method-springboot/.gitignore | 31 ++ .../.mvn/wrapper/MavenWrapperDownloader.java | 114 +++++++ .../.mvn/wrapper/maven-wrapper.jar | Bin 0 -> 48337 bytes .../.mvn/wrapper/maven-wrapper.properties | 1 + async-method-springboot/README.md | 268 ++++++++++++++++ async-method-springboot/mvnw | 298 ++++++++++++++++++ async-method-springboot/mvnw.cmd | 161 ++++++++++ async-method-springboot/pom.xml | 48 +++ .../AsyncMethodSpringbootApplication.java | 13 + .../config/AsyncConfig.java | 36 +++ .../controller/AsyncController.java | 38 +++ .../service/AsyncService.java | 48 +++ .../src/main/resources/application.properties | 1 + .../service/AsyncServiceTest.java | 39 +++ 14 files changed, 1096 insertions(+) create mode 100644 async-method-springboot/.gitignore create mode 100644 async-method-springboot/.mvn/wrapper/MavenWrapperDownloader.java create mode 100644 async-method-springboot/.mvn/wrapper/maven-wrapper.jar create mode 100644 async-method-springboot/.mvn/wrapper/maven-wrapper.properties create mode 100644 async-method-springboot/README.md create mode 100755 async-method-springboot/mvnw create mode 100644 async-method-springboot/mvnw.cmd create mode 100644 async-method-springboot/pom.xml create mode 100644 async-method-springboot/src/main/java/github/javaguide/asyncmethodspringboot/AsyncMethodSpringbootApplication.java create mode 100644 async-method-springboot/src/main/java/github/javaguide/asyncmethodspringboot/config/AsyncConfig.java create mode 100644 async-method-springboot/src/main/java/github/javaguide/asyncmethodspringboot/controller/AsyncController.java create mode 100644 async-method-springboot/src/main/java/github/javaguide/asyncmethodspringboot/service/AsyncService.java create mode 100644 async-method-springboot/src/main/resources/application.properties create mode 100644 async-method-springboot/src/test/java/github/javaguide/asyncmethodspringboot/service/AsyncServiceTest.java diff --git a/async-method-springboot/.gitignore b/async-method-springboot/.gitignore new file mode 100644 index 0000000..a2a3040 --- /dev/null +++ b/async-method-springboot/.gitignore @@ -0,0 +1,31 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/** +!**/src/test/** + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ + +### VS Code ### +.vscode/ diff --git a/async-method-springboot/.mvn/wrapper/MavenWrapperDownloader.java b/async-method-springboot/.mvn/wrapper/MavenWrapperDownloader.java new file mode 100644 index 0000000..7f91a56 --- /dev/null +++ b/async-method-springboot/.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 + + https://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +*/ + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.URL; +import java.nio.channels.Channels; +import java.nio.channels.ReadableByteChannel; +import java.util.Properties; + +public class MavenWrapperDownloader { + + /** + * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. + */ + private static final String DEFAULT_DOWNLOAD_URL = + "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"; + + /** + * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to + * use instead of the default one. + */ + private static final String MAVEN_WRAPPER_PROPERTIES_PATH = + ".mvn/wrapper/maven-wrapper.properties"; + + /** + * Path where the maven-wrapper.jar will be saved to. + */ + private static final String MAVEN_WRAPPER_JAR_PATH = + ".mvn/wrapper/maven-wrapper.jar"; + + /** + * Name of the property which should be used to override the default download url for the wrapper. + */ + private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; + + public static void main(String args[]) { + System.out.println("- Downloader started"); + File baseDirectory = new File(args[0]); + System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); + + // If the maven-wrapper.properties exists, read it and check if it contains a custom + // wrapperUrl parameter. + File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); + String url = DEFAULT_DOWNLOAD_URL; + if (mavenWrapperPropertyFile.exists()) { + FileInputStream mavenWrapperPropertyFileInputStream = null; + try { + mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); + Properties mavenWrapperProperties = new Properties(); + mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); + url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); + } catch (IOException e) { + System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); + } finally { + try { + if (mavenWrapperPropertyFileInputStream != null) { + mavenWrapperPropertyFileInputStream.close(); + } + } catch (IOException e) { + // Ignore ... + } + } + } + System.out.println("- Downloading from: : " + url); + + File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); + if (!outputFile.getParentFile().exists()) { + if (!outputFile.getParentFile().mkdirs()) { + System.out.println( + "- ERROR creating output direcrory '" + outputFile.getParentFile().getAbsolutePath() + "'"); + } + } + System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); + try { + downloadFileFromURL(url, outputFile); + System.out.println("Done"); + System.exit(0); + } catch (Throwable e) { + System.out.println("- Error downloading"); + e.printStackTrace(); + System.exit(1); + } + } + + private static void downloadFileFromURL(String urlString, File destination) throws Exception { + URL website = new URL(urlString); + ReadableByteChannel rbc; + rbc = Channels.newChannel(website.openStream()); + FileOutputStream fos = new FileOutputStream(destination); + fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); + fos.close(); + rbc.close(); + } + +} diff --git a/async-method-springboot/.mvn/wrapper/maven-wrapper.jar b/async-method-springboot/.mvn/wrapper/maven-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..01e67997377a393fd672c7dcde9dccbedf0cb1e9 GIT binary patch literal 48337 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 movies = + new ArrayList<>( + Arrays.asList( + "Forrest Gump", + "Titanic", + "Spirited Away", + "The Shawshank Redemption", + "Zootopia", + "Farewell ", + "Joker", + "Crawl")); + + /** 示范使用:找到特定字符/字符串开头的电影 */ + @Async + public CompletableFuture> completableFutureTask(String start) { + // 打印日志 + logger.warn(Thread.currentThread().getName() + "start this task!"); + // 找到特定字符/字符串开头的电影 + List results = + movies.stream().filter(movie -> movie.startsWith(start)).collect(Collectors.toList()); + // 模拟这是一个耗时的任务 + try { + Thread.sleep(1000L); + } catch (InterruptedException e) { + e.printStackTrace(); + } + //返回一个已经用给定值完成的新的CompletableFuture。 + return CompletableFuture.completedFuture(results); + } +} + +``` + +### 3. 测试编写的异步方法 + +```java +/** @author shuang.kou */ +@RestController +@RequestMapping("/async") +public class AsyncController { + @Autowired + AsyncService asyncService; + + @GetMapping("/movies") + public String completableFutureTask() throws ExecutionException, InterruptedException { + //开始时间 + long start = System.currentTimeMillis(); + // 开始执行大量的异步任务 + List words = Arrays.asList("F", "T", "S", "Z", "J", "C"); + List>> completableFutureList = + words.stream() + .map(word -> asyncService.completableFutureTask(word)) + .collect(Collectors.toList()); + // CompletableFuture.join()方法可以获取他们的结果并将结果连接起来 + List> results = completableFutureList.stream().map(CompletableFuture::join).collect(Collectors.toList()); + // 打印结果以及运行程序运行花费时间 + System.out.println("Elapsed time: " + (System.currentTimeMillis() - start)); + return results.toString(); + } +} +``` + +请求这个接口,控制台打印出下面的内容: + +``` +2019-10-01 13:50:17.007 WARN 18793 --- [lTaskExecutor-1] g.j.a.service.AsyncService : My ThreadPoolTaskExecutor-1start this task! +2019-10-01 13:50:17.007 WARN 18793 --- [lTaskExecutor-6] g.j.a.service.AsyncService : My ThreadPoolTaskExecutor-6start this task! +2019-10-01 13:50:17.007 WARN 18793 --- [lTaskExecutor-5] g.j.a.service.AsyncService : My ThreadPoolTaskExecutor-5start this task! +2019-10-01 13:50:17.007 WARN 18793 --- [lTaskExecutor-4] g.j.a.service.AsyncService : My ThreadPoolTaskExecutor-4start this task! +2019-10-01 13:50:17.007 WARN 18793 --- [lTaskExecutor-3] g.j.a.service.AsyncService : My ThreadPoolTaskExecutor-3start this task! +2019-10-01 13:50:17.007 WARN 18793 --- [lTaskExecutor-2] g.j.a.service.AsyncService : My ThreadPoolTaskExecutor-2start this task! +Elapsed time: 1010 +``` + +首先我们可以看到处理所有任务花费的时间大概是 1 s。这与我们自定义的 `ThreadPoolTaskExecutor` 有关,我们配置的核心线程数是 6 ,然后通过通过下面的代码模拟分配了 6 个任务给系统执行。这样每个线程都会被分配到一个任务,每个任务执行花费时间是 1 s ,所以处理 6 个任务的总花费时间是 1 s。 + +```java +List words = Arrays.asList("F", "T", "S", "Z", "J", "C"); +List>> completableFutureList = + words.stream() + .map(word -> asyncService.completableFutureTask(word)) + .collect(Collectors.toList()); +``` + +你可以自己验证一下,试着去把核心线程数的数量改为 3 ,再次请求这个接口你会发现处理所有任务花费的时间大概是 2 s。 + +另外,**从上面的运行结果可以看出,当所有任务执行完成之后才返回结果。这种情况对应于我们需要返回结果给客户端请求的情况下,假如我们不需要返回任务执行结果给客户端的话呢?** 就比如我们上传一个大文件到系统,上传之后只要大文件格式符合要求我们就上传成功。普通情况下我们需要等待文件上传完毕再返回给用户消息,但是这样会很慢。采用异步的话,当用户上传之后就立马返回给用户消息,然后系统再默默去处理上传任务。**这样也会增加一点麻烦,因为文件可能会上传失败,所以系统也需要一点机制来补偿这个问题,比如当上传遇到问题的时候,发消息通知用户。** + +下面会演示一下客户端不需要返回结果的情况: + +将`completableFutureTask`方法变为 void 类型 + +```java +@Async +public void completableFutureTask(String start) { + ...... + //这里可能是系统对任务执行结果的处理,比如存入到数据库等等...... + //doSomeThingWithResults(results); +} +``` + +Controller 代码修改如下: + +```java + @GetMapping("/movies") + public String completableFutureTask() throws ExecutionException, InterruptedException { + // Start the clock + long start = System.currentTimeMillis(); + // Kick of multiple, asynchronous lookups + List words = Arrays.asList("F", "T", "S", "Z", "J", "C"); + words.stream() + .forEach(word -> asyncService.completableFutureTask(word)); + // Wait until they are all done + // Print results, including elapsed time + System.out.println("Elapsed time: " + (System.currentTimeMillis() - start)); + return "Done"; + } +``` + +请求这个接口,控制台打印出下面的内容: + +``` +Elapsed time: 0 +2019-10-01 14:02:44.052 WARN 19051 --- [lTaskExecutor-4] g.j.a.service.AsyncService : My ThreadPoolTaskExecutor-4start this task! +2019-10-01 14:02:44.052 WARN 19051 --- [lTaskExecutor-3] g.j.a.service.AsyncService : My ThreadPoolTaskExecutor-3start this task! +2019-10-01 14:02:44.052 WARN 19051 --- [lTaskExecutor-2] g.j.a.service.AsyncService : My ThreadPoolTaskExecutor-2start this task! +2019-10-01 14:02:44.052 WARN 19051 --- [lTaskExecutor-1] g.j.a.service.AsyncService : My ThreadPoolTaskExecutor-1start this task! +2019-10-01 14:02:44.052 WARN 19051 --- [lTaskExecutor-6] g.j.a.service.AsyncService : My ThreadPoolTaskExecutor-6start this task! +2019-10-01 14:02:44.052 WARN 19051 --- [lTaskExecutor-5] g.j.a.service.AsyncService : My ThreadPoolTaskExecutor-5start this task! +``` + +可以看到系统会直接返回给用户结果,然后系统才真正开始执行任务。 + +## Reference + +- https://spring.io/guides/gs/async-method/ +- https://medium.com/trendyol-tech/spring-boot-async-executor-management-with-threadpooltaskexecutor-f493903617d \ No newline at end of file diff --git a/async-method-springboot/mvnw b/async-method-springboot/mvnw new file mode 100755 index 0000000..c188654 --- /dev/null +++ b/async-method-springboot/mvnw @@ -0,0 +1,298 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven2 Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ]; then + + if [ -f /etc/mavenrc ]; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ]; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false +darwin=false +mingw=false +case "$(uname)" in +CYGWIN*) cygwin=true ;; +MINGW*) mingw=true ;; +Darwin*) + darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="$(/usr/libexec/java_home)" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ]; then + if [ -r /etc/gentoo-release ]; then + JAVA_HOME=$(java-config --jre-home) + fi +fi + +if [ -z "$M2_HOME" ]; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ]; do + ls=$(ls -ld "$PRG") + link=$(expr "$ls" : '.*-> \(.*\)$') + if expr "$link" : '/.*' >/dev/null; then + PRG="$link" + else + PRG="$(dirname "$PRG")/$link" + fi + done + + saveddir=$(pwd) + + M2_HOME=$(dirname "$PRG")/.. + + # make it fully qualified + M2_HOME=$(cd "$M2_HOME" && pwd) + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=$(cygpath --unix "$M2_HOME") + [ -n "$JAVA_HOME" ] && + JAVA_HOME=$(cygpath --unix "$JAVA_HOME") + [ -n "$CLASSPATH" ] && + CLASSPATH=$(cygpath --path --unix "$CLASSPATH") +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw; then + [ -n "$M2_HOME" ] && + M2_HOME="$( ( + cd "$M2_HOME" + pwd + ))" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="$( ( + cd "$JAVA_HOME" + pwd + ))" + # TODO classpath? +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="$(which javac)" + if [ -n "$javaExecutable" ] && ! [ "$(expr \"$javaExecutable\" : '\([^ ]*\)')" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=$(which readlink) + if [ ! $(expr "$readLink" : '\([^ ]*\)') = "no" ]; then + if $darwin; then + javaHome="$(dirname \"$javaExecutable\")" + javaExecutable="$(cd \"$javaHome\" && pwd -P)/javac" + else + javaExecutable="$(readlink -f \"$javaExecutable\")" + fi + javaHome="$(dirname \"$javaExecutable\")" + javaHome=$(expr "$javaHome" : '\(.*\)/bin') + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ]; then + if [ -n "$JAVA_HOME" ]; then + if [ -x "$JAVA_HOME/jre/sh/java" ]; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="$(which java)" + fi +fi + +if [ ! -x "$JAVACMD" ]; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ]; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ]; then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ]; do + if [ -d "$wdir"/.mvn ]; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=$( + cd "$wdir/.." + pwd + ) + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' <"$1")" + fi +} + +BASE_DIR=$(find_maven_basedir "$(pwd)") +if [ -z "$BASE_DIR" ]; then + exit 1 +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" + while IFS="=" read key value; do + case "$key" in wrapperUrl) + jarUrl="$value" + break + ;; + esac + done <"$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + + if command -v wget >/dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + wget "$jarUrl" -O "$wrapperJarPath" + elif command -v curl >/dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + curl -o "$wrapperJarPath" "$jarUrl" + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=$(cygpath --path --windows "$M2_HOME") + [ -n "$JAVA_HOME" ] && + JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME") + [ -n "$CLASSPATH" ] && + CLASSPATH=$(cygpath --path --windows "$CLASSPATH") + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR") +fi + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/async-method-springboot/mvnw.cmd b/async-method-springboot/mvnw.cmd new file mode 100644 index 0000000..fef5a8f --- /dev/null +++ b/async-method-springboot/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 https://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven2 Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" +FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + echo Found %WRAPPER_JAR% +) else ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')" + echo Finished downloading %WRAPPER_JAR% +) +@REM End of extension + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% diff --git a/async-method-springboot/pom.xml b/async-method-springboot/pom.xml new file mode 100644 index 0000000..a5b3d07 --- /dev/null +++ b/async-method-springboot/pom.xml @@ -0,0 +1,48 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.1.8.RELEASE + + + github.javaguide + async-method-springboot + 0.0.1-SNAPSHOT + async-method-springboot + Creating Asynchronous Methods + + + 1.8 + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/async-method-springboot/src/main/java/github/javaguide/asyncmethodspringboot/AsyncMethodSpringbootApplication.java b/async-method-springboot/src/main/java/github/javaguide/asyncmethodspringboot/AsyncMethodSpringbootApplication.java new file mode 100644 index 0000000..55b35e3 --- /dev/null +++ b/async-method-springboot/src/main/java/github/javaguide/asyncmethodspringboot/AsyncMethodSpringbootApplication.java @@ -0,0 +1,13 @@ +package github.javaguide.asyncmethodspringboot; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class AsyncMethodSpringbootApplication { + + public static void main(String[] args) { + SpringApplication.run(AsyncMethodSpringbootApplication.class, args); + } + +} diff --git a/async-method-springboot/src/main/java/github/javaguide/asyncmethodspringboot/config/AsyncConfig.java b/async-method-springboot/src/main/java/github/javaguide/asyncmethodspringboot/config/AsyncConfig.java new file mode 100644 index 0000000..e5cb4e7 --- /dev/null +++ b/async-method-springboot/src/main/java/github/javaguide/asyncmethodspringboot/config/AsyncConfig.java @@ -0,0 +1,36 @@ +package github.javaguide.asyncmethodspringboot.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.AsyncConfigurer; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadPoolExecutor; + +/** @author shuang.kou */ +@Configuration +@EnableAsync +public class AsyncConfig implements AsyncConfigurer { + + private static final int CORE_POOL_SIZE = 6; + private static final int MAX_POOL_SIZE = 10; + private static final int QUEUE_CAPACITY = 100; + + @Bean + public Executor taskExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + // 核心线程数 + executor.setCorePoolSize(CORE_POOL_SIZE); + // 最大线程数 + executor.setMaxPoolSize(MAX_POOL_SIZE); + // 队列大小 + executor.setQueueCapacity(QUEUE_CAPACITY); + // 当最大池已满时,此策略保证不会丢失任务请求,但是可能会影响应用程序整体性能。 + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + executor.setThreadNamePrefix("My ThreadPoolTaskExecutor-"); + executor.initialize(); + return executor; + } +} diff --git a/async-method-springboot/src/main/java/github/javaguide/asyncmethodspringboot/controller/AsyncController.java b/async-method-springboot/src/main/java/github/javaguide/asyncmethodspringboot/controller/AsyncController.java new file mode 100644 index 0000000..b1a5d65 --- /dev/null +++ b/async-method-springboot/src/main/java/github/javaguide/asyncmethodspringboot/controller/AsyncController.java @@ -0,0 +1,38 @@ +package github.javaguide.asyncmethodspringboot.controller; + +import github.javaguide.asyncmethodspringboot.service.AsyncService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.stream.Collectors; + +/** @author shuang.kou */ +@RestController +@RequestMapping("/async") +public class AsyncController { + @Autowired + AsyncService asyncService; + + @GetMapping("/movies") + public String completableFutureTask() throws ExecutionException, InterruptedException { + //开始时间 + long start = System.currentTimeMillis(); + // 开始执行大量的异步任务 + List words = Arrays.asList("F", "T", "S", "Z", "J", "C"); + List>> completableFutureList = + words.stream() + .map(word -> asyncService.completableFutureTask(word)) + .collect(Collectors.toList()); + // CompletableFuture.join()方法可以获取他们的结果并将结果连接起来 + List> results = completableFutureList.stream().map(CompletableFuture::join).collect(Collectors.toList()); + // 打印结果以及运行程序运行花费时间 + System.out.println("Elapsed time: " + (System.currentTimeMillis() - start)); + return results.toString(); + } +} diff --git a/async-method-springboot/src/main/java/github/javaguide/asyncmethodspringboot/service/AsyncService.java b/async-method-springboot/src/main/java/github/javaguide/asyncmethodspringboot/service/AsyncService.java new file mode 100644 index 0000000..05e72c9 --- /dev/null +++ b/async-method-springboot/src/main/java/github/javaguide/asyncmethodspringboot/service/AsyncService.java @@ -0,0 +1,48 @@ +package github.javaguide.asyncmethodspringboot.service; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.stream.Collectors; + +/** @author shuang.kou */ +@Service +public class AsyncService { + + private static final Logger logger = LoggerFactory.getLogger(AsyncService.class); + + private List movies = + new ArrayList<>( + Arrays.asList( + "Forrest Gump", + "Titanic", + "Spirited Away", + "The Shawshank Redemption", + "Zootopia", + "Farewell ", + "Joker", + "Crawl")); + + /** 示范使用:找到特定字符/字符串开头的电影 */ + @Async + public CompletableFuture> completableFutureTask(String start) { + logger.warn(Thread.currentThread().getName() + "start this task!"); + // 找出所有以 F 开头的电影 + List results = + movies.stream().filter(movie -> movie.startsWith(start)).collect(Collectors.toList()); + // 模拟这是一个耗时的任务 + try { + Thread.sleep(1000L); + } catch (InterruptedException e) { + e.printStackTrace(); + } + // 返回一个已经用给定值完成的新的CompletableFuture。 + return CompletableFuture.completedFuture(results); + } +} diff --git a/async-method-springboot/src/main/resources/application.properties b/async-method-springboot/src/main/resources/application.properties new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/async-method-springboot/src/main/resources/application.properties @@ -0,0 +1 @@ + diff --git a/async-method-springboot/src/test/java/github/javaguide/asyncmethodspringboot/service/AsyncServiceTest.java b/async-method-springboot/src/test/java/github/javaguide/asyncmethodspringboot/service/AsyncServiceTest.java new file mode 100644 index 0000000..9657e66 --- /dev/null +++ b/async-method-springboot/src/test/java/github/javaguide/asyncmethodspringboot/service/AsyncServiceTest.java @@ -0,0 +1,39 @@ +package github.javaguide.asyncmethodspringboot.service; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.stream.Collectors; + +@SpringBootTest +@RunWith(SpringRunner.class) +public class AsyncServiceTest { + + @Autowired AsyncService asyncService; + + @Test + public void testCompletableFutureTask() throws InterruptedException, ExecutionException { + // 开始时间 + long start = System.currentTimeMillis(); + // 开始执行大量的异步任务 + List words = Arrays.asList("F", "T", "S", "Z", "J", "C"); + List>> completableFutureList = + words.stream() + .map(word -> asyncService.completableFutureTask(word)) + .collect(Collectors.toList()); + // CompletableFuture.join()方法可以获取他们的结果并将结果连接起来 + List> results = + completableFutureList.stream().map(CompletableFuture::join).collect(Collectors.toList()); + // 打印结果以及运行程序运行花费时间 + System.out.println("Elapsed time: " + (System.currentTimeMillis() - start)); + System.out.println(results.toString()); + } +} From 365f187ec80e595e8067631b5390c8e07052d278 Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Tue, 1 Oct 2019 15:16:27 +0800 Subject: [PATCH 046/204] Update README.md --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 26617f8..71f3df0 100644 --- a/README.md +++ b/README.md @@ -34,9 +34,12 @@ ### SpringBoot 异常处理 - [SpringBoot 异常处理](./md/springboot-handle-exception.md) +### SpringBoot 异步编程 + +[新手也能看懂的 SpringBoot 异步编程指南][./async-method-springboot/README.md] + ### SpringBoot+Mybatis [整合 SpringBoot+Mybatis](./md/springboot-mybatis.md) @@ -58,3 +61,5 @@ ## 说明 项目 logo 由 [logoly](https://logoly.pro/#/) 生成。 + +[./async-method-springboot/README.md]: \ No newline at end of file From b9ccd8b7dcd76b25a90df9061746437cbe4db634 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Tue, 1 Oct 2019 15:17:26 +0800 Subject: [PATCH 047/204] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 71f3df0..bba25cf 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ ### SpringBoot 异步编程 -[新手也能看懂的 SpringBoot 异步编程指南][./async-method-springboot/README.md] +[新手也能看懂的 SpringBoot 异步编程指南](./async-method-springboot/README.md) ### SpringBoot+Mybatis @@ -62,4 +62,4 @@ 项目 logo 由 [logoly](https://logoly.pro/#/) 生成。 -[./async-method-springboot/README.md]: \ No newline at end of file +[./async-method-springboot/README.md]: From 4d251da110a1374723c22de4866df99a86a4dac2 Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Tue, 1 Oct 2019 15:19:10 +0800 Subject: [PATCH 048/204] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bba25cf..9329352 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ ### SpringBoot 异步编程 -[新手也能看懂的 SpringBoot 异步编程指南](./async-method-springboot/README.md) +[新手也能看懂的 SpringBoot 异步编程指南](./async-method-springboot/README.md) ### SpringBoot+Mybatis From 2174f676e7ec1fa3c6326014bf75d75c47fd9151 Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Tue, 1 Oct 2019 15:20:03 +0800 Subject: [PATCH 049/204] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 9329352..8c0e2aa 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ - [SpringBoot 热部署](#springboot-热部署) - [SpringBoot 定时任务](#springboot-定时任务) - [SpringBoot 异常处理](#springboot-异常处理) + - [SpringBoot 异步编程](#springboot-异步编程) - [SpringBoot+Mybatis](#springbootmybatis) - [SpringBoot+阿里云OSS 存储服务](#springboot阿里云oss-存储服务) - [springboot-dubbo(使用SpringBoot+Dubbo 搭建一个分布式服务)](#springboot-dubbo使用springbootdubbo-搭建一个分布式服务) From 6ae2d811ec3a10b6953881ec84c88edec8a9ac61 Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Tue, 1 Oct 2019 15:32:06 +0800 Subject: [PATCH 050/204] Update README.md --- README.md | 61 +++++++++++-------------------------------------------- 1 file changed, 12 insertions(+), 49 deletions(-) diff --git a/README.md b/README.md index 8c0e2aa..cb54a62 100644 --- a/README.md +++ b/README.md @@ -6,61 +6,24 @@ **如果国内访问缓慢的话,可以通过码云查看:** https://gitee.com/SnailClimb/springboot-guide -### 目录 - -- [重要知识点](#重要知识点) -- [实例](#实例) - - [SpringBoot 热部署](#springboot-热部署) - - [SpringBoot 定时任务](#springboot-定时任务) - - [SpringBoot 异常处理](#springboot-异常处理) - - [SpringBoot 异步编程](#springboot-异步编程) - - [SpringBoot+Mybatis](#springbootmybatis) - - [SpringBoot+阿里云OSS 存储服务](#springboot阿里云oss-存储服务) - - [springboot-dubbo(使用SpringBoot+Dubbo 搭建一个分布式服务)](#springboot-dubbo使用springbootdubbo-搭建一个分布式服务) - ## 重要知识点 -- [RestController VS Controller](./md/RestControllerVSController.md) -- [关于Spring中的参数校验的一点思考](./md/spring-bean-validation) - -## 实例 - -### SpringBoot 热部署 - -[SpringBoot 使用 spring-boot-devtools 热部署](./md/spring-boot-devtools.md) - -### SpringBoot 定时任务 - -[5分钟搞懂如何在Spring Boot中Schedule Tasks](./md/SpringBoot-ScheduleTasks.md) - -### SpringBoot 异常处理 - -[SpringBoot 异常处理](./md/springboot-handle-exception.md) +### 基础 -### SpringBoot 异步编程 +1. [RestController VS Controller](./md/RestControllerVSController.md) +2. [SpringBoot 使用 spring-boot-devtools 热部署](./md/spring-boot-devtools.md) +3. [整合 SpringBoot+Mybatis](./md/springboot-mybatis.md) 、[SpirngBoot2.0+ 的 SpringBoot+Mybatis 多数据源配置](./md/springboot-mybatis-mutipledatasource.md) -[新手也能看懂的 SpringBoot 异步编程指南](./async-method-springboot/README.md) +### 进阶 -### SpringBoot+Mybatis - -[整合 SpringBoot+Mybatis](./md/springboot-mybatis.md) - -[简单地 SpirngBoot2.0+ 的 SpringBoot+Mybatis 多数据源配置](./md/springboot-mybatis-mutipledatasource.md) - -### SpringBoot+阿里云OSS 存储服务 - -[SpringBoot 整合 阿里云OSS 存储服务,快来免费搭建一个自己的图床](./md/springboot-oss.md) - -### SpringBoot+Dubbo - -[超详细,新手都能看懂 !使用SpringBoot+Dubbo 搭建一个分布式服务](./md/springboot-dubbo.md) - -### Spring Security With JWT - -[从零入门 !Spring Security With JWT(含权限验证)](https://github.com/Snailclimb/spring-security-jwt-guide) +1. [关于Spring中的参数校验的一点思考](./md/spring-bean-validation.md) +2. [5分钟搞懂如何在Spring Boot中Schedule Tasks](./md/SpringBoot-ScheduleTasks.md) +3. [SpringBoot 异常处理](./md/springboot-handle-exception.md) +4. [新手也能看懂的 SpringBoot 异步编程指南](./async-method-springboot/README.md) +5. [SpringBoot 整合 阿里云OSS 存储服务,快来免费搭建一个自己的图床](./md/springboot-oss.md) +6. [超详细,新手都能看懂 !使用SpringBoot+Dubbo 搭建一个分布式服务](./md/springboot-dubbo.md) +7. [从零入门 !Spring Security With JWT(含权限验证)](https://github.com/Snailclimb/spring-security-jwt-guide) ## 说明 项目 logo 由 [logoly](https://logoly.pro/#/) 生成。 - -[./async-method-springboot/README.md]: From 538b84f24b0405e523ad4ee52b6af491ffa77744 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Wed, 2 Oct 2019 16:33:08 +0800 Subject: [PATCH 051/204] Delete readme --- springboot-oss/readme | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 springboot-oss/readme diff --git a/springboot-oss/readme b/springboot-oss/readme deleted file mode 100644 index 49918ec..0000000 --- a/springboot-oss/readme +++ /dev/null @@ -1,7 +0,0 @@ -参考:https://blog.csdn.net/HcJsJqJSSM/article/details/80977735 -其他类似博客:https://blog.csdn.net/wonder_dog/article/details/81152307 - -遇到的问题:AliyunOSSConfig类 无法注入到 AliyunOSSConfig类中, -解决办法:在Controller类中注入,然后当做参数传递到上传文件的方法中 - -利用HTML5上传文件并显示在前端预览,以图片为例:https://blog.csdn.net/zhaoxiang66/article/details/79097250 From 5d1eb74d8ec8aac4bb0337f592569aafa3b3128b Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Wed, 2 Oct 2019 16:45:31 +0800 Subject: [PATCH 052/204] feat : add project reference --- README.md | 4 ++-- md/SpringBoot-ScheduleTasks.md | 3 ++- md/spring-bean-validation.md | 4 +++- md/springboot-dubbo.md | 9 ++++++--- md/springboot-handle-exception.md | 2 ++ md/springboot-oss.md | 6 ++++-- 6 files changed, 19 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index cb54a62..bf07924 100644 --- a/README.md +++ b/README.md @@ -10,8 +10,8 @@ ### 基础 -1. [RestController VS Controller](./md/RestControllerVSController.md) -2. [SpringBoot 使用 spring-boot-devtools 热部署](./md/spring-boot-devtools.md) +1. **[RestController VS Controller](./md/RestControllerVSController.md)** +2. [SpringBoot 使用 spring-boot-devtools 进行热部署](./md/spring-boot-devtools.md) 3. [整合 SpringBoot+Mybatis](./md/springboot-mybatis.md) 、[SpirngBoot2.0+ 的 SpringBoot+Mybatis 多数据源配置](./md/springboot-mybatis-mutipledatasource.md) ### 进阶 diff --git a/md/SpringBoot-ScheduleTasks.md b/md/SpringBoot-ScheduleTasks.md index da776e4..9a72282 100644 --- a/md/SpringBoot-ScheduleTasks.md +++ b/md/SpringBoot-ScheduleTasks.md @@ -1,6 +1,6 @@ 很多时候我们都需要为系统建立一个定时任务来帮我们做一些事情,SpringBoot 已经帮我们实现好了一个,我们只需要直接使用即可,当然你也可以不用 SpringBoot 自带的定时任务,整合 Quartz 很多时候也是一个不错的选择。 -本文不涉及 SpringBoot 整合 Quartz 的内容,只演示了如何使用 SpringBoot 自带的实现定时任务的方式。 +本文不涉及 SpringBoot 整合 Quartz 的内容,只演示了如何使用 SpringBoot 自带的实现定时任务的方式。相关代码地址:https://github.com/Snailclimb/springboot-guide/tree/master/springboot-schedule-tast ## Spring Schedule 实现定时任务 @@ -215,3 +215,4 @@ Current Thread : task-3 Fixed Delay Task : The time is now 14:27:36 ``` +相关代码地址:https://github.com/Snailclimb/springboot-guide/tree/master/springboot-schedule-tast \ No newline at end of file diff --git a/md/spring-bean-validation.md b/md/spring-bean-validation.md index e633351..0e7d680 100644 --- a/md/spring-bean-validation.md +++ b/md/spring-bean-validation.md @@ -481,4 +481,6 @@ public class PersonService { ## 参考 - https://reflectoring.io/bean-validation-with-spring-boot/ -- https://www.cnkirito.moe/spring-validation// \ No newline at end of file +- https://www.cnkirito.moe/spring-validation// + +相关代码地址:https://github.com/Snailclimb/springboot-guide/tree/master/bean-validation-demo \ No newline at end of file diff --git a/md/springboot-dubbo.md b/md/springboot-dubbo.md index 938c54d..799c1fc 100644 --- a/md/springboot-dubbo.md +++ b/md/springboot-dubbo.md @@ -131,7 +131,7 @@ mv zookeeper-3.4.12 zookeeper ```shell rm -rf zookeeper-3.4.12.tar.gz -``` +``` ### 3. 进入zookeeper目录,创建data文件夹。 @@ -176,8 +176,7 @@ dataDir=/usr/local/zookeeper/data ![运行 netstat -lntup命令查看网络状态](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-11-20/91151305.jpg) - ----- +---- 注意没有关闭防火墙可能出现的问题!!! @@ -407,3 +406,7 @@ public class DubboConsumerApplication { ### 6. 测试效果 浏览器访问 [http://localhost:8330/hello](http://localhost:8330/hello) 页面返回 Hello world,控制台输出 Hello SnailClimb,和预期一直,使用SpringBoot+Dubbo 搭建第一个简单的分布式服务实验成功! + + + +相关代码地址:https://github.com/Snailclimb/springboot-guide/tree/master/springboot-dubbo \ No newline at end of file diff --git a/md/springboot-handle-exception.md b/md/springboot-handle-exception.md index f06e05b..7bdc984 100644 --- a/md/springboot-handle-exception.md +++ b/md/springboot-handle-exception.md @@ -265,3 +265,5 @@ public class ResponseStatusExceptionController { - status : http status - reason :response 的消息内容 - cause : 抛出的异常 + +相关代码地址:https://github.com/Snailclimb/springboot-guide/tree/master/springboot-handle-exception \ No newline at end of file diff --git a/md/springboot-oss.md b/md/springboot-oss.md index aa2a98d..b932844 100644 --- a/md/springboot-oss.md +++ b/md/springboot-oss.md @@ -2,7 +2,7 @@ [https://help.aliyun.com/product/31815.html?spm=a2c4g.11186623.6.540.4e401c62EyJK5T](https://help.aliyun.com/product/31815.html?spm=a2c4g.11186623.6.540.4e401c62EyJK5T) -本篇文章会介绍到 SpringBoot 整合阿里云OSS 存储服务实现文件上传下载以及简单的查看。其实今天将的应该算的上是一个简单的小案例了,涉及到的知识点还算是比较多。 +本篇文章会介绍到 SpringBoot 整合阿里云OSS 存储服务实现文件上传下载以及简单的查看。其实今天将的应该算的上是一个简单的小案例了,涉及到的知识点还算是比较多。相关代码地址:https://github.com/Snailclimb/springboot-guide/tree/master/springboot-oss 。 @@ -32,7 +32,7 @@ 具有 Java 基础以及SpringBoot 简单基础知识即可。 ### 1.2 环境参数 - + - 开发工具:IDEA - 基础工具:Maven+JDK8 - 所用技术:SpringBoot+阿里云OSS 存储服务 Java 相关API @@ -510,3 +510,5 @@ JS 的内容主要是让我们上传的图片可以预览,就像我们在网 我们终于能够独立利用阿里云 OSS 完成一个自己的图床服务,但是其实如果你想用阿里云OSS当做图床可以直接使用极简图床:[http://jiantuku.com](http://jiantuku.com) 上传图片,比较方便!大家可能心里在想那你特么让我实现个图床干嘛?我觉得通过学习,大家以后可以做很多事情,比如 利用阿里云OSS 存储服务存放自己网站的相关图片。 +相关代码地址:https://github.com/Snailclimb/springboot-guide/tree/master/springboot-oss 。 + From 12471ae1c35af0d8a7c85dc036170f5a1928ede3 Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Wed, 2 Oct 2019 21:30:56 +0800 Subject: [PATCH 053/204] =?UTF-8?q?SpringBoot=E4=BB=8B=E7=BB=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 15 ++++++---- md/start/springboot-introduction.md | 43 +++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 5 deletions(-) create mode 100644 md/start/springboot-introduction.md diff --git a/README.md b/README.md index bf07924..32a352f 100644 --- a/README.md +++ b/README.md @@ -8,20 +8,25 @@ ## 重要知识点 +### 开始 + +1. **[Spring Boot 介绍](./md/start/springboot-introduction.md)** +2. [SpringBoot 开发环境要求](springboot-system-requirements) + ### 基础 1. **[RestController VS Controller](./md/RestControllerVSController.md)** -2. [SpringBoot 使用 spring-boot-devtools 进行热部署](./md/spring-boot-devtools.md) +2. [使用 spring-boot-devtools 进行热部署](./md/spring-boot-devtools.md) 3. [整合 SpringBoot+Mybatis](./md/springboot-mybatis.md) 、[SpirngBoot2.0+ 的 SpringBoot+Mybatis 多数据源配置](./md/springboot-mybatis-mutipledatasource.md) ### 进阶 1. [关于Spring中的参数校验的一点思考](./md/spring-bean-validation.md) 2. [5分钟搞懂如何在Spring Boot中Schedule Tasks](./md/SpringBoot-ScheduleTasks.md) -3. [SpringBoot 异常处理](./md/springboot-handle-exception.md) -4. [新手也能看懂的 SpringBoot 异步编程指南](./async-method-springboot/README.md) -5. [SpringBoot 整合 阿里云OSS 存储服务,快来免费搭建一个自己的图床](./md/springboot-oss.md) -6. [超详细,新手都能看懂 !使用SpringBoot+Dubbo 搭建一个分布式服务](./md/springboot-dubbo.md) +3. [Spring Boot 异常处理](./md/springboot-handle-exception.md) +4. [新手也能看懂的 Spring Boot 异步编程指南](./async-method-springboot/README.md) +5. [Spring Boot 整合 阿里云OSS 存储服务,快来免费搭建一个自己的图床](./md/springboot-oss.md) +6. [超详细,新手都能看懂 !使用Spring Boot+Dubbo 搭建一个分布式服务](./md/springboot-dubbo.md) 7. [从零入门 !Spring Security With JWT(含权限验证)](https://github.com/Snailclimb/spring-security-jwt-guide) ## 说明 diff --git a/md/start/springboot-introduction.md b/md/start/springboot-introduction.md new file mode 100644 index 0000000..e04a9c5 --- /dev/null +++ b/md/start/springboot-introduction.md @@ -0,0 +1,43 @@ +# 一 SpringBoot介绍 + +## 1.1 先从Spring谈起 +我们知道Spring是重量级企业开发框架 **Enterprise JavaBean(EJB)** 的替代平,Spring为企业级Java开发提供了一种相对简单的方法,通过 **依赖注入** 和 **面向切面编程** ,用简单的 **Java对象(Plain Old Java Object,POJO)** 实现了EJB的功能 + +**虽然Spring的组件代码是轻量级的,但它的配置却是重量级的(需要大量XML配置)** 。Spring 2.5引入了基于注解的组件扫描,这消除了大量针对应用程序自身组件的显式XML配置。Spring 3.0引入了基于Java的配置,这是一种类型安全的可重构配置方式,可以代替XML。 + +尽管如此,我们依旧没能逃脱配置的魔爪。开启某些Spring特性时,比如事务管理和Spring MVC,还是需要用XML或Java进行显式配置。启用第三方库时也需要显式配置,比如基于Thymeleaf的Web视图。配置Servlet和过滤器(比如Spring的DispatcherServlet)同样需要在web.xml或Servlet初始化代码里进行显式配置。组件扫描减少了配置量,Java配置让它看上去简洁不少,但Spring还是需要不少配置。 + +光配置这些XML文件都够我们头疼的了,占用了我们大部分时间和精力。除此之外,相关库的依赖非常让人头疼,不同库之间的版本冲突也非常常见。 + +**不过,好消息是:Spring Boot让这一切成为了过去。** + +## 1.2 再来谈谈 Spring Boot + + +**最好直白的介绍莫过于官方的介绍:** + +> Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can “just run”...Most Spring Boot applications need very little Spring configuration.(Spring Boot可以轻松创建独立的生产级基于Spring的应用程序,只要通过 “just run”(可能是run ‘Application’或java -jar 或 tomcat 或 maven插件run 或 shell脚本)便可以运行项目。大部分Spring Boot项目只需要少量的配置即可) + +**简而言之,从本质上来说,Spring Boot就是Spring,它做了那些没有它你自己也会去做的Spring Bean配置。** + +### 1.2.1 为什么需要 Spring Boot? + +Spring Framework旨在简化J2EE企业应用程序开发。Spring Boot Framework旨在简化Spring开发。 + +![why-we-need-springboot](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-7/why-we-need-springboot.png) + +### 1.2.2 Spring Boot的主要优点 + +1. 开发基于 Spring 的应用程序很容易。 +2. Spring Boot 项目所需的开发或工程时间明显减少,通常会提高整体生产力。 +3. Spring Boot不需要编写大量样板代码、XML配置和注释。 +4. Spring引导应用程序可以很容易地与Spring生态系统集成,如Spring JDBC、Spring ORM、Spring Data、Spring Security等。 +5. Spring Boot遵循“固执己见的默认配置”,以减少开发工作(默认配置可以修改)。 +6. Spring Boot 应用程序提供嵌入式HTTP服务器,如Tomcat和Jetty,可以轻松地开发和测试web应用程序。(这点很赞!普通运行Java程序的方式就能运行基于Spring Boot web 项目,省事很多) +7. Spring Boot提供命令行接口(CLI)工具,用于开发和测试Spring Boot应用程序,如Java或Groovy。 +8. Spring Boot提供了多种插件,可以使用内置工具(如Maven和Gradle)开发和测试Spring Boot应用程序。 + + + + + From c947a139d24e171a972eb463e0770f8d57487b55 Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Wed, 2 Oct 2019 21:31:10 +0800 Subject: [PATCH 054/204] =?UTF-8?q?SpringBoot=20=E5=BC=80=E5=8F=91?= =?UTF-8?q?=E7=8E=AF=E5=A2=83=E8=A6=81=E6=B1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- md/start/springboot-system-requirements.md | 30 ++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 md/start/springboot-system-requirements.md diff --git a/md/start/springboot-system-requirements.md b/md/start/springboot-system-requirements.md new file mode 100644 index 0000000..bee1273 --- /dev/null +++ b/md/start/springboot-system-requirements.md @@ -0,0 +1,30 @@ +### JDK + +截止到目前Spring Boot 的最新版本:2.1.8.RELEASE 要求 JDK 版本在 1.8 以上,所以确保你的电脑已经正确下载安装配置了 JDK(推荐 JDK 1.8 版本)。 + +### 构建工具 + +构建工具(本项目涉及的代码大部分会采用 Maven 作为包管理工具): + +| **Build Tool** | **Version** | +| -------------- | ----------- | +| Maven | 3.3+ | +| Gradle | 4.4+ | + +### 开发工具推荐 + +推荐使用 IDEA 进行开发。,最好的 Java 后台开发编辑器,没有之一! + +### Web 服务器 + +Spring Boot支持以下嵌入式servlet容器: + +| **Name** | **Servlet Version** | +| ------------ | ------------------- | +| Tomcat 9.0 | 4.0 | +| Jetty 9.4 | 3.1 | +| Undertow 2.0 | 4.0 | + +您还可以将Spring引导应用程序部署到任何Servlet 3.1+兼容的 Web 容器中。 + +这就是你为什么可以通过直接像运行 普通 Java 项目一样运行 SpringBoot 项目。这样的确省事了很多,方便了我们进行开发,降低了学习难度。 \ No newline at end of file From c2a307954863a945ef15d819a0c842d220d7838c Mon Sep 17 00:00:00 2001 From: Kou Shuang Date: Wed, 2 Oct 2019 23:04:00 +0800 Subject: [PATCH 055/204] =?UTF-8?q?=E7=94=9F=E6=88=90=E5=9C=A8=E7=BA=BF?= =?UTF-8?q?=E9=98=85=E8=AF=BB=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 25 +++++----- docs/.nojekyll | 0 docs/README.md | 35 ++++++++++++++ docs/_coverpage.md | 13 ++++++ .../advanced}/SpringBoot-ScheduleTasks.md | 0 .../advanced}/spring-bean-validation.md | 0 .../advanced/springboot-async.md | 0 {md => docs/advanced}/springboot-dubbo.md | 0 .../advanced}/springboot-handle-exception.md | 0 docs/advanced/springboot-hello-world.md | 39 ++++++++++++++++ {md => docs/advanced}/springboot-oss.md | 0 .../basis}/RestControllerVSController.md | 0 {md => docs/basis}/spring-boot-devtools.md | 0 .../springboot-mybatis-mutipledatasource.md | 0 {md => docs/basis}/springboot-mybatis.md | 0 docs/index.html | 44 ++++++++++++++++++ {md => docs}/start/springboot-introduction.md | 0 .../start/springboot-system-requirements.md | 0 docs/zhao-chen-hvuLPoMM19I-unsplash.jpg | Bin 0 -> 3850099 bytes 19 files changed, 144 insertions(+), 12 deletions(-) create mode 100644 docs/.nojekyll create mode 100644 docs/README.md create mode 100644 docs/_coverpage.md rename {md => docs/advanced}/SpringBoot-ScheduleTasks.md (100%) rename {md => docs/advanced}/spring-bean-validation.md (100%) rename async-method-springboot/README.md => docs/advanced/springboot-async.md (100%) rename {md => docs/advanced}/springboot-dubbo.md (100%) rename {md => docs/advanced}/springboot-handle-exception.md (100%) create mode 100644 docs/advanced/springboot-hello-world.md rename {md => docs/advanced}/springboot-oss.md (100%) rename {md => docs/basis}/RestControllerVSController.md (100%) rename {md => docs/basis}/spring-boot-devtools.md (100%) rename {md => docs/basis}/springboot-mybatis-mutipledatasource.md (100%) rename {md => docs/basis}/springboot-mybatis.md (100%) create mode 100644 docs/index.html rename {md => docs}/start/springboot-introduction.md (100%) rename {md => docs}/start/springboot-system-requirements.md (100%) create mode 100755 docs/zhao-chen-hvuLPoMM19I-unsplash.jpg diff --git a/README.md b/README.md index 32a352f..70b1ad9 100644 --- a/README.md +++ b/README.md @@ -10,25 +10,26 @@ ### 开始 -1. **[Spring Boot 介绍](./md/start/springboot-introduction.md)** -2. [SpringBoot 开发环境要求](springboot-system-requirements) +1. **[Spring Boot 介绍](./docs/start/springboot-introduction.md)** +2. [SpringBoot 开发环境要求](./docs/start/springboot-system-requirements.md) ### 基础 -1. **[RestController VS Controller](./md/RestControllerVSController.md)** -2. [使用 spring-boot-devtools 进行热部署](./md/spring-boot-devtools.md) -3. [整合 SpringBoot+Mybatis](./md/springboot-mybatis.md) 、[SpirngBoot2.0+ 的 SpringBoot+Mybatis 多数据源配置](./md/springboot-mybatis-mutipledatasource.md) +1. **[RestController VS Controller](./docs/basis/RestControllerVSController.md)** +2. [使用 spring-boot-devtools 进行热部署](./docs/basis/spring-boot-devtools.md) +3. [整合 SpringBoot+Mybatis](./docs/basis/springboot-mybatis.md) 、[SpirngBoot2.0+ 的 SpringBoot+Mybatis 多数据源配置](./docs/basis/springboot-mybatis-mutipledatasource.md) ### 进阶 -1. [关于Spring中的参数校验的一点思考](./md/spring-bean-validation.md) -2. [5分钟搞懂如何在Spring Boot中Schedule Tasks](./md/SpringBoot-ScheduleTasks.md) -3. [Spring Boot 异常处理](./md/springboot-handle-exception.md) -4. [新手也能看懂的 Spring Boot 异步编程指南](./async-method-springboot/README.md) -5. [Spring Boot 整合 阿里云OSS 存储服务,快来免费搭建一个自己的图床](./md/springboot-oss.md) -6. [超详细,新手都能看懂 !使用Spring Boot+Dubbo 搭建一个分布式服务](./md/springboot-dubbo.md) +1. [关于Spring中的参数校验的一点思考](./docs/advanced/spring-bean-validation.md) +2. [5分钟搞懂如何在Spring Boot中Schedule Tasks](./docs/advanced/SpringBoot-ScheduleTasks.md) +3. [Spring Boot 异常处理](./docs/advanced/springboot-handle-exception.md) +4. [新手也能看懂的 Spring Boot 异步编程指南](./docs/advanced/springboot-async.md) +5. [Spring Boot 整合 阿里云OSS 存储服务,快来免费搭建一个自己的图床](./docs/advanced/springboot-oss.md) +6. [超详细,新手都能看懂 !使用Spring Boot+Dubbo 搭建一个分布式服务](./docs/advanced/springboot-dubbo.md) 7. [从零入门 !Spring Security With JWT(含权限验证)](https://github.com/Snailclimb/spring-security-jwt-guide) ## 说明 - 项目 logo 由 [logoly](https://logoly.pro/#/) 生成。 +1. 项目 logo 由 [logoly](https://logoly.pro/#/) 生成。 +2. 利用 docsify 生成文档部署在 Github pages: [docsify 官网介绍](https://docsify.js.org/#/) \ No newline at end of file diff --git a/docs/.nojekyll b/docs/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..07c7a6a --- /dev/null +++ b/docs/README.md @@ -0,0 +1,35 @@ +

+ + + +

+ +**如果国内访问缓慢的话,可以通过码云查看:** https://gitee.com/SnailClimb/springboot-guide + +## 重要知识点 + +### 开始 + +1. **[Spring Boot 介绍](./start/springboot-introduction.md)** +2. [SpringBoot 开发环境要求](./start/springboot-system-requirements.md) + +### 基础 + +1. **[RestController VS Controller](./basis/RestControllerVSController.md)** +2. [使用 spring-boot-devtools 进行热部署](./basis/spring-boot-devtools.md) +3. [整合 SpringBoot+Mybatis](./basis/springboot-mybatis.md) 、[SpirngBoot2.0+ 的 SpringBoot+Mybatis 多数据源配置](./basis/springboot-mybatis-mutipledatasource.md) + +### 进阶 + +1. [关于Spring中的参数校验的一点思考](./advanced/spring-bean-validation.md) +2. [5分钟搞懂如何在Spring Boot中Schedule Tasks](./advanced/SpringBoot-ScheduleTasks.md) +3. [Spring Boot 异常处理](./advanced/springboot-handle-exception.md) +4. [新手也能看懂的 Spring Boot 异步编程指南](./advanced/springboot-async.md) +5. [Spring Boot 整合 阿里云OSS 存储服务,快来免费搭建一个自己的图床](./advanced/springboot-oss.md) +6. [超详细,新手都能看懂 !使用Spring Boot+Dubbo 搭建一个分布式服务](./advanced/springboot-dubbo.md) +7. [从零入门 !Spring Security With JWT(含权限验证)](https://github.com/Snailclimb/spring-security-jwt-guide) + +## 说明 + + 项目 logo 由 [logoly](https://logoly.pro/#/) 生成。 + diff --git a/docs/_coverpage.md b/docs/_coverpage.md new file mode 100644 index 0000000..2b7e02f --- /dev/null +++ b/docs/_coverpage.md @@ -0,0 +1,13 @@ +

+ + + +

+ +

Spring Boot 学习/面试指南

+ +[常用资源](https://shimo.im/docs/MuiACIg1HlYfVxrj/) +[GitHub](https://github.com/Snailclimb/springboot-guide) +[开始阅读](#重要知识点) + +![](zhao-chen-hvuLPoMM19I-unsplash.jpg) \ No newline at end of file diff --git a/md/SpringBoot-ScheduleTasks.md b/docs/advanced/SpringBoot-ScheduleTasks.md similarity index 100% rename from md/SpringBoot-ScheduleTasks.md rename to docs/advanced/SpringBoot-ScheduleTasks.md diff --git a/md/spring-bean-validation.md b/docs/advanced/spring-bean-validation.md similarity index 100% rename from md/spring-bean-validation.md rename to docs/advanced/spring-bean-validation.md diff --git a/async-method-springboot/README.md b/docs/advanced/springboot-async.md similarity index 100% rename from async-method-springboot/README.md rename to docs/advanced/springboot-async.md diff --git a/md/springboot-dubbo.md b/docs/advanced/springboot-dubbo.md similarity index 100% rename from md/springboot-dubbo.md rename to docs/advanced/springboot-dubbo.md diff --git a/md/springboot-handle-exception.md b/docs/advanced/springboot-handle-exception.md similarity index 100% rename from md/springboot-handle-exception.md rename to docs/advanced/springboot-handle-exception.md diff --git a/docs/advanced/springboot-hello-world.md b/docs/advanced/springboot-hello-world.md new file mode 100644 index 0000000..6f279ab --- /dev/null +++ b/docs/advanced/springboot-hello-world.md @@ -0,0 +1,39 @@ +## 一 SpringBoot介绍 + +### 1.1 先从Spring谈起 +我们知道Spring是重量级企业开发框架 **Enterprise JavaBean(EJB)** 的替代平,Spring为企业级Java开发提供了一种相对简单的方法,通过 **依赖注入** 和 **面向切面编程** ,用简单的 **Java对象(Plain Old Java Object,POJO)** 实现了EJB的功能 + +**虽然Spring的组件代码是轻量级的,但它的配置却是重量级的(需要大量XML配置)** 。Spring 2.5引入了基于注解的组件扫描,这消除了大量针对应用程序自身组件的显式XML配置。Spring 3.0引入了基于Java的配置,这是一种类型安全的可重构配置方式,可以代替XML。 + +尽管如此,我们依旧没能逃脱配置的魔爪。开启某些Spring特性时,比如事务管理和Spring MVC,还是需要用XML或Java进行显式配置。启用第三方库时也需要显式配置,比如基于Thymeleaf的Web视图。配置Servlet和过滤器(比如Spring的DispatcherServlet)同样需要在web.xml或Servlet初始化代码里进行显式配置。组件扫描减少了配置量,Java配置让它看上去简洁不少,但Spring还是需要不少配置。 + +光配置这些XML文件都够我们头疼的了,占用了我们大部分时间和精力。除此之外,相关库的依赖非常让人头疼,不同库之间的版本冲突也非常常见。 + +**不过,好消息是:Spring Boot让这一切成为了过去。** + +### 1.2 再来谈谈Spring Boot + + +**最好直白的介绍莫过于官方的介绍:** + +> Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can “just run”...Most Spring Boot applications need very little Spring configuration.(Spring Boot可以轻松创建独立的生产级基于Spring的应用程序,只要通过 “just run”(可能是run ‘Application’或java -jar 或 tomcat 或 maven插件run 或 shell脚本)便可以运行项目。大部分Spring Boot项目只需要少量的配置即可) + +**关于Spring Boot的一些误解:** + +- **Spring Boot不是应用服务器:** Spring Boot可以把Web应用程序变为可自执行的JAR文件,不用部署到传统Java应用服务器里就能在命令行里运行。Spring Boot在应用程序里嵌入了一个Servlet容器(Tomcat,Jetty或Undertow),以此实现这一功能。但这是内嵌的Servlet容器提供的功能,不是Spring Boot实现的 +- **Spring Boot也没有实现诸如JPA或JMS(Java Message Service,Java消息服务)之类的企业级Java规范。** 它的确支持不少企业级Java规范,但是要在Spring里自动配置支持那些特性的Bean。例如,Spring Boot没有实现JPA,不过它自动配置了某个JPA实现(比如Hibernate)的Bean,以此支持JPA +- **Spring Boot没有引入任何形式的代码生成,而是利用了Spring 4的条件化配置特性,以及Maven和Gradle提供的传递依赖解析,以此实现Spring应用程序上下文里的自动配置。** + + +**简而言之,从本质上来说,Spring Boot就是Spring,它做了那些没有它你自己也会去做的Spring Bean配置。** + +### Spring Boot的主要优点 + +1. 开发基于 Spring 的应用程序很容易。 +2. Spring Boot 项目所需的开发或工程时间明显减少,通常会提高整体生产力。 +3. Spring Boot不需要编写大量样板代码、XML配置和注释。 +4. Spring引导应用程序可以很容易地与Spring生态系统集成,如Spring JDBC、Spring ORM、Spring Data、Spring Security等。 +5. Spring Boot遵循“固执己见的默认配置”,以减少开发工作(默认配置可以修改)。 +6. Spring Boot 应用程序提供嵌入式HTTP服务器,如Tomcat和Jetty,可以轻松地开发和测试web应用程序。(这点很赞!普通运行Java程序的方式就能运行基于Spring Boot web 项目,省事很多) +7. Spring Boot提供命令行接口(CLI)工具,用于开发和测试Spring Boot应用程序,如Java或Groovy。 +8. Spring Boot提供了多种插件,可以使用内置工具(如Maven和Gradle)开发和测试Spring Boot应用程序。 \ No newline at end of file diff --git a/md/springboot-oss.md b/docs/advanced/springboot-oss.md similarity index 100% rename from md/springboot-oss.md rename to docs/advanced/springboot-oss.md diff --git a/md/RestControllerVSController.md b/docs/basis/RestControllerVSController.md similarity index 100% rename from md/RestControllerVSController.md rename to docs/basis/RestControllerVSController.md diff --git a/md/spring-boot-devtools.md b/docs/basis/spring-boot-devtools.md similarity index 100% rename from md/spring-boot-devtools.md rename to docs/basis/spring-boot-devtools.md diff --git a/md/springboot-mybatis-mutipledatasource.md b/docs/basis/springboot-mybatis-mutipledatasource.md similarity index 100% rename from md/springboot-mybatis-mutipledatasource.md rename to docs/basis/springboot-mybatis-mutipledatasource.md diff --git a/md/springboot-mybatis.md b/docs/basis/springboot-mybatis.md similarity index 100% rename from md/springboot-mybatis.md rename to docs/basis/springboot-mybatis.md diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000..e46ee24 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,44 @@ + + + + + + Document + + + + + + + +
+ + + + + + + + + \ No newline at end of file diff --git a/md/start/springboot-introduction.md b/docs/start/springboot-introduction.md similarity index 100% rename from md/start/springboot-introduction.md rename to docs/start/springboot-introduction.md diff --git a/md/start/springboot-system-requirements.md b/docs/start/springboot-system-requirements.md similarity index 100% rename from md/start/springboot-system-requirements.md rename to docs/start/springboot-system-requirements.md diff --git a/docs/zhao-chen-hvuLPoMM19I-unsplash.jpg b/docs/zhao-chen-hvuLPoMM19I-unsplash.jpg new file mode 100755 index 0000000000000000000000000000000000000000..75eac3f63056d6dd00b2e3697bceb3a06ec69dec GIT binary patch literal 3850099 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 z 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�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