Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用AspectJ处理变量参数_Java_Aspectj - Fatal编程技术网

Java 使用AspectJ处理变量参数

Java 使用AspectJ处理变量参数,java,aspectj,Java,Aspectj,我正在尝试使用AspectJ规范化应用程序中的URI。我正在捕获使用以下代码传入java.net.URI参数的方法的每个调用: Object around() : execution(* *(..,java.net.URI,..)) { for ( Object arg : thisJoinPoint.getArgs() ) { if ( arg instanceof URI ) { // normalize } }

我正在尝试使用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对象调用Procedure(并可能不改变传递其他参数)。但是,procedure调用只允许传递连接点收集的参数。对于数量可变的参数(主要对任何URI参数感兴趣,但愿意收集并传递所有参数),是否有办法实现这一点?

您需要更改建议的签名:

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);
}
objectaround(Object[]args):执行(**(..,java.net.URI,..)&&args(args){
对于(int i=0;i
更新:很遗憾,上面的代码不起作用。但这应该:

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);
    }
}
objectaround()抛出URISyntaxException:execution(****(..,URI,..){
最终对象[]args=thisJoinPoint.getArgs();
对于(int i=0;i
我知道这是一个老问题,但官方仍未解决。我刚看到,所以我要回答:

您提到URI是不可变的。因此,基本上这是一个正确解决方案的提示:拦截对象创建(构造函数调用)并在
around()
建议中检查结果。如果可以,则传递未更改的URI,否则创建一个新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替换为另一个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());
    }
}

我希望这能回答你的问题,尽管来得太晚了。我想我应该在这里记录解决方案,以供其他可能找到它的用户进一步参考。

下面的内容应该是评论,而不是完整的答案,但我有限的代表不允许我评论


问题中的代码以及Sean Patrick Floyd的答案中的代码都不起作用,因为在方法签名模式中只能出现一个通配符“.”。可以找到一个简短的解释。

我希望类似的东西会出现,但是(除非我理解/复制这个错误),我相信args(args)将这个连接点限制为只有一个Object[]参数的方法签名。由于执行部分将其限制为包含至少一个URI参数的方法签名,因此该连接点自相矛盾,永远找不到匹配项。请纠正我,如果我的误解,但我只是尝试了这个,它没有产生匹配。谢谢你。@Adam你说得对。请看我更改的答案。这个建议至少现在已经被应用了。这需要一些创造力,但看起来它应该会起作用——非常感谢!它看起来应该能工作,但似乎不能。。。非常奇怪的行为:它不会抛出任何异常(正如文档所示,在出现问题时可能会抛出异常)——它只返回null。使用Eclipse,我逐步完成它并设置断点,以确认通知所建议的方法未执行