需求描述:
对指定资源(方法或者类)进行权限控制。
解决方案
在需要权限控制的资源,加上权限控制注解
软件版本
- JAVA JDK 1.8
- Spring 4.3.6.RELEASE
实现细节
- 注解接口
package com.xmasq.framework.core.annotation.permission;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.stereotype.Component;
/**
* 权限控制
*
* @author 艾思祺-非渝
* @version 1.0.0
*/
@Component
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.TYPE })
public @interface Permission {
/** 进行权限过滤的操作类型 用户所拥有的权限集仅需要1项权限符合 */
public final static String OPER_OR = "OR";
/** 进行权限过滤的操作类型 用户所拥有的权限集需要覆盖全部 */
public final static String OPER_AND = "AND";
/**
* 需求的权限的操作模式,默认为OR
*/
public String oper() default OPER_OR;
/** 需要的权限 */
String[] value() default {};
}
2.对注解的实现进行一层封装,方便其它注解实现
package com.xmasq.framework.core.annotation;
import java.lang.annotation.Annotation;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.ClassUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
/**
* 注解处理器的简单封装,可以简单获取指定注解
*
* @author 艾思祺-非渝
* @version 1.0.0
*/
public abstract class BaseAnnotationHandler<T extends Annotation> extends HandlerInterceptorAdapter {
/**
* 获取指定注解
*
* @param handler
* @return
*/
public T getAnnotation(Object handler, Class<T> annotationClass) {
if (handler instanceof HandlerMethod) {
T annotation = null;
HandlerMethod handlerMethod = (HandlerMethod) handler;
annotation = handlerMethod.getMethodAnnotation(annotationClass);
if (annotation == null) {
annotation = AnnotationUtils.findAnnotation(handlerMethod.getBeanType(), annotationClass);
}
return annotation;
} else {
return AnnotationUtils.findAnnotation(ClassUtils.getUserClass(handler), annotationClass);
}
}
}
3.Permission注解的具体实现
package com.xmasq.framework.core.annotation.permission;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.ModelAndView;
import com.xmasq.framework.core.annotation.BaseAnnotationHandler;
import com.xmasq.framework.core.exception.BusinessException;
import com.xmasq.framework.module.user.UserContext;
import com.xmasq.framework.module.user.UserContextHelper;
/**
* Promission注解的处理
*
* @see com.xmasq.framework.core.annotation.permission.Permission
*
* @author 艾思祺-非渝
* @version 1.0.0
*/
@Component
public class PermissionHandler extends BaseAnnotationHandler<Permission> {
public static final String BEAN_NAME = "promissionInterceptor";
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
Permission promission = getAnnotation(handler, Permission.class);
// 具体实现细节
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
}
}
4.使用方式
@Permission(value = {"p_menu_view"})
@RestController
@RequestMapping(value = "/manage/menu")
public class MenuRestController extends BaseRestController {
@Autowired
private MenuService menuService;
@Permission(value = {"p_menu_edit"})
@PostMapping(value = "/save")
public AjaxResponse save(@RequestBody Menu menu) {
menuService.saveMenu(menu);
return AjaxResponse.success();
}
}
PS:关于获取注解,如果运用在类上,必须要要对注解加上spring的@Component注解,这样才能通过AnnotationUtils.findAnnotation(handlerMethod.getBeanType(), annotationClass);获取到指定注解