add: samples
diff --git a/samples/foo/src/main/java/com/supwisdom/leaveschool/foo/Application.java b/samples/foo/src/main/java/com/supwisdom/leaveschool/foo/Application.java
new file mode 100644
index 0000000..cf36972
--- /dev/null
+++ b/samples/foo/src/main/java/com/supwisdom/leaveschool/foo/Application.java
@@ -0,0 +1,18 @@
+package com.supwisdom.leaveschool.foo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * 启动后访问:
+ * 1. http://localhost:8080/foo/greeting/abc
+ * 2. http://localhost:8080/foo/model?name=abc&age=10
+ */
+@SpringBootApplication
+public class Application {
+
+ public static void main(String[] args) {
+ SpringApplication.run(Application.class, args);
+ }
+
+}
diff --git a/samples/foo/src/main/java/com/supwisdom/leaveschool/foo/controller/FooController.java b/samples/foo/src/main/java/com/supwisdom/leaveschool/foo/controller/FooController.java
new file mode 100644
index 0000000..120cb3c
--- /dev/null
+++ b/samples/foo/src/main/java/com/supwisdom/leaveschool/foo/controller/FooController.java
@@ -0,0 +1,45 @@
+package com.supwisdom.leaveschool.foo.controller;
+
+import com.supwisdom.leaveschool.foo.model.Foo;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import javax.validation.Valid;
+
+@Controller
+@RequestMapping("/foo")
+public class FooController {
+
+ /**
+ * http://localhost:8080/foo/greeting/abc
+ *
+ * @param name
+ * @param model
+ * @return
+ */
+ @GetMapping(path = "/greeting/{name}")
+ public String greeting(@PathVariable String name, Model model) {
+ model.addAttribute("name", "Good " + name);
+ return "foo/greeting";
+ }
+
+ /**
+ * good请求:
+ * http://localhost:8080/foo/model?name=abc&age=10
+ *
+ * bad请求:
+ * http://localhost:8080/foo/model?name=abc&age=-1
+ *
+ * @param foo
+ * @return
+ */
+ @GetMapping(path = "/model")
+ public String model(@Valid @ModelAttribute Foo foo) {
+ return "foo/model";
+ }
+
+}
diff --git a/samples/foo/src/main/java/com/supwisdom/leaveschool/foo/controller/FooRestController.java b/samples/foo/src/main/java/com/supwisdom/leaveschool/foo/controller/FooRestController.java
new file mode 100644
index 0000000..d8d1f98
--- /dev/null
+++ b/samples/foo/src/main/java/com/supwisdom/leaveschool/foo/controller/FooRestController.java
@@ -0,0 +1,60 @@
+package com.supwisdom.leaveschool.foo.controller;
+
+import com.supwisdom.leaveschool.foo.model.BarException;
+import com.supwisdom.leaveschool.foo.model.Foo;
+import com.supwisdom.leaveschool.foo.model.FooException;
+import org.springframework.util.MimeTypeUtils;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * curl -H 'Accept:application/json' 'http://localhost:8080/foo-rest/greeting/abc'
+ */
+@RestController
+@RequestMapping("/foo-rest")
+public class FooRestController {
+
+ /**
+ * curl -H 'Accept:application/json' 'http://localhost:8080/foo-rest/greeting/abc'
+ *
+ * @param name
+ * @return
+ */
+ @GetMapping(path = "/greeting/{name}", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ public Map<String, Object> greeting(@PathVariable String name) {
+ Map<String, Object> result = new HashMap<>();
+ result.put("message", "Good " + name);
+ return result;
+ }
+
+ /**
+ * good请求:
+ * curl -H 'Accept=application/json' 'http://localhost:8080/foo-rest/greeting?name=abc&age=1
+ * bad请求:
+ * curl -H 'Accept=application/json' 'http://localhost:8080/foo-rest/greeting?name=abc&age=-1
+ *
+ * @param foo
+ * @return
+ */
+ @GetMapping(path = "/model", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ public Foo model(@Valid Foo foo) {
+ return foo;
+ }
+
+ @GetMapping(path = "/exception1", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ public Map<String, Object> exception1() {
+ throw new FooException();
+ }
+
+ @GetMapping(path = "/exception2", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ public Map<String, Object> exception2() {
+ throw new BarException();
+ }
+
+}
diff --git a/samples/foo/src/main/java/com/supwisdom/leaveschool/foo/model/BarException.java b/samples/foo/src/main/java/com/supwisdom/leaveschool/foo/model/BarException.java
new file mode 100644
index 0000000..b0bb8b7
--- /dev/null
+++ b/samples/foo/src/main/java/com/supwisdom/leaveschool/foo/model/BarException.java
@@ -0,0 +1,22 @@
+package com.supwisdom.leaveschool.foo.model;
+
+public class BarException extends RuntimeException {
+ public BarException() {
+ }
+
+ public BarException(String message) {
+ super(message);
+ }
+
+ public BarException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public BarException(Throwable cause) {
+ super(cause);
+ }
+
+ public BarException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ }
+}
diff --git a/samples/foo/src/main/java/com/supwisdom/leaveschool/foo/model/Foo.java b/samples/foo/src/main/java/com/supwisdom/leaveschool/foo/model/Foo.java
new file mode 100644
index 0000000..f86f7f2
--- /dev/null
+++ b/samples/foo/src/main/java/com/supwisdom/leaveschool/foo/model/Foo.java
@@ -0,0 +1,31 @@
+package com.supwisdom.leaveschool.foo.model;
+
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+
+public class Foo {
+
+ @NotNull
+ @NotEmpty
+ private String name;
+
+ @Min(0)
+ private int age;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ public void setAge(int age) {
+ this.age = age;
+ }
+}
diff --git a/samples/foo/src/main/java/com/supwisdom/leaveschool/foo/model/FooException.java b/samples/foo/src/main/java/com/supwisdom/leaveschool/foo/model/FooException.java
new file mode 100644
index 0000000..0542d65
--- /dev/null
+++ b/samples/foo/src/main/java/com/supwisdom/leaveschool/foo/model/FooException.java
@@ -0,0 +1,8 @@
+package com.supwisdom.leaveschool.foo.model;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+@ResponseStatus(code = HttpStatus.BAD_REQUEST, reason = "Foo Reason")
+public class FooException extends RuntimeException {
+}
diff --git a/samples/foo/src/main/resources/META-INF/spring-configuration-metadata.json b/samples/foo/src/main/resources/META-INF/spring-configuration-metadata.json
new file mode 100644
index 0000000..1013fc1
--- /dev/null
+++ b/samples/foo/src/main/resources/META-INF/spring-configuration-metadata.json
@@ -0,0 +1,10 @@
+{
+ "groups": [
+ {
+ "sourceType": "com.supwisdom.leaveschool.foo.mvc.ExceptionErrorProperties",
+ "name": "exception.error-map",
+ "type": "java.util.Map",
+ "description": "Exception class -> error string的映射"
+ }
+ ]
+}
diff --git a/samples/foo/src/main/resources/application.yaml b/samples/foo/src/main/resources/application.yaml
new file mode 100644
index 0000000..e70d463
--- /dev/null
+++ b/samples/foo/src/main/resources/application.yaml
@@ -0,0 +1,9 @@
+spring:
+ application:
+ name: sample-foo
+
+infras:
+ mvc:
+ error:
+ error-map:
+ com.supwisdom.leaveschool.foo.model.BarException: Bar Reason
diff --git a/samples/foo/src/main/resources/templates/foo/greeting.html b/samples/foo/src/main/resources/templates/foo/greeting.html
new file mode 100644
index 0000000..f1c9c34
--- /dev/null
+++ b/samples/foo/src/main/resources/templates/foo/greeting.html
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML>
+<html xmlns:th="http://www.thymeleaf.org">
+<head>
+ <title>Getting Started: Serving Web Content</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+</head>
+<body>
+<p th:text="'Hello, ' + ${name} + '!'" />
+</body>
+</html>
diff --git a/samples/foo/src/main/resources/templates/foo/model.html b/samples/foo/src/main/resources/templates/foo/model.html
new file mode 100644
index 0000000..166c688
--- /dev/null
+++ b/samples/foo/src/main/resources/templates/foo/model.html
@@ -0,0 +1,11 @@
+<!DOCTYPE HTML>
+<html xmlns:th="http://www.thymeleaf.org">
+<head>
+ <title>Getting Started: Serving Web Content</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+</head>
+<body>
+<p th:text="'Hello, ' + ${foo.name} + '!'"/>
+<p th:text="'Your are ' + ${foo.age} + ' years old'"/>
+</body>
+</html>