如何解决具有功能区客户端阻止返回的“ 1”的api调用的自定义AOP春季启动注释
我对Ribbon / Eureka的使用经验确实很差,如果这是一个愚蠢的问题,请原谅我:
我有两个不同的微服务都连接到发现服务器,第一个使用自定义注释调用第二个微服务,该注释使用rest模板发送请求。 自定义注释名称为 PreHasAuthority
控制器:
@PreHasAuthority(value="[0].getProject()+'.requirements.update'")
@PostMapping(CREATE_UPDATE_REQUIREMENT)
public ResponseEntity<?> createUpdateRequirement(@Valid @RequestBody RequirementDTO requirementDTO,HttpServletRequest request,HttpServletResponse response) {
return requirementService.createUpdateRequirement(requirementDTO,request,response);
}
注释界面:
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface PreHasAuthority {
String value();
}
注释实施:
import java.lang.reflect.Method;
import javax.servlet.http.HttpServletRequest;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.stereotype.Component;
import netcomgroup.eu.service.AuthenticationService;
@Aspect
@Component
public class PreHasAuthorityServiceAspect {
@Autowired
private AuthenticationService authenticationService;
@Around(value = "@annotation(PreHasAuthority)")
public void around(ProceedingJoinPoint joinPoint) throws Throwable {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getmethod();
PreHasAuthority preHasAuthority = method.getAnnotation(PreHasAuthority.class);
Object[] args = joinPoint.getArgs();
String permission = preHasAuthority.value();
ExpressionParser elParser = new SpelExpressionParser();
Expression expression = elParser.parseExpression(permission);
String per = (String) expression.getValue(args);
String token =null;
for(Object o : args) {
if(o instanceof HttpServletRequest) {
HttpServletRequest request = (HttpServletRequest)o;
token=request.getHeader("X-Auth");
break;
}
}
if(token==null) {
throw new IllegalArgumentException("Token not found");
}
boolean hasPerm = authenticationService.checkPermission(per,token);
if(!hasPerm)
throw new Exception("Not Authorized");
}
}
我的功能区配置
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RoundRobinRule;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
public class RibbonConfiguration {
@Autowired
IClientConfig config;
@Bean
public IRule ribbonRule(IClientConfig config) {
return new RoundRobinRule();
}
}
应用程序属性中的Eureka配置
#Eureka config
eureka.client.serviceUrl.defaultZone= http://${registry.host:localhost}:${registry.port:8761}/eureka/
eureka.client.healthcheck.enabled= true
eureka.instance.leaserenewalIntervalInSeconds= 10
eureka.instance.leaseExpirationDurationInSeconds= 10
通过调用邮递员请求中的api将sendend正确发送到第二个微服务,并且我确定返回的是“ true”。
此后,该请求将停止,然后再输入 createUpdateRequirement 方法,并返回“ 1”作为邮递员的正文响应。没有提供排序错误。
我的猜测是问题出在自定义批注中,原因是当我删除批注时api调用可以正常工作,但是我无法理解该问题,因为它似乎对我来说都是正确设置的。
解决方法
您的@Around
建议永远不会调用joinPoint.proceed()
。因此,拦截的目标方法将永远不会执行。
第二个问题是您的通知方法返回void
,即它永远不会与任何返回其他类型的方法(例如ResponseEntity<?> createUpdateRequirement(..)
方法)匹配。
此外,around
是本机AspectJ语法中的保留关键字。即使它可以在注释驱动的语法中工作,您也应该将建议方法重命名为aroundAdvice
或interceptPreHasAuthority
之类的其他名称。
请务必阅读AspectJ或Spring AOP教程,尤其是Spring manual's AOP chapter。 ?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。