我正在尝试使用AspectJ规范化应用程序中的URI。我正在使用以下代码捕获对传入java.net.URI参数的方法所做的每个调用:
Object around() : execution(* *(..,java.net.URI,..)) {
for ( Object arg : thisJoinPoint.getArgs() ) {
if ( arg instanceof URI ) {
// normalize
}
}
return proceed();
}
但是,由于URI是不可变的,我无法将规范化值交换到现有对象中。我需要的是调用继续使用新的,规范化的URI对象(并且可能传递其他参数不变)。但是,继续调用只允许我传递由连接点收集的参数。有没有办法为可变数量的参数完成此操作(主要是对任何URI参数感兴趣,但愿意收集并传递所有参数)?
答案 0 :(得分:3)
您需要更改建议的签名:
Object around(Object[] args) : execution(* *(..,java.net.URI,..)) && args(args) {
for(int i = 0; i < args.length; i++){
Object arg = args[i];
if ( arg instanceof URI ) {
args[i] = normalizeUrI((URI)arg);
}
}
return proceed(args);
}
更新:遗憾的是上面的代码不起作用。但这应该:
Object around() throws URISyntaxException : execution(* **.*(..,URI,..)) {
final Object[] args = thisJoinPoint.getArgs();
for(int i = 0; i < args.length; i++){
final Object arg = args[i];
if ( arg instanceof URI ) {
args[i] = normalizeUrI((URI)arg);
}
}
try{
return ((ProceedingJoinPoint)thisJoinPoint).proceed(args);
} catch(final Throwable e){
throw new IllegalStateException(e);
}
}
答案 1 :(得分:1)
以下内容应该是评论而非完整答案,但我的有限代表不允许我发表评论......
问题中的代码以及Sean Patrick Floyd的答案中的代码将无效,因为在方法签名模式中只能出现一次通配符“..”。可以找到here的简短解释。
答案 2 :(得分:0)
我知道这是一个老问题,但官方仍未解决。我刚看到它,所以我要回答它:
您提到URI是不可变的。所以基本上这是对正确解决方案的暗示:拦截对象创建(构造函数调用)并在around()
建议中检查结果。如果没有问题,请传递未更改的URI,否则创建一个新的,修复或暗杀任何错误。
假设您有此应用程序类创建URI:
package de.scrum_master.aspectj.sample.uri;
import java.net.URI;
import java.net.URISyntaxException;
public class URIApp {
public static void main(String[] args) throws URISyntaxException {
URI[] uris = {
new URI("https://google.com?search=olympics"),
new URI("http://yahoo.com/mail/login"),
new URI("https://facebook.com/user?name=kriegaex"),
new URI("http://stackoverflow.com/questions/123456")
};
for (URI uri : uris)
System.out.println(uri);
}
}
进一步假设我们认为所有URI都具有“http”不安全的方案/协议,因此是错误的。我们想通过使用“https”将URI替换为另一个来解决此问题。我们将在以下方面做到这一点:
package de.scrum_master.aspectj.sample.uri;
import java.net.URI;
import java.net.URISyntaxException;
public aspect URIFixer {
pointcut uriCreation() : call(URI.new(..)) && !within(URIFixer);
URI around() throws URISyntaxException : uriCreation() {
URI result = proceed();
return isOk(result) ? result : fix(result);
}
boolean isOk(URI uri) {
return "https".equals(uri.getScheme());
}
URI fix(URI uri) throws URISyntaxException {
return new URI("https", uri.getAuthority(), uri.getPath(), uri.getQuery(), uri.getFragment());
}
}
我希望这可以回答你的问题,即使是姗姗来迟。我想我应该在这里记录解决方案,以供其他可能找到它的用户进一步参考。