将CrudApiController,MapBeanUtils抽取到common项目
diff --git a/samples/common/pom.xml b/samples/common/pom.xml
index 864192d..4c60df4 100644
--- a/samples/common/pom.xml
+++ b/samples/common/pom.xml
@@ -16,6 +16,12 @@
<dependencies>
<dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-web</artifactId>
+ <optional>true</optional>
+ </dependency>
+
+ <dependency>
<groupId>com.supwisdom.infras</groupId>
<artifactId>infras-data-jpa</artifactId>
</dependency>
diff --git a/samples/common/src/main/java/com/supwisdom/leaveschool/common/controller/api/CrudApiController.java b/samples/common/src/main/java/com/supwisdom/leaveschool/common/controller/api/CrudApiController.java
new file mode 100644
index 0000000..eb45af1
--- /dev/null
+++ b/samples/common/src/main/java/com/supwisdom/leaveschool/common/controller/api/CrudApiController.java
@@ -0,0 +1,337 @@
+package com.supwisdom.leaveschool.common.controller.api;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.collections.IteratorUtils;
+import org.springframework.data.domain.Page;
+import org.springframework.http.HttpStatus;
+import org.springframework.util.MimeTypeUtils;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+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.ResponseBody;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+import com.supwisdom.leaveschool.common.domain.ABaseDomain;
+import com.supwisdom.leaveschool.common.model.PagerRequestModel;
+import com.supwisdom.leaveschool.common.model.PagerResponseModel;
+import com.supwisdom.leaveschool.common.repository.BaseJpaRepository;
+import com.supwisdom.leaveschool.common.util.DomainUtils;
+
+public abstract class CrudApiController<D extends ABaseDomain, R extends BaseJpaRepository<D>> {
+
+ protected abstract R getRepository();
+
+ /**
+ *
+ * curl -i -s -X GET -H 'Accept:application/json' 'http://localhost:10010/${API_PATH_PREFIX}/domains'
+ * curl -i -s -X GET -H 'Accept:application/json' 'http://localhost:10010/${API_PATH_PREFIX}/domains?pageIndex=2&pageSize=50'
+ * curl -i -s -X GET -H 'Accept:application/json' 'http://localhost:10010/${API_PATH_PREFIX}/domains?pageIndex=0&pageSize=20&mapBean[code]=code&mapBean[name]=name&mapBean[status]=1'
+ * curl -i -s -X GET -H 'Accept:application/json' 'http://localhost:10010/${API_PATH_PREFIX}/domains?pageIndex=0&pageSize=20&mapBean[code]=code&mapBean[name]=name&mapBean[status]=0'
+ *
+ * response success:
+ *
+ * {
+ * "pageIndex":0,
+ * "pageSize":20,
+ * "mapBean":null,
+ * "pageCount":1,
+ * "recordCount":1,
+ * "items":[
+ * {
+ * "id":"ff80808164feb8990164feba0de50000",
+ * "companyId":"1",
+ * "deleted":false,
+ * "addAccount":"group","addTime":"2018-08-03T07:39:23.000+0000",
+ * "editAccount":null,"editTime":null,
+ * "deleteAccount":null,"deleteTime":null,
+ * "code":"test001",
+ * "name":"测试001",
+ * "memo":"测试001备注",
+ * "status":"1"
+ * }
+ * ]
+ * }
+ *
+ * response error 401:
+ *
+ * {
+ * "timestamp":"2018-08-03T08:48:25.777+0000",
+ * "status":401,
+ * "error":"Http Status 401",
+ * "message":"Unauthorized",
+ * "path":"/${API_PATH_PREFIX}/domains"
+ * }
+ *
+ * @param pagerRequestModel
+ * @return
+ */
+ @GetMapping(produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public PagerResponseModel<D> list(PagerRequestModel pagerRequestModel) {
+
+ Page<D> page = getRepository().selectPageList(pagerRequestModel.getPageIndex(), pagerRequestModel.getPageSize(), pagerRequestModel.getMapBean());
+
+ @SuppressWarnings("unchecked")
+ List<D> list = IteratorUtils.toList(page.iterator());
+
+ PagerResponseModel<D> pagerResponseModel = PagerResponseModel.of(pagerRequestModel);
+ pagerResponseModel.setPageCount(page.getTotalPages());
+ pagerResponseModel.setRecordCount(page.getTotalElements());
+ pagerResponseModel.setItems(list);
+
+ return pagerResponseModel;
+ }
+
+ /**
+ *
+ * curl -i -s -X GET -H 'Accept:application/json' 'http://localhost:10010/${API_PATH_PREFIX}/domains/1'
+ *
+ * response success:
+ *
+ * {
+ * "id":"ff80808164feb8990164feba0de50000",
+ * "companyId":"1",
+ * "deleted":false,
+ * "addAccount":"group","addTime":"2018-08-03T07:39:23.000+0000",
+ * "editAccount":null,"editTime":null,
+ * "deleteAccount":null,"deleteTime":null,
+ * "code":"test001",
+ * "name":"测试001",
+ * "memo":"测试001备注",
+ * "status":"1"
+ * }
+ *
+ * response error 401:
+ *
+ * {
+ * "timestamp":"2018-08-03T08:43:26.080+0000",
+ * "status":401,
+ * "error":"Http Status 401",
+ * "message":"Unauthorized",
+ * "path":"/${API_PATH_PREFIX}/domains/ff80808164fecf640164fed269480000"
+ * }
+ *
+ * response error 500:
+ *
+ * {
+ * "timestamp":"2018-08-03T07:44:07.963+0000",
+ * "status":500,
+ * "error":"Internal Server Error",
+ * "exception":"java.lang.RuntimeException",
+ * "message":"exception.get.domain.not.exist",
+ * "path":"/${API_PATH_PREFIX}/domains/1"
+ * }
+ *
+ * @param id
+ * @return
+ */
+ @GetMapping(path = "/{id}", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public D get(@PathVariable("id") String id) {
+
+ if (id == null || id.length() == 0) {
+ throw new RuntimeException("exception.get.id.must.not.empty"); // FIXME: RestException
+ }
+
+ D d = getRepository().selectById(id);
+
+ if (d == null) {
+ throw new RuntimeException("exception.get.domain.not.exist"); // FIXME: RestException
+ }
+
+ return d;
+ }
+
+ /**
+ *
+ * curl -i -s -X POST -H 'Content-Type:application/json' -H 'Accept:application/json' 'http://localhost:10010/${API_PATH_PREFIX}/domains' \
+ * -d '{"code":"test001","name":"测试001","memo":"测试001备注","status":"1","addAccount":"admin"}'
+ *
+ * response success:
+ *
+ * {
+ * "success":"info.save.success"
+ * }
+ *
+ * response error 401:
+ *
+ * {
+ * "timestamp":"2018-08-03T08:48:25.777+0000",
+ * "status":401,
+ * "error":"Http Status 401",
+ * "message":"Unauthorized",
+ * "path":"/${API_PATH_PREFIX}/domains"
+ * }
+ *
+ * response error: // FIXME: save error
+ *
+ * {
+ * "timestamp":"2018-08-03T07:45:43.436+0000",
+ * "status":500,
+ * "error":"Internal Server Error",
+ * "exception":"org.springframework.dao.DataIntegrityViolationException",
+ * "message":"could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement",
+ * "path":"/${API_PATH_PREFIX}/domains"
+ * }
+ *
+ * @param group
+ * @return
+ */
+ @PostMapping(consumes = MimeTypeUtils.APPLICATION_JSON_VALUE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public Map<String, Object> save(@RequestBody D d) {
+
+ @SuppressWarnings("unused")
+ D ret = getRepository().insert(d);
+
+ Map<String, Object> res = new HashMap<String, Object>();
+ res.put("success", "info.save.success");
+
+ return res;
+ }
+
+ /**
+ *
+ * curl -i -s -X PUT -H 'Content-Type:application/json' -H 'Accept:application/json' 'http://localhost:10010/${API_PATH_PREFIX}/domains' \
+ * -d '{"id":"1","status":"0"}'
+ *
+ * response success:
+ *
+ * {
+ * "success":"info.update.success"
+ * }
+ *
+ * response error 401:
+ *
+ * {
+ * "timestamp":"2018-08-03T08:48:25.777+0000",
+ * "status":401,
+ * "error":"Http Status 401",
+ * "message":"Unauthorized",
+ * "path":"/${API_PATH_PREFIX}/domains"
+ * }
+ *
+ * curl -i -s -X PUT -H 'Content-Type:application/json' -H 'Accept:application/json' 'http://localhost:10010/${API_PATH_PREFIX}/domains' \
+ * -d '{"status":"0"}'
+ *
+ * response error:
+ *
+ * {
+ * "timestamp":"2018-08-03T07:50:52.327+0000",
+ * "status":500,
+ * "error":"Internal Server Error",
+ * "exception":"java.lang.RuntimeException",
+ * "message":"exception.update.id.must.not.empty",
+ * "path":"/${API_PATH_PREFIX}/domains"
+ * }
+ *
+ * curl -i -s -X PUT -H 'Content-Type:application/json' -H 'Accept:application/json' 'http://localhost:10010/${API_PATH_PREFIX}/domains' \
+ * -d '{"id":"1","status":"0"}'
+ *
+ * response error:
+ *
+ * {
+ * "timestamp":"2018-08-03T07:48:24.774+0000",
+ * "status":500,
+ * "error":"Internal Server Error",
+ * "exception":"java.lang.RuntimeException",
+ * "message":"exception.update.domain.not.exist",
+ * "path":"/${API_PATH_PREFIX}/domains"
+ * }
+ *
+ * @param group
+ * @return
+ */
+ @PutMapping(consumes = MimeTypeUtils.APPLICATION_JSON_VALUE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public Map<String, Object> update(@RequestBody D d) {
+
+ if (d.getId() == null || d.getId().length() == 0) {
+ throw new RuntimeException("exception.update.id.must.not.empty"); // FIXME: RestException
+ }
+
+ D tmp = getRepository().selectById(d.getId());
+ if (tmp == null) {
+ throw new RuntimeException("exception.update.domain.not.exist"); // FIXME: RestException
+ }
+
+ tmp = DomainUtils.merge(d, tmp);
+
+ @SuppressWarnings("unused")
+ D ret = getRepository().update(tmp);
+ getRepository().flush();
+
+ Map<String, Object> res = new HashMap<String, Object>();
+ res.put("success", "info.update.success");
+
+ return res;
+ }
+
+ /**
+ *
+ * curl -i -s -X DELETE -H 'Accept:application/json' 'http://localhost:10010/${API_PATH_PREFIX}/domains/1'
+ *
+ * response success:
+ *
+ * {
+ * "success":"info.delete.success"
+ * }
+ *
+ * response error 401:
+ *
+ * {
+ * "timestamp":"2018-08-03T08:48:25.777+0000",
+ * "status":401,
+ * "error":"Http Status 401",
+ * "message":"Unauthorized",
+ * "path":"/${API_PATH_PREFIX}/domains/1"
+ * }
+ *
+ * response error 500:
+ *
+ * {
+ * "timestamp":"2018-08-03T08:03:16.364+0000",
+ * "status":500,
+ * "error":"Internal Server Error",
+ * "exception":"java.lang.RuntimeException",
+ * "message":"exception.delete.domain.not.exist",
+ * "path":"/${API_PATH_PREFIX}/domains/1"
+ * }
+ *
+ * @param id
+ * @return
+ */
+ @DeleteMapping(path = "/{id}", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public Map<String, Object> delete(@PathVariable("id") String id) {
+
+ if (id == null || id.length() == 0) {
+ throw new RuntimeException("exception.delete.id.must.not.empty"); // FIXME: RestException
+ }
+
+ D tmp = getRepository().selectById(id);
+ if (tmp == null) {
+ throw new RuntimeException("exception.delete.domain.not.exist"); // FIXME: RestException
+ }
+
+ getRepository().delete(tmp);
+
+ Map<String, Object> res = new HashMap<String, Object>();
+ res.put("success", "info.delete.success");
+
+ return res;
+ }
+
+
+}
diff --git a/samples/common/src/main/java/com/supwisdom/leaveschool/common/util/MapBeanUtils.java b/samples/common/src/main/java/com/supwisdom/leaveschool/common/util/MapBeanUtils.java
new file mode 100644
index 0000000..e788bac
--- /dev/null
+++ b/samples/common/src/main/java/com/supwisdom/leaveschool/common/util/MapBeanUtils.java
@@ -0,0 +1,150 @@
+package com.supwisdom.leaveschool.common.util;
+
+import java.util.Map;
+
+public class MapBeanUtils {
+
+ /**
+ * 判断 mapBean 中的 key 是否存在;若存在,则判断是否有值
+ *
+ * @param mapBean
+ * @param key
+ * @return
+ */
+ public static boolean containsValue(Map<String, Object> mapBean, String key) {
+
+ if (!mapBean.containsKey(key)) {
+ return false;
+ }
+
+ if (mapBean.get(key) == null) {
+ return false;
+ }
+
+ if (String.valueOf(mapBean.get(key)).isEmpty()) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * 获取 mapBean 中 key 的 value,若不存在,则返回 null
+ *
+ * @param mapBean
+ * @param key
+ * @return
+ */
+ public static String getString(Map<String, Object> mapBean, String key) {
+
+ return getString(mapBean, key, null);
+ }
+
+ /**
+ * 获取 mapBean 中 key 的 value,若不存在,则返回 defaultValue
+ *
+ * @param mapBean
+ * @param key
+ * @param defaultValue
+ * @return
+ */
+ public static String getString(Map<String, Object> mapBean, String key, String defaultValue) {
+
+ if (containsValue(mapBean, key)) {
+ return String.valueOf(mapBean.get(key));
+ }
+
+ return defaultValue;
+ }
+
+ /**
+ * 获取 mapBean 中 key 的 value,若不存在,则返回 false
+ *
+ * @param mapBean
+ * @param key
+ * @return
+ */
+ public static boolean getBoolean(Map<String, Object> mapBean, String key) {
+
+ return getBoolean(mapBean, key, false);
+ }
+
+ /**
+ * 获取 mapBean 中 key 的 value,若不存在,则返回 defaultValue
+ *
+ * @param mapBean
+ * @param key
+ * @param defaultValue
+ * @return
+ */
+ public static boolean getBoolean(Map<String, Object> mapBean, String key, Boolean defaultValue) {
+
+ if (containsValue(mapBean, key)) {
+ Boolean b = Boolean.valueOf(String.valueOf(mapBean.get(key)));
+ return b == null ? defaultValue : b.booleanValue();
+ }
+
+ return defaultValue;
+ }
+
+ /**
+ * 获取 mapBean 中 key 的 value,若不存在,则返回 -1
+ *
+ * @param mapBean
+ * @param key
+ * @return
+ */
+ public static int getInteger(Map<String, Object> mapBean, String key) {
+
+ return getInteger(mapBean, key, -1);
+ }
+
+ /**
+ * 获取 mapBean 中 key 的 value,若不存在,则返回 defaultValue
+ *
+ * @param mapBean
+ * @param key
+ * @param defaultValue
+ * @return
+ */
+ public static int getInteger(Map<String, Object> mapBean, String key, Integer defaultValue) {
+
+ if (containsValue(mapBean, key)) {
+ Integer i = Integer.valueOf(String.valueOf(mapBean.get(key)));
+ return i == null ? defaultValue : i.intValue();
+ }
+
+ return defaultValue;
+ }
+
+ /**
+ * 获取 mapBean 中 key 的 value,若不存在,则返回 -1L
+ *
+ * @param mapBean
+ * @param key
+ * @return
+ */
+ public static long getLong(Map<String, Object> mapBean, String key) {
+
+ return getLong(mapBean, key, -1L);
+ }
+
+ /**
+ * 获取 mapBean 中 key 的 value,若不存在,则返回 defaultValue
+ *
+ * @param mapBean
+ * @param key
+ * @param defaultValue
+ * @return
+ */
+ public static long getLong(Map<String, Object> mapBean, String key, Long defaultValue) {
+
+ if (containsValue(mapBean, key)) {
+ Long l = Long.valueOf(String.valueOf(mapBean.get(key)));
+ return l == null ? defaultValue : l.longValue();
+ }
+
+ return defaultValue;
+ }
+
+}