Spring AOP:访问建议的返回值

时间:2014-03-26 11:55:55

标签: java spring aop spring-aop

我希望增加我对目前不太好的AOP的了解。我有以下程序。主要是,我创建了一些User对象并打印出他们的用户名。在创建用户之前,我有一个安全方面,如果发现有危险的字(检查SQL注入),它会运行并打印出错误。它可以工作,但它总是创建用户并打印出用户名,即使安全性发现错误。

安全检查返回一个布尔值。如果check返回true,是否可以只运行其余的?为此,我需要访问建议的返回值。或者它需要更多的AOP和返回后完成?如果是这样,有人可以解释一下吗?我现在只知道如何使用之前和之后。

感谢您的帮助。以下是我的代码:

public class App 
{
    public static void main( String[] args ){

        ApplicationContext context = new ClassPathXmlApplicationContext("context.xml");
        List<String> names = new ArrayList<String>();
        List<User> users = new ArrayList<User>();

        names.add("Chris");
        names.add("Dave");
        names.add(";DROP table");
        names.add("Bob");

        User user = null;
        for(String name : names){
            user = context.getBean("user", User.class);
            user.setUsername(name);
            users.add(user);
        }
        for(User u : users){
            System.out.println(u.getUsername());
        }   
    }
}

这是安全:

public class Security {

    private List<String> words = new ArrayList<String>();

    {
        words.add("drop");
        words.add("delete");
        words.add("truncate");
        words.add("remove");
    }

    public boolean check(String input){
        for(String word: words){
            if(input.toLowerCase().contains(word)){
                System.err.println("Unsafe word " + word + " found!!!!!");
                return false;
            }
        }
        return true;
    }
}

以下是我在context.xml中的内容

<bean id="user" class="com.company.springAOPExample.User" scope="prototype" />
<bean id="security" class="com.company.springAOPExample.Security" />

<aop:config>
    <aop:aspect ref="security">
        <aop:pointcut id="setUsername" expression="execution(* com.company.springAOPExample.User.setUsername(java.lang.String)) and args(username)" />
        <aop:before pointcut-ref="setUsername" method="check" arg-names="username" />
    </aop:aspect>
</aop:config>

2 个答案:

答案 0 :(得分:2)

首先我认为你必须在users.add(user);而不是user.setUsername(name);添加AOP 你需要使用&#34;周围的建议&#34;如果是真的话,请致电继续,如果是假的话,请致电:

public class Security {

    private List<String> words = new ArrayList<String>();

    {
        words.add("drop");
        words.add("delete");
        words.add("truncate");
        words.add("remove");
    }

    public Void check(User user, ProceedingJoinPoint pjp){
        for(String word: words){
            if(!user.getUsername().toLowerCase().contains(word)){
                return pjp.proceed();
            }
            return;
        }

    }
}

答案 1 :(得分:0)

好的,我已经解决了,感谢前面的回答指向'around'以及本教程非常有用(http://www.compiletimeerror.com/2013/05/spring-aop-around-advice-example.html#.UzMAJvkRAmM)。这是主要方法:

public static void main( String[] args ){
    ApplicationContext context = new ClassPathXmlApplicationContext("context.xml");
    List<String> names = new ArrayList<String>();
    List<User> users = new ArrayList<User>();

    names.add("Chris");
    names.add("Dave");
    names.add(";DROP table");
    names.add("Bob");

    User user = null;

    for(String name : names){
        user = context.getBean("user", User.class);
        user.setUsername(name);

        if(user.getUsername()!=null){
            users.add(user);
        }           
    }

    for(User u : users){
        System.out.println(u.getUsername());
    }   
}

以下是安全性中的检查方法:

public void check(ProceedingJoinPoint pjp) throws Throwable {
    boolean match = false; 
    Object o[] = pjp.getArgs();

    for(String word: words){
        if(o[0].toString().toLowerCase().contains(word)){
            System.err.println("Unsafe word " + word + " found!!!!!");
            match = true;
        }
    }

    if(!match){
        pjp.proceed();
        return;
    }
}

这是context.xml:

<bean id="user" class="com.company.springAOPExample.User" scope="prototype" />
<bean id="security" class="com.company.springAOPExample.Security" />


<aop:config>
    <aop:aspect ref="security">
        <aop:pointcut id="setUsername" expression="execution(* com.company.springAOPExample.User.setUsername(java.lang.String))" />
        <aop:around pointcut-ref="setUsername" method="check" />
    </aop:aspect>
</aop:config>