我正在使用Java Spring Mvc和Spring AOP从用户那里查找参数名称。
我有一个控制器,它从用户获取参数并调用服务。
我有一个方面,在服务之前运行。
方面应检查username和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);
}
DomainService:
@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.**
}
在这种情况下,我希望在我的方面获得“domain”,“user”和“apiKey”参数名称。
知道我在这里缺少什么吗?
谢谢,
或
答案 0 :(得分:6)
正如我在上面的评论中所说,根据代理类型,您可以或不可以访问参数名称。如果你的bean实现了接口,那么JDK代理将由spring创建,在这种代理中,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()
答案 1 :(得分:1)
我只能使用Java 8在Eclipse中完成这项工作。方法如下:
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
。在STS 3.5.1(Eclipse Kepler SR2 4.3.2)中进行了测试。
答案 2 :(得分:1)
最简单的方法是在配置文件中设置proxyTargetClass
,即
@EnableAspectJAutoProxy(proxyTargetClass = true)