zhouhao 8 lat temu
rodzic
commit
b6508a830f
44 zmienionych plików z 1197 dodań i 265 usunięć
  1. 47 0
      hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/CreateController.java
  2. 4 43
      hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/CrudController.java
  3. 45 0
      hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/DeleteController.java
  4. 5 5
      hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/GenericEntityController.java
  5. 53 0
      hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/QueryController.java
  6. 37 0
      hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/UpdateController.java
  7. 45 0
      hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/UpdateEntityController.java
  8. 1 1
      hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/message/ResponseMessage.java
  9. 6 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/builder/EasyOrmSqlBuilder.java
  10. 6 6
      hsweb-commons/hsweb-commons-entity/src/main/java/org/hswebframework/web/commons/entity/PagerResult.java
  11. 77 0
      hsweb-commons/hsweb-commons-entity/src/main/java/org/hswebframework/web/commons/entity/SimpleTreeSortSupportEntity.java
  12. 3 3
      hsweb-commons/hsweb-commons-entity/src/main/java/org/hswebframework/web/commons/entity/SortSupport.java
  13. 13 84
      hsweb-commons/hsweb-commons-entity/src/main/java/org/hswebframework/web/commons/entity/TreeSortSupportEntity.java
  14. 16 13
      hsweb-commons/hsweb-commons-entity/src/main/java/org/hswebframework/web/commons/entity/TreeSupport.java
  15. 2 2
      hsweb-commons/hsweb-commons-service/hsweb-commons-service-api/src/main/java/org/hswebframework/web/service/CreateEntityService.java
  16. 6 9
      hsweb-commons/hsweb-commons-service/hsweb-commons-service-api/src/main/java/org/hswebframework/web/service/CrudService.java
  17. 2 2
      hsweb-commons/hsweb-commons-service/hsweb-commons-service-api/src/main/java/org/hswebframework/web/service/InsertService.java
  18. 5 7
      hsweb-commons/hsweb-commons-service/hsweb-commons-service-api/src/main/java/org/hswebframework/web/service/QueryByEntityService.java
  19. 33 0
      hsweb-commons/hsweb-commons-service/hsweb-commons-service-api/src/main/java/org/hswebframework/web/service/QueryService.java
  20. 36 0
      hsweb-commons/hsweb-commons-service/hsweb-commons-service-api/src/main/java/org/hswebframework/web/service/TreeService.java
  21. 22 13
      hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/main/java/org/hswebframework/web/service/AbstractService.java
  22. 104 0
      hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/main/java/org/hswebframework/web/service/AbstractTreeSortService.java
  23. 17 4
      hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/main/java/org/hswebframework/web/service/DefaultDSLQueryService.java
  24. 20 25
      hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/main/java/org/hswebframework/web/service/DefaultQueryByEntityService.java
  25. 20 28
      hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/main/java/org/hswebframework/web/service/GenericEntityService.java
  26. 5 7
      hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/main/java/org/hswebframework/web/service/GenericService.java
  27. 14 0
      hsweb-commons/hsweb-commons-utils/pom.xml
  28. 50 0
      hsweb-commons/hsweb-commons-utils/src/main/java/org/hswebframework/web/AopUtils.java
  29. 10 0
      hsweb-commons/hsweb-commons-utils/src/main/java/org/hswebframework/web/ThreadLocalUtils.java
  30. 32 0
      hsweb-concurrent/hsweb-concurrent-cache/pom.xml
  31. 32 0
      hsweb-concurrent/hsweb-concurrent-counter/hsweb-concurrent-counter-api/pom.xml
  32. 44 0
      hsweb-concurrent/hsweb-concurrent-counter/hsweb-concurrent-counter-api/src/main/java/org/hswebframework/web/concurrent/counter/Counter.java
  33. 36 0
      hsweb-concurrent/hsweb-concurrent-counter/hsweb-concurrent-counter-api/src/main/java/org/hswebframework/web/concurrent/counter/CounterManager.java
  34. 36 0
      hsweb-concurrent/hsweb-concurrent-counter/pom.xml
  35. 32 0
      hsweb-concurrent/hsweb-concurrent-lock/pom.xml
  36. 38 0
      hsweb-concurrent/pom.xml
  37. 2 2
      hsweb-core/src/main/java/org/hswebframework/web/BusinessException.java
  38. 6 0
      hsweb-i18n/hsweb-i18n-cn/src/main/resources/messages_zh_CN.properties
  39. 48 2
      hsweb-starter/hsweb-spring-boot-starter/src/main/java/org/hswebframework/web/starter/HswebAutoConfiguration.java
  40. 93 0
      hsweb-starter/hsweb-spring-boot-starter/src/main/java/org/hswebframework/web/starter/RestControllerExceptionTranslator.java
  41. 28 6
      hsweb-starter/hsweb-spring-boot-starter/src/main/java/org/hswebframework/web/starter/convert/FastJsonHttpMessageConverter.java
  42. 50 0
      hsweb-starter/hsweb-spring-boot-starter/src/main/java/org/hswebframework/web/starter/resolver/AuthorizationArgumentResolver.java
  43. 4 3
      hsweb-starter/hsweb-spring-boot-starter/src/main/java/org/hswebframework/web/starter/resolver/JsonParamResolver.java
  44. 12 0
      pom.xml

+ 47 - 0
hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/CreateController.java

@@ -0,0 +1,47 @@
+/*
+ * Copyright 2016 http://www.hswebframework.org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.controller;
+
+import org.hswebframework.web.authorization.annotation.Authorize;
+import org.hswebframework.web.controller.message.ResponseMessage;
+import org.hswebframework.web.logging.AccessLogger;
+import org.hswebframework.web.service.InsertService;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+import static org.hswebframework.web.controller.message.ResponseMessage.ok;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public interface CreateController<E, PK> {
+
+    InsertService<E, PK> getService();
+
+    @Authorize(action = "add")
+    @PostMapping
+    @AccessLogger("添加数据")
+    @ResponseStatus(HttpStatus.CREATED)
+    default ResponseMessage add(@RequestBody E data) {
+        return ok(getService().insert(data));
+    }
+}

+ 4 - 43
hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/CrudController.java

@@ -18,57 +18,18 @@
 
 package org.hswebframework.web.controller;
 
-import org.hswebframework.web.authorization.Authorize;
 import org.hswebframework.web.commons.entity.Entity;
-import org.hswebframework.web.controller.message.ResponseMessage;
-import org.hswebframework.web.logging.AccessLogger;
 import org.hswebframework.web.service.CrudService;
-import org.springframework.http.HttpStatus;
-import org.springframework.web.bind.annotation.*;
-
-import static org.hswebframework.web.controller.message.ResponseMessage.ok;
 
 /**
  * TODO 完成注释
  *
  * @author zhouhao
  */
-public interface CrudController<B, PK, Q extends Entity> {
-
-    CrudService<B, PK, Q> getService();
-
-    @Authorize(action = "read")
-    @GetMapping
-    @AccessLogger("查询")
-    default ResponseMessage list(Q param) {
-        return ok(getService().selectPager(param));
-    }
-
-    @Authorize(action = "read")
-    @GetMapping(path = "/{id}")
-    @AccessLogger("根据主键查询")
-    default ResponseMessage getByPrimaryKey(PK id) {
-        return ok(getService().selectByPk(id));
-    }
-
-    @Authorize(action = "update")
-    @PutMapping(path = "/{id}")
-    @AccessLogger("根据主键修改数据")
-    ResponseMessage updateByPrimaryKey(@PathVariable PK id, @RequestBody B data);
-
-    @Authorize(action = "delete")
-    @DeleteMapping(path = "/{id}")
-    @AccessLogger("根据主键删除数据")
-    default ResponseMessage deleteByPrimaryKey(@PathVariable PK id) {
-        return ok(getService().deleteByPk(id));
-    }
+public interface CrudController<E, PK, Q extends Entity>
+        extends QueryController<E, PK, Q>, UpdateController<E, PK>, CreateController<E, PK>, DeleteController<PK> {
 
-    @Authorize(action = "add")
-    @PostMapping
-    @AccessLogger("添加数据")
-    @ResponseStatus(HttpStatus.CREATED)
-    default ResponseMessage add(@RequestBody B data) {
-        return ok(getService().insert(data));
-    }
+    @SuppressWarnings("unchecked")
+    CrudService<E, PK> getService();
 
 }

+ 45 - 0
hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/DeleteController.java

@@ -0,0 +1,45 @@
+/*
+ * Copyright 2016 http://www.hswebframework.org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.controller;
+
+import org.hswebframework.web.authorization.annotation.Authorize;
+import org.hswebframework.web.controller.message.ResponseMessage;
+import org.hswebframework.web.logging.AccessLogger;
+import org.hswebframework.web.service.DeleteService;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+
+import static org.hswebframework.web.controller.message.ResponseMessage.ok;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public interface DeleteController<PK> {
+
+    DeleteService<PK> getService();
+
+    @Authorize(action = "delete")
+    @DeleteMapping(path = "/{id}")
+    @AccessLogger("根据主键删除数据")
+    default ResponseMessage deleteByPrimaryKey(@PathVariable PK id) {
+        return ok(getService().deleteByPk(id));
+    }
+
+}

+ 5 - 5
hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/GenericEntityController.java

@@ -18,8 +18,8 @@
 
 package org.hswebframework.web.controller;
 
+import org.hswebframework.web.commons.entity.Entity;
 import org.hswebframework.web.commons.entity.GenericEntity;
-import org.hswebframework.web.commons.entity.param.QueryParamEntity;
 import org.hswebframework.web.controller.message.ResponseMessage;
 import org.hswebframework.web.service.CrudService;
 import org.springframework.web.bind.annotation.PathVariable;
@@ -32,13 +32,13 @@ import static org.hswebframework.web.controller.message.ResponseMessage.ok;
  *
  * @author zhouhao
  */
-public interface GenericEntityController<B extends GenericEntity<PK>, PK>
-        extends CrudController<B, PK, QueryParamEntity> {
+public interface GenericEntityController<E extends GenericEntity<PK>, PK, Q extends Entity>
+        extends CrudController<E, PK, Q> {
 
-    CrudService<B, PK, QueryParamEntity> getService();
+    CrudService<E, PK> getService();
 
     @Override
-    default ResponseMessage updateByPrimaryKey(@PathVariable PK id, @RequestBody B data) {
+    default ResponseMessage updateByPrimaryKey(@PathVariable PK id, @RequestBody E data) {
         data.setId(id);
         return ok(getService().updateByPk(data));
     }

+ 53 - 0
hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/QueryController.java

@@ -0,0 +1,53 @@
+/*
+ * Copyright 2016 http://www.hswebframework.org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.controller;
+
+import org.hswebframework.web.authorization.annotation.Authorize;
+import org.hswebframework.web.commons.entity.Entity;
+import org.hswebframework.web.controller.message.ResponseMessage;
+import org.hswebframework.web.logging.AccessLogger;
+import org.hswebframework.web.service.QueryByEntityService;
+import org.hswebframework.web.service.QueryService;
+import org.springframework.web.bind.annotation.GetMapping;
+
+import static org.hswebframework.web.controller.message.ResponseMessage.ok;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public interface QueryController<E, PK, Q extends Entity> {
+
+    <T extends QueryByEntityService<E> & QueryService<E, PK>> T getService();
+
+    @Authorize(action = "read")
+    @GetMapping
+    @AccessLogger("查询")
+    default ResponseMessage list(Q param) {
+        return ok(getService().selectPager(param));
+    }
+
+    @Authorize(action = "read")
+    @GetMapping(path = "/{id}")
+    @AccessLogger("根据主键查询")
+    default ResponseMessage getByPrimaryKey(PK id) {
+        return ok(getService().selectByPk(id));
+    }
+
+}

+ 37 - 0
hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/UpdateController.java

@@ -0,0 +1,37 @@
+/*
+ * Copyright 2016 http://www.hswebframework.org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.controller;
+
+import org.hswebframework.web.authorization.annotation.Authorize;
+import org.hswebframework.web.controller.message.ResponseMessage;
+import org.hswebframework.web.logging.AccessLogger;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public interface UpdateController<E, PK> {
+    @Authorize(action = "update")
+    @PutMapping(path = "/{id}")
+    @AccessLogger("根据主键修改数据")
+    ResponseMessage updateByPrimaryKey(@PathVariable PK id, @RequestBody E data);
+}

+ 45 - 0
hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/UpdateEntityController.java

@@ -0,0 +1,45 @@
+/*
+ * Copyright 2016 http://www.hswebframework.org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.controller;
+
+import org.hswebframework.web.authorization.annotation.Authorize;
+import org.hswebframework.web.commons.entity.GenericEntity;
+import org.hswebframework.web.controller.message.ResponseMessage;
+import org.hswebframework.web.logging.AccessLogger;
+import org.hswebframework.web.service.UpdateService;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public interface UpdateEntityController<E extends GenericEntity<PK>, PK> extends UpdateController<E, PK> {
+
+    UpdateService<E> getService();
+
+    @Authorize(action = "update")
+    @PutMapping(path = "/{id}")
+    @AccessLogger("根据主键修改数据")
+    default ResponseMessage updateByPrimaryKey(@PathVariable PK id, @RequestBody E data) {
+        data.setId(id);
+        return ResponseMessage.ok(getService().updateByPk(data));
+    }
+}

+ 1 - 1
hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/message/ResponseMessage.java

@@ -253,7 +253,7 @@ public class ResponseMessage implements Serializable {
     public static ResponseMessage error(String message, int code) {
         ResponseMessage response = new ResponseMessage();
         response.setCode(code);
-        response.setData(message);
+        response.setMessage(message);
         return response;
     }
 

+ 6 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/builder/EasyOrmSqlBuilder.java

@@ -212,6 +212,9 @@ public class EasyOrmSqlBuilder {
     }
 
     public String buildSelectFields(String resultMapId, String tableName, QueryParam param) {
+        if (param == null) {
+            return "*";
+        }
         if (param.isPaging() && Pager.get() == null) {
             Pager.doPaging(param.getPageIndex(), param.getPageSize());
         }
@@ -239,6 +242,9 @@ public class EasyOrmSqlBuilder {
     }
 
     public String buildOrder(String resultMapId, String tableName, QueryParam param) {
+        if (param == null) {
+            return "";
+        }
         RDBTableMetaData tableMetaData = createMeta(tableName, resultMapId);
         SqlAppender appender = new SqlAppender(" order by ");
         param.getSorts().stream()

+ 6 - 6
hsweb-commons/hsweb-commons-entity/src/main/java/org/hswebframework/web/commons/entity/PagerResult.java

@@ -21,16 +21,16 @@ package org.hswebframework.web.commons.entity;
 
 import java.util.List;
 
-public class PagerResult<B> implements Entity {
+public class PagerResult<E> implements Entity {
     private static final long serialVersionUID = -6171751136953308027L;
     private int total;
 
-    private List<B> data;
+    private List<E> data;
 
     public PagerResult() {
     }
 
-    public PagerResult(int total, List<B> data) {
+    public PagerResult(int total, List<E> data) {
         this.total = total;
         this.data = data;
     }
@@ -39,16 +39,16 @@ public class PagerResult<B> implements Entity {
         return total;
     }
 
-    public PagerResult<B> setTotal(int total) {
+    public PagerResult<E> setTotal(int total) {
         this.total = total;
         return this;
     }
 
-    public List<B> getData() {
+    public List<E> getData() {
         return data;
     }
 
-    public PagerResult<B> setData(List<B> data) {
+    public PagerResult<E> setData(List<E> data) {
         this.data = data;
         return this;
     }

+ 77 - 0
hsweb-commons/hsweb-commons-entity/src/main/java/org/hswebframework/web/commons/entity/SimpleTreeSortSupportEntity.java

@@ -0,0 +1,77 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.commons.entity;
+
+import org.hswebframework.web.Describe;
+
+/**
+ * 支持树形结构,排序的实体类,要使用树形结构,排序功能的实体类直接继承该类
+ */
+public abstract class SimpleTreeSortSupportEntity<PK> extends SimpleGenericEntity<PK>
+        implements TreeSortSupportEntity<PK> {
+    /**
+     * 父级类别
+     */
+    @Describe("父级类别ID")
+    private PK parentId;
+
+    /**
+     * 树结构编码,用于快速查找, 每一层由4位字符组成,用-分割
+     * 如第一层:0001 第二层:0001-0001 第三层:0001-0001-0001
+     */
+    @Describe("树识别码")
+    private String treeCode;
+
+    /**
+     * 排序索引
+     */
+    @Describe("排序索引")
+    private long sortIndex;
+
+    @Override
+    public String getTreeCode() {
+        return treeCode;
+    }
+
+    @Override
+    public void setTreeCode(String treeCode) {
+        this.treeCode = treeCode;
+    }
+
+    @Override
+    public PK getParentId() {
+        return parentId;
+    }
+
+    @Override
+    public void setParentId(PK parentId) {
+        this.parentId = parentId;
+    }
+
+    @Override
+    public long getSortIndex() {
+        return sortIndex;
+    }
+
+    @Override
+    public void setSortIndex(long sortIndex) {
+        this.sortIndex = sortIndex;
+    }
+
+}

+ 3 - 3
hsweb-commons/hsweb-commons-entity/src/main/java/org/hswebframework/web/commons/entity/SortSupport.java

@@ -18,13 +18,13 @@
 
 package org.hswebframework.web.commons.entity;
 
-public interface SortSupport extends Comparable<SortSupport>, Entity {
+public interface SortSupportEntity extends Comparable<SortSupportEntity>, Entity {
 
     long getSortIndex();
 
-    SortSupport setSortIndex(long sortIndex);
+    void setSortIndex(long sortIndex);
 
-    default int compareTo(SortSupport support) {
+    default int compareTo(SortSupportEntity support) {
         if (support == null) return -1;
         return Long.compare(getSortIndex(), support.getSortIndex());
     }

+ 13 - 84
hsweb-commons/hsweb-commons-entity/src/main/java/org/hswebframework/web/commons/entity/TreeSortSupportEntity.java

@@ -1,95 +1,24 @@
 /*
+ * Copyright 2016 http://www.hswebframework.org
  *
- *  * Copyright 2016 http://www.hswebframework.org
- *  *
- *  * Licensed under the Apache License, Version 2.0 (the "License");
- *  * you may not use this file except in compliance with the License.
- *  * You may obtain a copy of the License at
- *  *
- *  *     http://www.apache.org/licenses/LICENSE-2.0
- *  *
- *  * Unless required by applicable law or agreed to in writing, software
- *  * distributed under the License is distributed on an "AS IS" BASIS,
- *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  * See the License for the specific language governing permissions and
- *  * limitations under the License.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
  *
  */
 
 package org.hswebframework.web.commons.entity;
 
-import org.hswebframework.web.Describe;
-
 /**
  * 支持树形结构,排序的实体类,要使用树形结构,排序功能的实体类直接继承该类
  */
-public abstract class TreeSortSupportEntity extends SimpleGenericEntity<String> implements TreeSupport, SortSupport {
-
-    /**
-     * 父级类别
-     */
-    @Describe("父级类别ID")
-    private String parentId;
-
-    /**
-     * 树结构编码,用于快速查找, 每一层由4位字符组成,用-分割
-     * 如第一层:0001 第二层:0001-0001 第三层:0001-0001-0001
-     */
-    @Describe("树识别码")
-    private String treeCode;
-
-    /**
-     * 排序索引
-     */
-    @Describe("排序索引")
-    private long sortIndex;
-
-    @Override
-    public String getTreeCode() {
-        return treeCode;
-    }
-
-    @Override
-    public void setTreeCode(String treeCode) {
-        this.treeCode = treeCode;
-    }
-
-    @Override
-    public String getParentId() {
-        return parentId;
-    }
-
-    @Override
-    public void setParentId(String parentId) {
-        this.parentId = parentId;
-    }
-
-    @Override
-    public long getSortIndex() {
-        return sortIndex;
-    }
-
-    @Override
-    public TreeSortSupportEntity setSortIndex(long sortIndex) {
-        this.sortIndex = sortIndex;
-        return this;
-    }
-
-    public interface Property {
-        /**
-         * 父级类别
-         */
-        String parentId = "parentId";
-
-        /**
-         * 树结构编码,用于快速查找, 每一层由4位字符组成,用-分割
-         * 如第一层:0001 第二层:0001-0001 第三层:0001-0001-0001
-         */
-        String treeCode = "treeCode";
-
-        /**
-         * 排序索引
-         */
-        String sortIndex = "sortIndex";
-    }
+public interface TreeSortSupportEntity<PK> extends TreeSupportEntity<PK>, SortSupportEntity {
 }

+ 16 - 13
hsweb-commons/hsweb-commons-entity/src/main/java/org/hswebframework/web/commons/entity/TreeSupport.java

@@ -25,20 +25,23 @@ import org.hswebframwork.utils.StringUtils;
 
 import java.util.List;
 
-public interface TreeSupport extends Entity {
-    String getId();
+public interface TreeSupportEntity<PK> extends GenericEntity<PK> {
 
-    void setId(String id);
+    String id = "id";
+
+    String treeCode = "treeCode";
+
+    String parentId = "parentId";
 
     String getTreeCode();
 
     void setTreeCode(String treeCode);
 
-    String getParentId();
+    PK getParentId();
 
-    void setParentId(String parentId);
+    void setParentId(PK parentId);
 
-    <T extends TreeSupport> List<T> getChildren();
+    <T extends TreeSupportEntity<PK>> List<T> getChildren();
 
     static String getParentTreeCode(String treeCode) {
         if (treeCode == null || treeCode.length() < 4) return null;
@@ -52,28 +55,28 @@ public interface TreeSupport extends Entity {
      *
      * @param parent 树结构的根节点
      * @param target 目标集合,转换后的数据将直接添加({@link List#add(Object)})到这个集合.
-     * @param <T>    继承{@link TreeSupport}的类型
+     * @param <T>    继承{@link TreeSupportEntity}的类型
      */
-    static <T extends TreeSupport> void expandTree2List(T parent, List<T> target) {
+    static <T extends TreeSupportEntity<PK>, PK> void expandTree2List(TreeSupportEntity<PK> parent, List<T> target, IDGenerator<PK> idGenerator) {
         List<T> children = parent.getChildren();
         if (parent.getTreeCode() == null) {
             parent.setTreeCode(RandomUtil.randomChar(4));
         }
         if (children != null) {
-            String pid = parent.getId();
+            PK pid = parent.getId();
             if (pid == null) {
-                pid = IDGenerator.MD5.generate();
+                pid = idGenerator.generate();
                 parent.setId(pid);
             }
             for (int i = 0; i < children.size(); i++) {
                 T child = children.get(i);
-                if (child instanceof SortSupport && parent instanceof SortSupport) {
-                    ((SortSupport) child).setSortIndex(StringUtils.toLong(((SortSupport) parent).getSortIndex() + "0" + (i + 1)));
+                if (child instanceof SortSupportEntity && parent instanceof SortSupportEntity) {
+                    ((SortSupportEntity) child).setSortIndex(StringUtils.toLong(((SortSupportEntity) parent).getSortIndex() + "0" + (i + 1)));
                 }
                 child.setParentId(pid);
                 child.setTreeCode(parent.getTreeCode() + "-" + RandomUtil.randomChar(4));
                 target.add(child);
-                expandTree2List(child, target);
+                expandTree2List(child, target, idGenerator);
             }
         }
     }

+ 2 - 2
hsweb-commons/hsweb-commons-service/hsweb-commons-service-api/src/main/java/org/hswebframework/web/service/CreateEntityService.java

@@ -28,11 +28,11 @@ package org.hswebframework.web.service;
  * @author zhouhao
  * @since 3.0
  */
-public interface CreateEntityService<B> {
+public interface CreateEntityService<E> {
     /**
      * 创建实体
      *
      * @return 实体
      */
-    B createEntity();
+    E createEntity();
 }

+ 6 - 9
hsweb-commons/hsweb-commons-service/hsweb-commons-service-api/src/main/java/org/hswebframework/web/service/CrudService.java

@@ -18,20 +18,17 @@
 
 package org.hswebframework.web.service;
 
-import org.hswebframework.web.commons.entity.Entity;
-
 /**
  * 通用Service,实现增删改查
  *
  * @author zhouhao
  * @since 3.0
  */
-public interface CrudService<B, PK, Q extends Entity> extends
-        QueryByEntityService<B, Q>,
-        UpdateService<B>,
-        InsertService<B, PK>,
+public interface CrudService<E, PK> extends
+        QueryByEntityService<E>,
+        UpdateService<E>,
+        InsertService<E, PK>,
         DeleteService<PK>,
-        CreateEntityService<B> {
-
-    B selectByPk(PK id);
+        CreateEntityService<E>,
+        QueryService<E, PK> {
 }

+ 2 - 2
hsweb-commons/hsweb-commons-service/hsweb-commons-service-api/src/main/java/org/hswebframework/web/service/InsertService.java

@@ -21,7 +21,7 @@ package org.hswebframework.web.service;
 /**
  * @author zhouhao
  */
-public interface InsertService<B,Pk> {
+public interface InsertService<E, PK> {
 
     /**
      * 添加一条数据
@@ -29,5 +29,5 @@ public interface InsertService<B,Pk> {
      * @param data 要添加的数据
      * @return 添加后生成的主键
      */
-    Pk insert(B data);
+    PK insert(E data);
 }

+ 5 - 7
hsweb-commons/hsweb-commons-service/hsweb-commons-service-api/src/main/java/org/hswebframework/web/service/QueryByEntityService.java

@@ -23,14 +23,12 @@ import org.hswebframework.web.commons.entity.PagerResult;
 
 import java.util.List;
 
-public interface QueryByEntityService<B, Q extends Entity> extends Service {
-    PagerResult<B> selectPager(Q param);
+public interface QueryByEntityService<E> extends Service {
+    PagerResult<E> selectPager(Entity param);
 
-    List<B> select(Q param);
+    List<E> select(Entity param);
 
-    List<B> select();
+    int count(Entity param);
 
-    int count(Q param);
-
-    B selectSingle(Q param);
+    E selectSingle(Entity param);
 }

+ 33 - 0
hsweb-commons/hsweb-commons-service/hsweb-commons-service-api/src/main/java/org/hswebframework/web/service/QueryService.java

@@ -0,0 +1,33 @@
+/*
+ * Copyright 2016 http://www.hswebframework.org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.service;
+
+import java.util.List;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public interface QueryService<E, PK> {
+    E selectByPk(PK id);
+
+    List<E> select();
+
+    int count();
+}

+ 36 - 0
hsweb-commons/hsweb-commons-service/hsweb-commons-service-api/src/main/java/org/hswebframework/web/service/TreeService.java

@@ -0,0 +1,36 @@
+/*
+ * Copyright 2016 http://www.hswebframework.org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.service;
+
+import org.hswebframework.web.commons.entity.TreeSupportEntity;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public interface TreeService<E extends TreeSupportEntity, PK> extends Service {
+    List<E> selectChildNode(PK parentId);
+
+    List<E> selectAllChildNode(PK parentId);
+
+    int updateBatch(Collection<E> data);
+}

+ 22 - 13
hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/main/java/org/hswebframework/web/service/AbstractService.java

@@ -17,22 +17,31 @@ import javax.validation.Validator;
  *
  * @author zhouhao
  */
-public abstract class AbstractService<B extends Entity, PK> implements CreateEntityService<B>, Service {
+public abstract class AbstractService<E extends Entity, PK> implements CreateEntityService<E>, Service {
     protected Logger logger = LoggerFactory.getLogger(this.getClass());
 
-    @Autowired(required = false)
     protected Validator validator;
 
-    @Autowired(required = false)
     protected EntityFactory entityFactory;
 
-    private Class<B>  beanType;
-    private Class<PK> primaryKeyType;
+    @Autowired(required = false)
+    public void setValidator(Validator validator) {
+        this.validator = validator;
+    }
+
+    @Autowired(required = false)
+    public void setEntityFactory(EntityFactory entityFactory) {
+        this.entityFactory = entityFactory;
+    }
+
+    protected Class<E> entityType;
+
+    protected Class<PK> primaryKeyType;
 
     @SuppressWarnings("unchecked")
     public AbstractService() {
         primaryKeyType = (Class<PK>) ClassUtils.getGenericType(this.getClass(), 1);
-        beanType = (Class<B>) ClassUtils.getGenericType(this.getClass(), 0);
+        entityType = (Class<E>) ClassUtils.getGenericType(this.getClass(), 0);
     }
 
     protected boolean entityFactoryIsEnabled() {
@@ -42,12 +51,12 @@ public abstract class AbstractService<B extends Entity, PK> implements CreateEnt
         return null != entityFactory;
     }
 
-    protected Class<B> getEntityRealType() {
+    protected Class<E> getEntityRealType() {
         return entityFactory.getInstanceType(getEntityType());
     }
 
-    protected Class<B> getEntityType() {
-        return beanType;
+    protected Class<E> getEntityType() {
+        return entityType;
     }
 
     protected Class<PK> getPrimaryKeyType() {
@@ -55,7 +64,7 @@ public abstract class AbstractService<B extends Entity, PK> implements CreateEnt
     }
 
     @Override
-    public B createEntity() {
+    public E createEntity() {
         if (!entityFactoryIsEnabled()) {
             throw new UnsupportedOperationException("{unsupported_operation}");
         }
@@ -84,7 +93,7 @@ public abstract class AbstractService<B extends Entity, PK> implements CreateEnt
         }
     }
 
-    protected void tryValidate(B bean) {
+    protected void tryValidate(E bean) {
         if (validator == null) {
             logger.warn("validator is null!");
             return;
@@ -95,11 +104,11 @@ public abstract class AbstractService<B extends Entity, PK> implements CreateEnt
             throw new ValidationException(results);
     }
 
-    public void assertNotNull(Object data) {
+    public static void assertNotNull(Object data) {
         assertNotNull(data, "{data_not_found}");
     }
 
-    public void assertNotNull(Object data, String message) {
+    public static void assertNotNull(Object data, String message) {
         if (null == data) throw new NotFoundException(message);
     }
 

+ 104 - 0
hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/main/java/org/hswebframework/web/service/AbstractTreeSortService.java

@@ -0,0 +1,104 @@
+/*
+ * Copyright 2016 http://www.hswebframework.org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.service;
+
+import org.hswebframework.web.commons.entity.TreeSortSupportEntity;
+import org.hswebframework.web.commons.entity.TreeSupportEntity;
+import org.hswebframework.web.id.IDGenerator;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.Assert;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public abstract class AbstractTreeSortService<E extends TreeSortSupportEntity<PK>, PK>
+        extends GenericEntityService<E, PK> implements TreeService<E, PK> {
+
+    protected abstract IDGenerator<PK> getIDGenerator();
+
+    @Override
+    @Transactional(readOnly = true)
+    public List<E> selectAllChildNode(PK parentId) {
+        assertNotNull(parentId);
+        E old = selectByPk(parentId);
+        assertNotNull(old);
+        return createQuery().where().like$(TreeSupportEntity.treeCode, old.getTreeCode()).noPaging().list();
+    }
+
+    @Override
+    @Transactional(readOnly = true)
+    public List<E> selectChildNode(PK parentId) {
+        assertNotNull(parentId);
+        return createQuery().where(TreeSupportEntity.parentId, parentId).noPaging().list();
+    }
+
+    @Override
+    public PK insert(E entity) {
+        entity.setId(getIDGenerator().generate());
+        List<E> childrenList = new ArrayList<>();
+        TreeSupportEntity.expandTree2List(entity, childrenList, getIDGenerator());
+        super.insert(entity);
+        childrenList.forEach(this::saveOrUpdateForSingle);
+        return entity.getId();
+    }
+
+    public int updateBatch(Collection<E> data) {
+        Assert.notNull(data);
+        return data.stream().map(this::updateByPk).reduce(Math::addExact).orElse(0);
+    }
+
+    @Override
+    public int updateByPk(E entity) {
+        Assert.notNull(entity);
+        List<E> childrenList = new ArrayList<>();
+        TreeSupportEntity.expandTree2List(entity, childrenList, getIDGenerator());
+        return this.saveOrUpdateForSingle(entity) +
+                childrenList.stream()
+                        .map(this::saveOrUpdateForSingle)
+                        .reduce(Math::addExact)
+                        .orElse(0);
+    }
+
+    public int saveOrUpdateForSingle(E entity) {
+        Assert.notNull(entity);
+        PK id = entity.getId();
+        if (null == id || this.selectByPk(id) == null) {
+            if (null == id)
+                entity.setId(getIDGenerator().generate());
+            super.insert(entity);
+            return 1;
+        }
+        return super.updateByPk(entity);
+    }
+
+    @Override
+    public int deleteByPk(PK id) {
+        E old = selectByPk(id);
+        assertNotNull(old);
+        return DefaultDSLDeleteService.createDelete(getDao())
+                // where tree_code like 'treeCode%'
+                .where().like$(TreeSupportEntity.treeCode, old.getTreeCode())
+                .exec();
+    }
+}

+ 17 - 4
hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/main/java/org/hswebframework/web/service/DefaultDSLQueryService.java

@@ -19,13 +19,24 @@
 package org.hswebframework.web.service;
 
 import org.hsweb.ezorm.core.dsl.Query;
+import org.hswebframework.web.commons.entity.Entity;
 import org.hswebframework.web.commons.entity.param.QueryParamEntity;
 import org.hswebframework.web.dao.dynamic.QueryByBeanDao;
 
 import java.util.List;
 
-public interface DefaultDSLQueryService<B>
-        extends DefaultQueryByEntityService<B> {
+public interface DefaultDSLQueryService<E, PK>
+        extends DefaultQueryByEntityService<E>, QueryService<E, PK> {
+
+    @Override
+    default List<E> select() {
+        return createQuery().noPaging().list();
+    }
+
+    @Override
+    default int count() {
+        return createQuery().total();
+    }
 
     /**
      * 创建本服务的dsl查询操作对象
@@ -39,11 +50,12 @@ public interface DefaultDSLQueryService<B>
      * @see org.hsweb.ezorm.core.Conditional
      * @since 3.0
      */
-    default Query<B, QueryParamEntity> createQuery() {
-        Query<B, QueryParamEntity> query = Query.empty(new QueryParamEntity());
+    default Query<E, QueryParamEntity> createQuery() {
+        Query<E, QueryParamEntity> query = Query.empty(new QueryParamEntity());
         query.setListExecutor(this::select);
         query.setTotalExecutor(this::count);
         query.setSingleExecutor(this::selectSingle);
+        query.noPaging();
         return query;
     }
 
@@ -71,6 +83,7 @@ public interface DefaultDSLQueryService<B>
             if (null == list || list.size() == 0) return null;
             else return list.get(0);
         });
+        query.noPaging();
         return query;
     }
 }

+ 20 - 25
hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/main/java/org/hswebframework/web/service/DefaultQueryByEntityService.java

@@ -20,29 +20,31 @@ package org.hswebframework.web.service;
 
 import org.hsweb.ezorm.core.dsl.Query;
 import org.hsweb.ezorm.core.param.QueryParam;
+import org.hswebframework.web.commons.entity.Entity;
 import org.hswebframework.web.commons.entity.PagerResult;
 import org.hswebframework.web.commons.entity.param.QueryParamEntity;
 import org.hswebframework.web.dao.dynamic.QueryByBeanDao;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
-public interface DefaultQueryByEntityService<B>
-        extends QueryByEntityService<B, QueryParamEntity> {
-    QueryByBeanDao<B> getDao();
+public interface DefaultQueryByEntityService<E>
+        extends QueryByEntityService<E> {
+
+    QueryByBeanDao<E> getDao();
 
     @Override
-    default PagerResult<B> selectPager(QueryParamEntity param) {
-        PagerResult<B> pagerResult = new PagerResult<>();
-        param.setPaging(false);
+    default PagerResult<E> selectPager(Entity param) {
+        PagerResult<E> pagerResult = new PagerResult<>();
         int total = getDao().count(param);
         pagerResult.setTotal(total);
         if (total == 0) {
-            pagerResult.setData(new ArrayList<>());
+            pagerResult.setData(Collections.emptyList());
         } else {
             //根据实际记录数量重新指定分页参数
-            param.rePaging(total);
+            if (param instanceof QueryParamEntity)
+                ((QueryParamEntity) param).rePaging(total);
             pagerResult.setData(getDao().query(param));
         }
         return pagerResult;
@@ -65,20 +67,11 @@ public interface DefaultQueryByEntityService<B>
      */
     @Override
     @Transactional(readOnly = true)
-    default List<B> select(QueryParamEntity param) {
+    default List<E> select(Entity param) {
+        if (param == null) param = QueryParamEntity.empty();
         return getDao().query(param);
     }
 
-    /**
-     * 查询所有数据
-     *
-     * @return 所有数据
-     */
-    @Override
-    @Transactional(readOnly = true)
-    default List<B> select() {
-        return getDao().query(new QueryParamEntity());
-    }
 
     /**
      * 查询记录总数,用于分页等操作。查询条件同 {@link DefaultQueryByEntityService#select}
@@ -88,7 +81,8 @@ public interface DefaultQueryByEntityService<B>
      */
     @Override
     @Transactional(readOnly = true)
-    default int count(QueryParamEntity param) {
+    default int count(Entity param) {
+        if (param == null) param = QueryParamEntity.empty();
         return getDao().count(param);
     }
 
@@ -97,13 +91,14 @@ public interface DefaultQueryByEntityService<B>
      *
      * @param param 查询条件
      * @return 单个结果
-     * @see this#select(QueryParamEntity)
+     * @see this#select(Entity)
      */
     @Override
     @Transactional(readOnly = true)
-    default B selectSingle(QueryParamEntity param) {
-        param.doPaging(0, 1);
-        List<B> list = this.select(param);
+    default E selectSingle(Entity param) {
+        if (param instanceof QueryParamEntity)
+            ((QueryParamEntity) param).doPaging(0, 1);
+        List<E> list = this.select(param);
         if (list.size() == 0) return null;
         else return list.get(0);
     }

+ 20 - 28
hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/main/java/org/hswebframework/web/service/GenericEntityService.java

@@ -19,18 +19,9 @@
 package org.hswebframework.web.service;
 
 import org.hswebframework.web.commons.entity.GenericEntity;
-import org.hswebframework.web.commons.entity.factory.EntityFactory;
-import org.hswebframework.web.NotFoundException;
 import org.hswebframework.web.dao.CrudDao;
-import org.hswebframework.web.validate.SimpleValidateResults;
-import org.hswebframework.web.validate.ValidationException;
-import org.hswebframwork.utils.ClassUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
 
-import javax.validation.Validator;
 import java.util.List;
 
 /**
@@ -39,9 +30,9 @@ import java.util.List;
  * @author zhouhao
  */
 @Transactional(rollbackFor = Throwable.class)
-public abstract class GenericEntityService<B extends GenericEntity<PK>, PK>
-        extends AbstractService<B, PK>
-        implements GenericService<B, PK> {
+public abstract class GenericEntityService<E extends GenericEntity<PK>, PK>
+        extends AbstractService<E, PK>
+        implements GenericService<E, PK> {
 
     @SuppressWarnings("unchecked")
     public GenericEntityService() {
@@ -49,7 +40,7 @@ public abstract class GenericEntityService<B extends GenericEntity<PK>, PK>
     }
 
     @Override
-    public abstract CrudDao<B, PK> getDao();
+    public abstract CrudDao<E, PK> getDao();
 
     @Override
     public int deleteByPk(PK pk) {
@@ -57,37 +48,38 @@ public abstract class GenericEntityService<B extends GenericEntity<PK>, PK>
     }
 
     @Override
-    public int updateByPk(B data) {
-        tryValidate(data);
-        return createUpdate(data).where(GenericEntity.id, data.getId()).exec();
+    public int updateByPk(E entity) {
+        tryValidate(entity);
+        return createUpdate(entity).where(GenericEntity.id, entity.getId()).exec();
     }
 
     @Override
-    public int updateByPk(List<B> data) {
+    public int updateByPk(List<E> data) {
         return data.stream().map(this::updateByPk).reduce(Math::addExact).orElse(0);
     }
 
     @Override
-    public int saveOrUpdate(B po) {
-        if (null != po.getId()) {
-            return updateByPk(po);
+    public int saveOrUpdate(E entity) {
+        if (null != entity.getId() && null != selectByPk(entity.getId())) {
+            return updateByPk(entity);
         } else {
-            insert(po);
+            insert(entity);
         }
         return 1;
     }
 
     @Override
-    public PK insert(B data) {
-        tryValidateProperty(null != data.getId(), GenericEntity.id, "id {not_be_null}");
-        tryValidate(data);
-        getDao().insert(data);
-        return data.getId();
+    public PK insert(E entity) {
+        tryValidate(entity);
+        getDao().insert(entity);
+        return entity.getId();
     }
 
     @Override
     @Transactional(readOnly = true)
-    public B selectByPk(PK id) {
-        return createQuery().where(GenericEntity.id, id).single();
+    public E selectByPk(PK pk) {
+        if (null == pk) return null;
+        return createQuery().where(GenericEntity.id, pk).single();
     }
+
 }

+ 5 - 7
hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/main/java/org/hswebframework/web/service/GenericService.java

@@ -19,7 +19,6 @@
 package org.hswebframework.web.service;
 
 import org.hswebframework.web.dao.CrudDao;
-import org.hswebframework.web.commons.entity.param.QueryParamEntity;
 import org.springframework.transaction.annotation.Transactional;
 
 /**
@@ -30,15 +29,14 @@ import org.springframework.transaction.annotation.Transactional;
  * @see DefaultDSLUpdateService
  * @see DefaultDSLDeleteService
  * @see CrudService
- * @see QueryParamEntity
  * @see CrudDao
  */
-public interface GenericService<B, PK> extends
-        DefaultDSLQueryService<B>,
-        DefaultDSLUpdateService<B>,
+public interface GenericService<E, PK> extends
+        DefaultDSLQueryService<E, PK>,
+        DefaultDSLUpdateService<E>,
         DefaultDSLDeleteService<PK>,
-        CrudService<B, PK, QueryParamEntity> {
+        CrudService<E, PK> {
     @Override
     @Transactional
-    CrudDao<B, PK> getDao();
+    CrudDao<E, PK> getDao();
 }

+ 14 - 0
hsweb-commons/hsweb-commons-utils/pom.xml

@@ -30,4 +30,18 @@
     <artifactId>hsweb-commons-utils</artifactId>
 
 
+    <dependencies>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>servlet-api</artifactId>
+            <version>2.5</version>
+            <optional>true</optional>
+        </dependency>
+
+        <dependency>
+            <groupId>org.aspectj</groupId>
+            <artifactId>aspectjweaver</artifactId>
+            <optional>true</optional>
+        </dependency>
+    </dependencies>
 </project>

+ 50 - 0
hsweb-commons/hsweb-commons-utils/src/main/java/org/hswebframework/web/AopUtils.java

@@ -0,0 +1,50 @@
+/*
+ * Copyright 2016 http://www.hswebframework.org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.hswebframework.web;
+
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.reflect.MethodSignature;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+public class AopUtils {
+
+    public static final String getMethodName(JoinPoint pjp) {
+        StringBuilder methodName = new StringBuilder(pjp.getSignature().getName()).append("(");
+        MethodSignature signature = (MethodSignature) pjp.getSignature();
+        String[] names = signature.getParameterNames();
+        Class[] args = signature.getParameterTypes();
+        for (int i = 0, len = args.length; i < len; i++) {
+            if (i != 0) methodName.append(",");
+            methodName.append(args[i].getSimpleName()).append(" ").append(names[i]);
+        }
+        return methodName.append(")").toString();
+    }
+
+    public static final Map<String, Object> getArgsMap(JoinPoint pjp) {
+        MethodSignature signature = (MethodSignature) pjp.getSignature();
+        Map<String, Object> args = new LinkedHashMap<>();
+        String names[] = signature.getParameterNames();
+        for (int i = 0, len = names.length; i < len; i++) {
+            args.put(names[i], pjp.getArgs()[i]);
+        }
+        return args;
+    }
+}

+ 10 - 0
hsweb-commons/hsweb-commons-utils/src/main/java/org/hswebframework/web/ThreadLocalUtils.java

@@ -40,7 +40,17 @@ public class ThreadLocalUtils {
         local.remove();
     }
 
+    @SuppressWarnings("unchecked")
     public static <T> T get(String key) {
         return ((T) local.get().get(key));
     }
+
+    @SuppressWarnings("unchecked")
+    public static <T> T getAndRemove(String key) {
+        try {
+            return ((T) local.get().get(key));
+        } finally {
+            local.get().remove(key);
+        }
+    }
 }

+ 32 - 0
hsweb-concurrent/hsweb-concurrent-cache/pom.xml

@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2016 http://www.hswebframework.org
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~       http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~  See the License for the specific language governing permissions and
+  ~  limitations under the License.
+  ~
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>hsweb-concurrent</artifactId>
+        <groupId>org.hswebframework.web</groupId>
+        <version>3.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>hsweb-concurrent-cache</artifactId>
+
+
+</project>

+ 32 - 0
hsweb-concurrent/hsweb-concurrent-counter/hsweb-concurrent-counter-api/pom.xml

@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2016 http://www.hswebframework.org
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~       http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~  See the License for the specific language governing permissions and
+  ~  limitations under the License.
+  ~
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>hsweb-concurrent-counter</artifactId>
+        <groupId>org.hswebframework.web</groupId>
+        <version>3.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>hsweb-concurrent-counter-api</artifactId>
+
+
+</project>

+ 44 - 0
hsweb-concurrent/hsweb-concurrent-counter/hsweb-concurrent-counter-api/src/main/java/org/hswebframework/web/concurrent/counter/Counter.java

@@ -0,0 +1,44 @@
+/*
+ * Copyright 2016 http://www.hswebframework.org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.concurrent.counter;
+
+import java.math.BigDecimal;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public interface Counter {
+    BigDecimal get();
+
+    void set(Number num);
+
+    BigDecimal getAndAdd(long num);
+
+    void add(long num);
+
+    void increment();
+
+    void decrement();
+
+    BigDecimal incrementAndGet();
+
+    BigDecimal decrementAndGet();
+
+}

+ 36 - 0
hsweb-concurrent/hsweb-concurrent-counter/hsweb-concurrent-counter-api/src/main/java/org/hswebframework/web/concurrent/counter/CounterManager.java

@@ -0,0 +1,36 @@
+/*
+ * Copyright 2016 http://www.hswebframework.org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.concurrent.counter;
+
+import java.util.Map;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public interface CounterManager {
+
+    Map<String, Counter> getCounters();
+
+    default Counter getCounter(String name) {
+        return getCounter(name, 0);
+    }
+
+    Counter getCounter(String name, Number initValue);
+}

+ 36 - 0
hsweb-concurrent/hsweb-concurrent-counter/pom.xml

@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2016 http://www.hswebframework.org
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~       http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~  See the License for the specific language governing permissions and
+  ~  limitations under the License.
+  ~
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>hsweb-concurrent</artifactId>
+        <groupId>org.hswebframework.web</groupId>
+        <version>3.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>hsweb-concurrent-counter</artifactId>
+    <packaging>pom</packaging>
+    <modules>
+        <module>hsweb-concurrent-counter-api</module>
+    </modules>
+
+
+</project>

+ 32 - 0
hsweb-concurrent/hsweb-concurrent-lock/pom.xml

@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2016 http://www.hswebframework.org
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~       http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~  See the License for the specific language governing permissions and
+  ~  limitations under the License.
+  ~
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>hsweb-concurrent</artifactId>
+        <groupId>org.hswebframework.web</groupId>
+        <version>3.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>hsweb-concurrent-lock</artifactId>
+
+
+</project>

+ 38 - 0
hsweb-concurrent/pom.xml

@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2016 http://www.hswebframework.org
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~       http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~  See the License for the specific language governing permissions and
+  ~  limitations under the License.
+  ~
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>hsweb-framework</artifactId>
+        <groupId>org.hswebframework.web</groupId>
+        <version>3.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>hsweb-concurrent</artifactId>
+    <packaging>pom</packaging>
+    <modules>
+        <module>hsweb-concurrent-cache</module>
+        <module>hsweb-concurrent-lock</module>
+        <module>hsweb-concurrent-counter</module>
+    </modules>
+
+
+</project>

+ 2 - 2
hsweb-core/src/main/java/org/hswebframework/web/BusinessException.java

@@ -24,10 +24,10 @@ package org.hswebframework.web;
  * @author zhouhao
  */
 public class BusinessException extends RuntimeException {
-    private int status = 400;
+    private int status = 500;
 
     public BusinessException(String message) {
-        this(message, 400);
+        this(message, 500);
     }
 
     public BusinessException(String message, int status) {

+ 6 - 0
hsweb-i18n/hsweb-i18n-cn/src/main/resources/messages_zh_CN.properties

@@ -16,3 +16,9 @@
 #  */
 #
 error=错误
+decrypt_param_error=解密参数错误
+user_not_exists=用户不存在
+user_is_disabled=用户已禁用
+password_error=密码错误
+private_key_is_null=私钥为空
+verify_code_error=验证码错误

+ 48 - 2
hsweb-starter/hsweb-spring-boot-starter/src/main/java/org/hswebframework/web/starter/HswebAutoConfiguration.java

@@ -19,11 +19,25 @@
 package org.hswebframework.web.starter;
 
 import com.alibaba.fastjson.serializer.SerializerFeature;
+import org.hswebframework.web.authorization.AuthorizationHolder;
+import org.hswebframework.web.authorization.AuthorizationSupplier;
+import org.hswebframework.web.commons.entity.factory.EntityFactory;
+import org.hswebframework.web.commons.entity.factory.MapperEntityFactory;
 import org.hswebframework.web.starter.convert.FastJsonHttpMessageConverter;
+import org.hswebframework.web.starter.resolver.AuthorizationArgumentResolver;
+import org.hswebframework.web.starter.resolver.JsonParamResolver;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.ComponentScan;
 import org.springframework.context.annotation.Configuration;
-import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.context.annotation.Primary;
+import org.springframework.web.method.support.HandlerMethodArgumentResolver;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+
+import java.util.List;
 
 /**
  * TODO 完成注释
@@ -35,7 +49,8 @@ import org.springframework.http.converter.HttpMessageConverter;
 public class HswebAutoConfiguration {
 
     @Bean
-    public HttpMessageConverter<Object> converter() {
+    @Primary
+    public FastJsonHttpMessageConverter fastJsonHttpMessageConverter(@Autowired(required = false) EntityFactory entityFactory) {
         FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
         // TODO: 16-12-24  应该可配置
         converter.setFeatures(
@@ -44,6 +59,37 @@ public class HswebAutoConfiguration {
                 SerializerFeature.WriteNullBooleanAsFalse,
                 SerializerFeature.WriteDateUseDateFormat
         );
+        converter.setEntityFactory(entityFactory);
         return converter;
     }
+
+    @Bean
+    public JsonParamResolver jsonParamResolver(FastJsonHttpMessageConverter fastJsonHttpMessageConverter) {
+        return new JsonParamResolver(fastJsonHttpMessageConverter);
+    }
+
+    @Bean
+    @ConditionalOnBean(AuthorizationSupplier.class)
+    public AuthorizationArgumentResolver authorizationArgumentResolver(AuthorizationSupplier authorizationSupplier) {
+        AuthorizationHolder.setSupplier(authorizationSupplier);
+        return new AuthorizationArgumentResolver(authorizationSupplier);
+    }
+
+    @Bean
+    public WebMvcConfigurer webMvcConfigurer(List<HandlerMethodArgumentResolver> handlerMethodArgumentResolvers) {
+        return new WebMvcConfigurerAdapter() {
+            @Override
+            public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
+                super.addArgumentResolvers(argumentResolvers);
+                argumentResolvers.addAll(handlerMethodArgumentResolvers);
+            }
+        };
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    public EntityFactory entityFactory() {
+        return new MapperEntityFactory();
+    }
+
 }

+ 93 - 0
hsweb-starter/hsweb-spring-boot-starter/src/main/java/org/hswebframework/web/starter/RestControllerExceptionTranslator.java

@@ -0,0 +1,93 @@
+/*
+ * Copyright 2016 http://www.hswebframework.org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.starter;
+
+import com.alibaba.fastjson.JSON;
+import org.hswebframework.web.AuthorizeException;
+import org.hswebframework.web.AuthorizeForbiddenException;
+import org.hswebframework.web.BusinessException;
+import org.hswebframework.web.NotFoundException;
+import org.hswebframework.web.controller.message.ResponseMessage;
+import org.hswebframework.web.validate.ValidationException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.core.annotation.Order;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.*;
+
+@RestControllerAdvice
+public class RestControllerExceptionTranslator {
+
+    private Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    @ExceptionHandler(ValidationException.class)
+    @ResponseStatus(HttpStatus.BAD_REQUEST)
+    @ResponseBody
+    ResponseMessage handleException(ValidationException exception) {
+        return ResponseMessage.error(exception.getMessage(), 400);
+    }
+
+    @ExceptionHandler(org.hsweb.ezorm.rdb.exception.ValidationException.class)
+    @ResponseStatus(HttpStatus.BAD_REQUEST)
+    @ResponseBody
+    ResponseMessage handleException(org.hsweb.ezorm.rdb.exception.ValidationException exception) {
+        return ResponseMessage.error(JSON.toJSONString(exception.getValidateResult()), 400);
+    }
+
+    @ExceptionHandler(BusinessException.class)
+    @ResponseBody
+    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
+    ResponseMessage handleException(BusinessException exception) {
+        if (exception.getCause() != null) {
+            logger.error("{}:{}", exception.getMessage(), exception.getStatus(), exception.getCause());
+        }
+        return ResponseMessage.error(exception.getMessage(), exception.getStatus());
+    }
+
+    @ExceptionHandler(AuthorizeException.class)
+    @ResponseStatus(HttpStatus.UNAUTHORIZED)
+    @ResponseBody
+    ResponseMessage handleException(AuthorizeException exception) {
+        return ResponseMessage.error(exception.getMessage(), exception.getStatus());
+    }
+
+    @ExceptionHandler(AuthorizeForbiddenException.class)
+    @ResponseStatus(HttpStatus.FORBIDDEN)
+    @ResponseBody
+    ResponseMessage handleException(AuthorizeForbiddenException exception) {
+        return ResponseMessage.error(exception.getMessage(), exception.getStatus());
+    }
+
+
+    @ExceptionHandler(NotFoundException.class)
+    @ResponseStatus(HttpStatus.NOT_FOUND)
+    @ResponseBody
+    ResponseMessage handleException(NotFoundException exception) {
+        return ResponseMessage.error(exception.getMessage(), 404);
+    }
+
+//    @ExceptionHandler(Throwable.class)
+//    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
+//    @ResponseBody
+//    @Order()
+//    ResponseMessage handleException(Throwable exception) {
+//        logger.error(exception.getMessage(), exception);
+//        return ResponseMessage.error(exception.getMessage(), 500);
+//    }
+
+}

+ 28 - 6
hsweb-starter/hsweb-spring-boot-starter/src/main/java/org/hswebframework/web/starter/convert/FastJsonHttpMessageConverter.java

@@ -5,6 +5,8 @@ import com.alibaba.fastjson.serializer.PropertyPreFilter;
 import com.alibaba.fastjson.serializer.SerializerFeature;
 import com.alibaba.fastjson.serializer.SimplePropertyPreFilter;
 import org.hswebframework.web.ThreadLocalUtils;
+import org.hswebframework.web.commons.entity.Entity;
+import org.hswebframework.web.commons.entity.factory.EntityFactory;
 import org.hswebframework.web.controller.message.ResponseMessage;
 import org.hswebframwork.utils.StringUtils;
 import org.springframework.http.HttpInputMessage;
@@ -32,11 +34,21 @@ public class FastJsonHttpMessageConverter extends AbstractHttpMessageConverter<O
 
     private SerializerFeature[] features = new SerializerFeature[0];
 
+    private EntityFactory entityFactory;
+
     public FastJsonHttpMessageConverter() {
         super(new MediaType("application", "json", UTF8),
                 new MediaType("application", "*+json", UTF8));
     }
 
+    public void setEntityFactory(EntityFactory entityFactory) {
+        this.entityFactory = entityFactory;
+    }
+
+    public EntityFactory getEntityFactory() {
+        return entityFactory;
+    }
+
     @Override
     protected boolean supports(Class<?> clazz) {
         return true;
@@ -58,6 +70,20 @@ public class FastJsonHttpMessageConverter extends AbstractHttpMessageConverter<O
         this.features = features;
     }
 
+    public Object readByString(Class<?> clazz, String jsonStr) {
+        return readByBytes(clazz, jsonStr.getBytes());
+    }
+
+    public Object readByBytes(Class<?> clazz, byte[] bytes) {
+        if (clazz == String.class) return new String(bytes, charset);
+        if (entityFactory != null && Entity.class.isAssignableFrom(clazz)) {
+            @SuppressWarnings("unchecked")
+            Class<Entity> tmp = entityFactory.getInstanceType((Class<Entity>) clazz);
+            if (tmp != null) clazz = tmp;
+        }
+        return JSON.parseObject(bytes, 0, bytes.length, charset.newDecoder(), clazz);
+    }
+
     @Override
     protected Object readInternal(Class<?> clazz, HttpInputMessage inputMessage) throws IOException,
             HttpMessageNotReadableException {
@@ -74,16 +100,13 @@ public class FastJsonHttpMessageConverter extends AbstractHttpMessageConverter<O
             }
         }
         byte[] bytes = baos.toByteArray();
-        if (clazz == String.class) return new String(bytes, charset);
-        // TODO: 16-12-24 clazz应该使用beanFactory获取
-        return JSON.parseObject(bytes, 0, bytes.length, charset.newDecoder(), clazz);
+        return readByBytes(clazz, bytes);
     }
 
     public String converter(Object obj) {
         if (obj instanceof String) return (String) obj;
         String text;
-        String callback = ThreadLocalUtils.get("jsonp-callback");
-        ThreadLocalUtils.remove("jsonp-callback");
+        String callback = ThreadLocalUtils.getAndRemove("jsonp-callback");
         if (obj instanceof ResponseMessage) {
             ResponseMessage message = (ResponseMessage) obj;
             if (message.getCode() == 200 && message.isOnlyData())
@@ -109,7 +132,6 @@ public class FastJsonHttpMessageConverter extends AbstractHttpMessageConverter<O
     protected void writeInternal(Object obj, HttpOutputMessage outputMessage) throws IOException,
             HttpMessageNotWritableException {
         OutputStream out = outputMessage.getBody();
-
         byte[] bytes = converter(obj).getBytes(charset);
         out.write(bytes);
         out.flush();

+ 50 - 0
hsweb-starter/hsweb-spring-boot-starter/src/main/java/org/hswebframework/web/starter/resolver/AuthorizationArgumentResolver.java

@@ -0,0 +1,50 @@
+/*
+ * Copyright 2016 http://www.hswebframework.org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.starter.resolver;
+
+import org.hswebframework.web.authorization.AuthorizationSupplier;
+import org.hswebframework.web.authorization.annotation.AuthInfo;
+import org.springframework.core.MethodParameter;
+import org.springframework.web.bind.support.WebDataBinderFactory;
+import org.springframework.web.context.request.NativeWebRequest;
+import org.springframework.web.method.support.HandlerMethodArgumentResolver;
+import org.springframework.web.method.support.ModelAndViewContainer;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public class AuthorizationArgumentResolver implements HandlerMethodArgumentResolver {
+
+    AuthorizationSupplier authorizationSupplier;
+
+    public AuthorizationArgumentResolver(AuthorizationSupplier authorizationSupplier) {
+        this.authorizationSupplier = authorizationSupplier;
+    }
+
+    @Override
+    public boolean supportsParameter(MethodParameter parameter) {
+        return parameter.hasParameterAnnotation(AuthInfo.class);
+    }
+
+    @Override
+    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
+        return authorizationSupplier.get();
+    }
+}

+ 4 - 3
hsweb-starter/hsweb-spring-boot-starter/src/main/java/org/hswebframework/web/starter/resolver/JsonParamResolver.java

@@ -33,6 +33,10 @@ public class JsonParamResolver implements HandlerMethodArgumentResolver {
 
     private FastJsonHttpMessageConverter fastJsonHttpMessageConverter;
 
+    public JsonParamResolver(FastJsonHttpMessageConverter fastJsonHttpMessageConverter) {
+        this.fastJsonHttpMessageConverter = fastJsonHttpMessageConverter;
+    }
+
     @Override
     public boolean supportsParameter(MethodParameter parameter) {
         return parameter.hasParameterAnnotation(JsonParam.class) && fastJsonHttpMessageConverter != null;
@@ -49,7 +53,4 @@ public class JsonParamResolver implements HandlerMethodArgumentResolver {
         return null;
     }
 
-    public void setFastJsonHttpMessageConverter(FastJsonHttpMessageConverter fastJsonHttpMessageConverter) {
-        this.fastJsonHttpMessageConverter = fastJsonHttpMessageConverter;
-    }
 }

+ 12 - 0
pom.xml

@@ -36,6 +36,8 @@
         <module>hsweb-commons</module>
         <module>hsweb-i18n</module>
         <module>hsweb-logging</module>
+        <module>hsweb-concurrent</module>
+        <module>hsweb-examples</module>
     </modules>
 
     <packaging>pom</packaging>
@@ -256,4 +258,14 @@
             <url>http://nexus.hsweb.me/content/repositories/snapshots/</url>
         </snapshotRepository>
     </distributionManagement>
+    <pluginRepositories>
+        <pluginRepository>
+            <id>hsweb-nexus</id>
+            <name>Nexus Release Repository</name>
+            <url>http://nexus.hsweb.me/content/groups/public/</url>
+            <snapshots>
+                <enabled>true</enabled>
+            </snapshots>
+        </pluginRepository>
+    </pluginRepositories>
 </project>