除了标题中的功能,其实这种方式可以用到很多功能方面,在解耦方面起着巨大的效果
项目中需要对每一个权限做权限控制
切面主要能起到解耦效果,但是扫描是扫一片的,不能灵活设置,这时候想到了注解,哪边需要扫描就在哪个接口加注解。优点是:代码量少,灵活。
屁话不多说,直接上码
1,自定义注解
package com.movitech.contract.config;
import java.lang.annotation.*;
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Oauth {
}
2,切面(设计到了数据库操作,不贴代码了,很简单~)
package com.movitech.contract.config;
import com.movitech.commons.utils.StringUtil;
import com.movitech.contract.dao.OauthDao;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
@Aspect // 声明切面
@Component //声明组件
@ComponentScan //组件自动扫描
@EnableAspectJAutoProxy //spring自动切换JDK动态代理和CGLIB
public class OauthAspect {
@Autowired
private OauthDao oauthDao;
@Before("execution(public * com.movitech.contract.controller.*.*(..)) && @annotation(com.movitech.contract.config.Oauth)")
public void doOauth(JoinPoint point) throws Throwable {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
//获取调用者带来的token
Object token = request.getHeaders("token").nextElement();
//截取请求的uri
String requestUri = request.getRequestURI();
int num = requestUri.length() - requestUri.replace("/","").length();
if(num >= 4){
//截取/a/b/c三层后面的字符
requestUri = getStr(requestUri,3);
}
System.out.println("token:"+token+"======="+"requestUri:"+requestUri);
//根据uri来获取接口开发状态
Integer isValid = oauthDao.getIsValid(requestUri);
if(StringUtil.isEmpty(isValid)){
System.out.println("接口状态:关闭!");
throw new Exception("接口状态:关闭,不允许访问!");
}else {
if(isValid == 1){
System.out.println("接口状态:可用!");
}else{
System.out.println("接口状态:关闭!");
throw new Exception("接口状态:关闭,不允许访问!");
}
}
//根据uri来获取鉴权约定的token
String id = oauthDao.getId(requestUri);
//判断是否一致,是:放行;否则抛出异常
if(token.equals(id)){
System.out.println("权限通过,放行");
}else {
throw new Exception("权限不满足,不允许访问次接口!请先去鉴权!!");
}
}
private static String getStr(String str, int n) {
int i = 0;
int s = 0;
while (i++ < n) {
s = str.indexOf("/", s + 1);
if (s == -1) {
return str;
}
}
return str.substring(0, s);
}
}
3,接口controller
package com.movitech.contract.controller;
import com.movitech.contract.config.Oauth;
import com.movitech.contract.service.HelloService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@Autowired
private HelloService helloService;
@GetMapping("/a/b/c/d/e/f")
@Oauth
public String hello(String name) {
String result = "nihao3";
return result;
}
}