From d2eba560109be42e24f6ba5f2ef6342abb33985a Mon Sep 17 00:00:00 2001 From: zhouhao Date: Fri, 24 Feb 2017 15:18:21 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=9D=83=E9=99=90,=E4=BF=AE?= =?UTF-8?q?=E5=A4=8Dcontroller=E9=87=8D=E5=86=99=E7=88=B6=E7=B1=BB?= =?UTF-8?q?=E5=AF=BC=E8=87=B4=E6=B3=A8=E8=A7=A3=E5=A4=B1=E6=95=88=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shiro/ShiroAutoconfiguration.java | 7 +- ...stAuthorizationAttributeSourceAdvisor.java | 21 ++- .../boost/DefaultFieldAccessController.java | 6 + .../web/controller/CreateController.java | 7 +- .../web/controller/DeleteController.java | 5 +- .../GenericEntityUpdateController.java | 5 +- .../web/controller/QueryController.java | 11 +- .../web/controller/UpdateController.java | 5 +- .../controller/message/ResponseMessage.java | 145 +++++------------- .../web/example/simple/SpringBootExample.java | 4 +- .../web/example/simple/TestController.java | 5 + .../src/main/resources/application.yml | 6 +- .../web/logging/AccessLogger.java | 1 + .../web/starter/HswebAutoConfiguration.java | 4 +- .../RestControllerExceptionTranslator.java | 12 +- .../convert/FastJsonHttpMessageConverter.java | 9 +- .../authorization/UserController.java | 15 +- 17 files changed, 115 insertions(+), 153 deletions(-) diff --git a/hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/ShiroAutoconfiguration.java b/hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/ShiroAutoconfiguration.java index cfb5cba7a..be44ee292 100644 --- a/hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/ShiroAutoconfiguration.java +++ b/hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/ShiroAutoconfiguration.java @@ -184,7 +184,8 @@ public class ShiroAutoconfiguration { static class MethodInterceptorHolderAdvisor { @Around(value = "@annotation(org.hswebframework.web.authorization.annotation.RequiresExpression)" + "||@annotation(org.hswebframework.web.authorization.annotation.RequiresDataAccess)" + - "||@annotation(org.hswebframework.web.authorization.annotation.Authorize)") + "||@annotation(org.hswebframework.web.authorization.annotation.Authorize)" + + "||within(@org.hswebframework.web.authorization.annotation.Authorize *)") public Object around(ProceedingJoinPoint pjp) throws Throwable { MethodSignature signature = (MethodSignature) pjp.getSignature(); String methodName = AopUtils.getMethodBody(pjp); @@ -202,14 +203,14 @@ public class ShiroAutoconfiguration { @ResponseStatus(HttpStatus.FORBIDDEN) @ResponseBody ResponseMessage handleException(AuthorizationException exception) { - return ResponseMessage.error(exception.getMessage(), 403); + return ResponseMessage.error(403, exception.getMessage()); } @ExceptionHandler(UnauthenticatedException.class) @ResponseStatus(HttpStatus.UNAUTHORIZED) @ResponseBody ResponseMessage handleException(UnauthenticatedException exception) { - return ResponseMessage.error(exception.getMessage() == null ? "{access_denied}" : exception.getMessage(), 401); + return ResponseMessage.error(401, exception.getMessage() == null ? "{access_denied}" : exception.getMessage()); } } diff --git a/hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/BoostAuthorizationAttributeSourceAdvisor.java b/hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/BoostAuthorizationAttributeSourceAdvisor.java index e74c808df..c5835bf2b 100644 --- a/hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/BoostAuthorizationAttributeSourceAdvisor.java +++ b/hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/BoostAuthorizationAttributeSourceAdvisor.java @@ -28,11 +28,11 @@ import org.hswebframework.web.authorization.annotation.RequiresDataAccess; import org.hswebframework.web.authorization.annotation.RequiresExpression; import org.hswebframework.web.authorization.annotation.RequiresFieldAccess; import org.springframework.aop.support.StaticMethodMatcherPointcutAdvisor; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.annotation.AnnotationUtils; import java.lang.annotation.Annotation; import java.lang.reflect.Method; +import java.util.Arrays; /** * @author zhouhao @@ -100,16 +100,28 @@ public class BoostAuthorizationAttributeSourceAdvisor extends StaticMethodMatche */ public boolean matches(Method method, Class targetClass) { Method m = method; - if (isAuthzAnnotationPresent(m)) { return true; } - //The 'method' parameter could be from an interface that doesn't have the annotation. //Check to see if the implementation has it. if (targetClass != null) { try { - m = targetClass.getMethod(m.getName(), m.getParameterTypes()); + //尝试解决由于被拦截的方法使用了泛型,并且重写了方法,导致无法获取父类方法的问题 + Class[] parameter = Arrays + .stream(m.getParameterTypes()) + .map(type -> { + if (type.isInterface()) return type; + Class[] interfaces = type.getInterfaces(); + if (interfaces.length > 0) return interfaces[0]; + Class superclass = type.getSuperclass(); + if (null != superclass && superclass != Object.class) { + return superclass; + } + return type; + }) + .toArray(Class[]::new); + m = targetClass.getMethod(m.getName(), parameter); if (isAuthzAnnotationPresent(m)) { return true; } @@ -131,5 +143,4 @@ public class BoostAuthorizationAttributeSourceAdvisor extends StaticMethodMatche } return false; } - } diff --git a/hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/DefaultFieldAccessController.java b/hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/DefaultFieldAccessController.java index 75ef5a6e3..5b621de63 100644 --- a/hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/DefaultFieldAccessController.java +++ b/hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/DefaultFieldAccessController.java @@ -6,6 +6,7 @@ import org.hswebframework.web.authorization.access.FieldAccess; import org.hswebframework.web.authorization.access.FieldAccessController; import org.hswebframework.web.authorization.access.ParamContext; import org.hswebframework.web.commons.entity.Entity; +import org.hswebframework.web.commons.entity.RecordCreationEntity; import org.hswebframework.web.commons.entity.param.QueryParamEntity; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -64,6 +65,11 @@ public class DefaultFieldAccessController implements FieldAccessController { } catch (Exception e) { } } + if (entity instanceof RecordCreationEntity) { + RecordCreationEntity creationEntity = ((RecordCreationEntity) entity); + creationEntity.setCreateTime(null); + creationEntity.setCreatorId(null); + } } else { logger.warn("doUpdateAccess skip ,because can not found any entity in param!"); } diff --git a/hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/CreateController.java b/hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/CreateController.java index 78018b493..922bf8faf 100644 --- a/hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/CreateController.java +++ b/hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/CreateController.java @@ -17,6 +17,7 @@ package org.hswebframework.web.controller; +import org.hswebframework.web.authorization.Permission; import org.hswebframework.web.authorization.annotation.Authorize; import org.hswebframework.web.controller.message.ResponseMessage; import org.hswebframework.web.logging.AccessLogger; @@ -39,13 +40,13 @@ import static org.hswebframework.web.controller.message.ResponseMessage.ok; * @author zhouhao * @since 3.0 */ -public interface CreateController { +public interface CreateController { InsertService getService(); - @Authorize(action = "add") + @Authorize(action = Permission.ACTION_ADD) @PostMapping - @AccessLogger("添加数据") + @AccessLogger("{action_add}") @ResponseStatus(HttpStatus.CREATED) default ResponseMessage add(@RequestBody E data) { return ok(getService().insert(data)); diff --git a/hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/DeleteController.java b/hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/DeleteController.java index 90fb1b163..598da6966 100644 --- a/hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/DeleteController.java +++ b/hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/DeleteController.java @@ -17,6 +17,7 @@ package org.hswebframework.web.controller; +import org.hswebframework.web.authorization.Permission; import org.hswebframework.web.authorization.annotation.Authorize; import org.hswebframework.web.controller.message.ResponseMessage; import org.hswebframework.web.logging.AccessLogger; @@ -35,9 +36,9 @@ public interface DeleteController { DeleteService getService(); - @Authorize(action = "delete") + @Authorize(action = Permission.ACTION_DELETE) @DeleteMapping(path = "/{id}") - @AccessLogger("根据主键删除数据") + @AccessLogger("{delete_by_primary_key}") default ResponseMessage deleteByPrimaryKey(@PathVariable PK id) { return ok(getService().deleteByPk(id)); } diff --git a/hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/GenericEntityUpdateController.java b/hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/GenericEntityUpdateController.java index 99c47953c..a95229ddb 100644 --- a/hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/GenericEntityUpdateController.java +++ b/hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/GenericEntityUpdateController.java @@ -17,6 +17,7 @@ package org.hswebframework.web.controller; +import org.hswebframework.web.authorization.Permission; import org.hswebframework.web.authorization.annotation.Authorize; import org.hswebframework.web.commons.entity.GenericEntity; import org.hswebframework.web.controller.message.ResponseMessage; @@ -37,9 +38,9 @@ public interface GenericEntityUpdateController, PK> UpdateService getService(); - @Authorize(action = "update") + @Authorize(action = Permission.ACTION_UPDATE) @PutMapping(path = "/{id}") - @AccessLogger("根据主键修改数据") + @AccessLogger("{update_by_primary_key}") default ResponseMessage updateByPrimaryKey(@PathVariable PK id, @RequestBody E data) { data.setId(id); return ResponseMessage.ok(getService().updateByPk(data)); diff --git a/hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/QueryController.java b/hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/QueryController.java index e5f48c1ad..bb53cc867 100644 --- a/hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/QueryController.java +++ b/hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/QueryController.java @@ -17,6 +17,7 @@ package org.hswebframework.web.controller; +import org.hswebframework.web.authorization.Permission; import org.hswebframework.web.authorization.annotation.Authorize; import org.hswebframework.web.commons.entity.Entity; import org.hswebframework.web.commons.entity.param.QueryParamEntity; @@ -39,7 +40,7 @@ import static org.hswebframework.web.controller.message.ResponseMessage.ok; * @see QueryParamEntity * @see 3.0 */ -public interface QueryController { +public interface QueryController { /** * 获取实现了{@link QueryByEntityService}和{@link QueryService}的服务类 @@ -59,16 +60,16 @@ public interface QueryController { * @param param 参数 * @return 查询结果 */ - @Authorize(action = "read") + @Authorize(action = Permission.ACTION_QUERY) @GetMapping - @AccessLogger("根据条件查询") + @AccessLogger("{dynamic_query}") default ResponseMessage list(Q param) { return ok(getService().selectPager(param)); } - @Authorize(action = "read") + @Authorize(action = Permission.ACTION_GET) @GetMapping(path = "/{id}") - @AccessLogger("根据主键查询") + @AccessLogger("{get_by_id}") default ResponseMessage getByPrimaryKey(@PathVariable PK id) { return ok(getService().selectByPk(id)); } diff --git a/hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/UpdateController.java b/hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/UpdateController.java index 9eaaede3e..9ac271094 100644 --- a/hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/UpdateController.java +++ b/hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/UpdateController.java @@ -17,6 +17,7 @@ package org.hswebframework.web.controller; +import org.hswebframework.web.authorization.Permission; import org.hswebframework.web.authorization.annotation.Authorize; import org.hswebframework.web.controller.message.ResponseMessage; import org.hswebframework.web.logging.AccessLogger; @@ -30,8 +31,8 @@ import org.springframework.web.bind.annotation.RequestBody; * @author zhouhao */ public interface UpdateController { - @Authorize(action = "update") + @Authorize(action = Permission.ACTION_UPDATE) @PutMapping(path = "/{id}") - @AccessLogger("根据主键修改数据") + @AccessLogger("{update_by_primary_key}") ResponseMessage updateByPrimaryKey(@PathVariable PK id, @RequestBody E data); } diff --git a/hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/message/ResponseMessage.java b/hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/message/ResponseMessage.java index cad7e4c91..571d073c6 100644 --- a/hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/message/ResponseMessage.java +++ b/hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/message/ResponseMessage.java @@ -28,23 +28,46 @@ import java.util.*; /** * 响应消息。controller中处理后,返回此对象,响应请求结果给客户端。 */ -public class ResponseMessage implements Serializable { +public class ResponseMessage extends LinkedHashMap implements Serializable { private static final long serialVersionUID = 8992436576262574064L; - /** - * 反馈数据 - */ - private Object data; + public static ResponseMessage error(String message) { + return error(500, message); + } - /** - * 反馈信息 - */ - private String message; + public static ResponseMessage error(int status, String message) { + ResponseMessage msg = new ResponseMessage(); + msg.put("message", message); + msg.put("status", status); + return msg.putTimeStamp(); + } - /** - * 响应码 - */ - private int code; + public static ResponseMessage ok() { + return ok(null); + } + + private ResponseMessage putTimeStamp() { + put("timestamp", System.currentTimeMillis()); + return this; + } + + public static ResponseMessage ok(Object data) { + return new ResponseMessage() + .data(data) + .putTimeStamp() + .status(200); + } + + public ResponseMessage and(String key, Object value) { + put(key, value); + return this; + } + + public ResponseMessage data(Object data) { + if (data != null) + put("data", data); + return this; + } /** * 过滤字段:指定需要序列化的字段 @@ -56,24 +79,9 @@ public class ResponseMessage implements Serializable { */ private transient Map, Set> excludes; - private transient boolean onlyData; - - private transient String callback; - - public Map toMap() { - Map map = new HashMap<>(); - if (data != null) - map.put("data", this.getData()); - if (message != null) - map.put("message", this.getMessage()); - map.put("code", this.getCode()); - return map; - } - protected ResponseMessage() { } - public ResponseMessage include(Class type, String... fields) { return include(type, Arrays.asList(fields)); } @@ -125,7 +133,7 @@ public class ResponseMessage implements Serializable { excludes = new HashMap<>(); if (fields == null || fields.isEmpty()) return this; Class type; - if (data != null) type = data.getClass(); + if (getData() != null) type = getData().getClass(); else return this; exclude(type, fields); return this; @@ -136,7 +144,7 @@ public class ResponseMessage implements Serializable { includes = new HashMap<>(); if (fields == null || fields.isEmpty()) return this; Class type; - if (data != null) type = data.getClass(); + if (getData() != null) type = getData().getClass(); else return this; include(type, fields); return this; @@ -159,32 +167,20 @@ public class ResponseMessage implements Serializable { } public Object getData() { - return data; + return get("data"); } - public ResponseMessage setData(Object data) { - this.data = data; - return this; - } @Override public String toString() { return JSON.toJSONStringWithDateFormat(this, "yyyy-MM-dd HH:mm:ss"); } - public int getCode() { - return code; - } - - public ResponseMessage setCode(int code) { - this.code = code; + public ResponseMessage status(int status) { + put("status", status); return this; } - public static ResponseMessage fromJson(String json) { - return JSON.parseObject(json, ResponseMessage.class); - } - public Map, Set> getExcludes() { return excludes; } @@ -193,63 +189,4 @@ public class ResponseMessage implements Serializable { return includes; } - public ResponseMessage onlyData() { - setOnlyData(true); - return this; - } - - public void setOnlyData(boolean onlyData) { - this.onlyData = onlyData; - } - - public boolean isOnlyData() { - return onlyData; - } - - public ResponseMessage callback(String callback) { - this.callback = callback; - return this; - } - - public String getCallback() { - return callback; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public static ResponseMessage ok() { - return ok(null); - } - - public static ResponseMessage ok(Object data) { - ResponseMessage message = new ResponseMessage(); - message.setCode(200); - message.setData(data); - return message; - } - - public static ResponseMessage created(Object data) { - ResponseMessage message = new ResponseMessage(); - message.setCode(201); - message.setData(data); - return message; - } - - public static ResponseMessage error(String message) { - return error(message, 500); - } - - public static ResponseMessage error(String message, int code) { - ResponseMessage response = new ResponseMessage(); - response.setCode(code); - response.setMessage(message); - return response; - } - } \ No newline at end of file diff --git a/hsweb-examples/hsweb-examples-simple/src/main/java/org/hswebframework/web/example/simple/SpringBootExample.java b/hsweb-examples/hsweb-examples-simple/src/main/java/org/hswebframework/web/example/simple/SpringBootExample.java index b1457f5e0..dfb8fa976 100644 --- a/hsweb-examples/hsweb-examples-simple/src/main/java/org/hswebframework/web/example/simple/SpringBootExample.java +++ b/hsweb-examples/hsweb-examples-simple/src/main/java/org/hswebframework/web/example/simple/SpringBootExample.java @@ -35,8 +35,8 @@ import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; +import org.springframework.boot.context.TypeExcludeFilter; +import org.springframework.context.annotation.*; import org.springframework.jdbc.datasource.DataSourceUtils; import javax.sql.DataSource; diff --git a/hsweb-examples/hsweb-examples-simple/src/main/java/org/hswebframework/web/example/simple/TestController.java b/hsweb-examples/hsweb-examples-simple/src/main/java/org/hswebframework/web/example/simple/TestController.java index aaf41fe51..5a759453f 100644 --- a/hsweb-examples/hsweb-examples-simple/src/main/java/org/hswebframework/web/example/simple/TestController.java +++ b/hsweb-examples/hsweb-examples-simple/src/main/java/org/hswebframework/web/example/simple/TestController.java @@ -13,6 +13,7 @@ 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.controller.QueryController; +import org.hswebframework.web.controller.authorization.UserController; import org.hswebframework.web.controller.message.ResponseMessage; import org.hswebframework.web.entity.authorization.SimpleUserEntity; import org.hswebframework.web.entity.authorization.UserEntity; @@ -30,6 +31,7 @@ import java.util.List; */ @RestController @Authorize(permission = "test") +@RequestMapping("/test") public class TestController implements QueryController { @GetMapping("/test1") @@ -61,6 +63,9 @@ public class TestController implements QueryController, CreateController { private UserService userService; @@ -64,16 +67,16 @@ public class UserController implements QueryController