2014-03-26 80 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>