2014-03-26 98 views
0

我想提高我对AOP的了解,这在目前不是很好。我有以下程序。主要的是,我创建了一些用户对象并打印出他们的用户名。在创建用户之前,我有一个安全方面,如果它发现一个危险词(检查SQL注入),它将运行并输出一个错误。它可以工作,但它总是创建用户并打印出用户名,即使安全性发现错误。Spring AOP:访问建议的返回值

安全检查返回一个布尔值。如果检查返回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> 
+0

你想要做的,如果它做什么返回false? –

+1

A方面没有对结果做任何事情。为了防止调用该方法,您必须创建一个环绕的方面,并调用'proceed或not call'proceed'。或者从当前方面抛出异常,以防止进一步处理方法调用。 –

+0

@SotiriosDelimanolis如果它返回false,我希望它什么都不做,继续进行for循环的下一次迭代。我想抛出一个异常,但循环中的其余迭代不会运行。我将阅读有关“周围”的内容。 – Chris

回答

2

第一,我认为你必须添加AOP上users.add(user);不是user.setUsername(name);然后是 您需要使用“周围的建议”,并在出现错误的情况下进行调用,以防错误地调用它:

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; 
     } 

    } 
} 
0

好的,我解决了它,这要感谢上一个回答指向'周围',并且也对本教程非常有用(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>