3


我正在使用 Java Spring Mvc 和 Spring AOP 从用户那里查找参数名称。
我有一个控制器,它从用户那里获取参数并调用服务。
我有一个在服务之前运行的方面。
方面应检查用户名和 apiKey 参数是否存在。
这是我的代码:

控制器 :

@RequestMapping(method = RequestMethod.POST, produces=MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody String getDomainWithFoundIn(@RequestParam (value="domain") String domain, @RequestParam (value="user") String user, @RequestParam (value="apiKey") String apiKey) throws JsonGenerationException, JsonMappingException, IOException {
    return domainService.getDomainDataWithFoundIn(domain, user, apiKey);
}

域服务接口:

public interface IDomainService {
    public String getDomainDataWithFoundIn(String domainStr, String user, String apiKey);
}

域服务:

@Override
@ApiAuthentication
public String getDomainDataWithFoundIn(String domainStr, String user, String apiKey) {
//Do stuff here
}

还有我的 AOP 课:

@Component
@Aspect
public class AuthAspect {
@Before("@annotation(apiAuthentication)") 
public void printIt (JoinPoint joinPoint, ApiAuthentication apiAuthentication) throws NoAuthenticationParametersException, UserWasNotFoundException {
        final MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        final String[] parameterNames = signature.getParameterNames();
        **//parameterNames is null here.**
}

在这种情况下,我希望得到“域”、“用户”和“apiKey”参数名称。
知道我在这里缺少什么吗?
谢谢,
或者。

4

3 回答 3

6

正如我在上面的评论中所说,根据代理类型,您可以或不能访问参数名称。如果你的bean实现了接口,那么spring会创建JDK代理,在这种代理中MethodSignature.getParameterNames()为null。如果您的 bean 没有实现接口,则创建 CGLIB 代理,其中填充 MethodSignature.getParameterNames()。

如果可以,您可以通过删除 bean 接口切换到 CGLIB 代理 bean,它应该可以工作。

我现在也在苦苦挣扎,我无法删除接口。我为此想出了不同的解决方案。在界面上,我可以通过一些自定义注释标记我的参数:

interface MyInterface {
  void myMetod(@ParamName("foo") Object foo, @ParamName("bar") Object bar);
}

现在在 AOP 代理中,我可以在以下位置获取此信息:

MethodSignature.getMethod().getParameterAnnotations()
于 2014-10-31T14:12:30.443 回答
1

我只能在 Eclipse 中使用 Java 8 来完成这项工作。就是这样:

  • 右键单击项目 -> 属性 -> Java 构建路径 -> 库选项卡并确保在其中添加 JDK 8 而不是现在的(在我的情况下,我有 JDK_1.7.0_51 并将其替换为 JDK_1.8.0_05 )。应用更改。
  • 转到 Java 编译器 -> 检查Enable project specific settings-> 检查Use default compliance settings并设置Compiler compliance level为 1.8。Generated .class files compatibility和也是如此Source compatibility
  • 在该Classfile Generation部分确保检查Store method parameter names选项(在我的测试中,我Classfile Generation检查了所有选项)。在我的情况下,该Store method parameter names选项仅适用于 1.8 的合规级别。单击Ok
  • 清理并重新编译您的项目。
  • 我还使用 JDK 8 在 Tomcat 7 上运行我的项目。无需在调试模式下运行它。

在 STS 3.5.1 (Eclipse Kepler SR2 4.3.2) 中对此进行了测试。

于 2014-08-13T12:32:07.853 回答
1

最简单的方法是proxyTargetClass在你的配置文件中设置,即

@EnableAspectJAutoProxy(proxyTargetClass = true)
于 2017-11-02T08:55:21.253 回答