当前位置: 首页 > 知识库问答 >
问题:

检索参数值

殷建弼
2023-03-14

在我的请求中,我有一个参数名“accessToken”,如何从ProceedingJoinPoint获取请求参数值?

public Object handleAccessToken(ProceedingJoinPoint joinPoint) throws Throwable { 
    final Signature signature = joinPoint.getStaticPart().getSignature();
    if (signature instanceof MethodSignature) {
        final MethodSignature ms = (MethodSignature) signature;
        String[] params = ms.getParameterNames();
        for (String param : params) {
            System.out.println(param);
            // here how do i get parameter value using param ?
        }
    }
}

调用方法:

public MyResponse saveUser(
    @RequestParam("accessToken") String accessToken,
    @RequestBody final UserDto userDto
) {
    // code 
}

我想在AOP中获得这个访问令牌。

提前谢谢。

共有2个答案

百里默
2023-03-14

要获取作为方法参数的参数,可以尝试以下操作:

Object[] methodArguments = joinPoint.getArgs();
荆乐
2023-03-14

好的,Shamseer,我只是有一点空闲时间,所以我试着回答你的问题,而不是你回答我评论中的所有问题。我这样做的方式是,我不会使用参数名,而是尝试使用注释匹配参数,也就是说,我将使用神奇的名称“accessToken”匹配注释类型和值,而不是方法参数名,该名称可能会因不知道您的方面的人的简单重构而更改,由于编译期间从类文件中剥离调试信息或由于混淆。

下面是一些针对AspectJ而不是Spring AOP测试的自洽示例代码,但后者的语法是前者语法的子集:

带有主方法的示例类:

有三种方法,它们都在其中一个参数上有一个@RequestParam注释,但其中只有两种方法具有“accessToken”的神奇值。无论参数类型如何(一个字符串和一个int),它们都应该匹配,但不应该匹配带有RequestParam(“someParameter”)的参数。严格来说,所有方法的执行都是匹配的,但运行时反射消除了不需要的执行。如果您的注释在类或方法级别或参数类型上,我们可以在切入点中直接匹配它们,而无需反射,但对于参数注释,这超出了AspectJ当前(v1.8.4)的能力,不幸的是,我们必须使用反射。

package de.scrum_master.app;

import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;

public class MyResponse {
    public MyResponse saveUser(
        @RequestParam("accessToken") String accessToken,
        @RequestBody final UserDto userDto
    ) {
        return this;
    }

    public MyResponse doSomething(
        @RequestParam("someParameter") String text,
        @RequestBody final UserDto userDto
    ) {
        return this;
    }

    public MyResponse doSomethingElse(
        @RequestParam("accessToken") int number
    ) {
        return this;
    }

    public static void main(String[] args) {
        MyResponse myResponse = new MyResponse();
        myResponse.doSomething("I am not a token", new UserDto());
        myResponse.saveUser("I am a token", new UserDto());
        myResponse.doSomethingElse(12345);
    }
}

使代码编译的虚拟助手类:

package de.scrum_master.app;

public class UserDto {}

方面:

请注意,我的捕获所有切入点执行(**(..) 仅用于说明。你应该把范围缩小到你真正想要匹配的方法。

package de.scrum_master.aspect;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

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.web.bind.annotation.RequestParam;

@Aspect
public class AccessTokenAspect {
    @Around("execution(* *(..))")
    public Object handleAccessToken(ProceedingJoinPoint thisJoinPoint) throws Throwable {
        System.out.println(thisJoinPoint);
        Object[] args = thisJoinPoint.getArgs();
        MethodSignature methodSignature = (MethodSignature) thisJoinPoint.getStaticPart().getSignature();
        Method method = methodSignature.getMethod();
        Annotation[][] parameterAnnotations = method.getParameterAnnotations();
        assert args.length == parameterAnnotations.length;
        for (int argIndex = 0; argIndex < args.length; argIndex++) {
            for (Annotation annotation : parameterAnnotations[argIndex]) {
                if (!(annotation instanceof RequestParam))
                    continue;
                RequestParam requestParam = (RequestParam) annotation;
                if (! "accessToken".equals(requestParam.value()))
                    continue;
                System.out.println("  " + requestParam.value() + " = " + args[argIndex]);
            }
        }
        return thisJoinPoint.proceed();
    }
}

控制台输出:

execution(void de.scrum_master.app.MyResponse.main(String[]))
execution(MyResponse de.scrum_master.app.MyResponse.doSomething(String, UserDto))
execution(MyResponse de.scrum_master.app.MyResponse.saveUser(String, UserDto))
  accessToken = I am a token
execution(MyResponse de.scrum_master.app.MyResponse.doSomethingElse(int))
  accessToken = 12345

另请参阅一个相关但稍简单的问题的答案,该问题具有类似的代码。

 类似资料:
  • 问题内容: 给定如下所示的URL,如何解析查询参数的值?例如,在这种情况下,我需要的值。 我在我的环境中使用Django;有没有一种方法可以帮助我? 我尝试使用,但它没有返回ghi我希望的值。 问题答案: Python 2: Python 3: 返回值列表,因此上述代码将打印。

  • 问题内容: 有谁知道从HttpServletRequest对象仅获取POST参数的方法吗? IE,PHP具有$ _POST超全局变量,并且Perl的CGI.pm仅在HTTP方法为POST(默认情况下)时才检索POST参数。 HttpServletRequest.getParameter(String)将包括 得到 URL参数,即使HTTP方法是POST。 问题答案: 我猜一种方法可能是手动解析并检

  • 本文向大家介绍Android 检索查询参数,包括了Android 检索查询参数的使用技巧和注意事项,需要的朋友参考一下 示例 如果用户点击一个linkto http://www.example.com/map?param1=FOO&param2=BAR,那么param1这里将有一个价值"FOO"和param2将有一个价值"BAR"。

  • 问题内容: 我正在尝试使用HttpServletRequest从发布的表单中检索传递给jax- rs的一些参数。但是,我的请求对象始终为我的参数返回空值。我不是要这样做吗?我已经在下面发布了代码,并发送了示例请求。 这是我的服务: 请求示例: 问题答案:

  • 我正在开发一个具有这种结构的rest Web服务 http://localhost:8080/context/login/{用户}/{密码} 此请求的示例为 http://localhost:8080/context/login/admin/admin 我在applicationContext中配置了一个AbstractPhaseInterceptor。我的spring应用程序的xml。拦截器类是

  • 问题内容: 我有一个三层应用程序,我必须进行修改。我对Java的整个Web知识都是陌生的,所以请多多包涵。 当前,应用程序具有UI,应用程序和数据库层,但是我试图使用依赖注入将SQL数据库与数据库层分离。 因此,在某些时候,我不需要在应用程序中使用SQL Server凭据,因为数据库后端可能是纯文本。 关键是当前的SQL凭据作为init参数存储在web.xml文件中。这些是通过servlet代码获