2013-03-24 58 views
0

我想知道是否有任何簡單的方法來驗證使用Java的Diameter URI(下面的描述)?在Java中驗證Diameter URI的方法?

Note, a Diameter URI must have one of the forms: 

aaa://FQDN[:PORT][;transport=TRANS][;protocol=PROT] 
aaas://FQDN[:PORT][;transport=TRANS][;protocol=PROT] 

The FQDN (mandatory) has to be replaced with the fully qualified host name (or IP), the PORT (optional, default is 3868) with the port number, TRANS (optional) with the transport protocol (can be TCP or SCTP) and PROT (optional) with diameter. 

Some examples of the acceptable forms are: 

aaa://server.com 
aaa://127.0.0.1 
aaa://server.com:1234 
aaas://server.com:1234;transport=tcp 
aaas://[::1] 
aaas://[::1]:1234 
aaas://[::1]:1234;transport=tcp;protocol=diameter 

Note, as shown above, if using an IPv6 address, the address must be placed in box brackets, whereas the port number (if specified), with its colon separator, should be outside of the brackets. 

我覺得這樣使用正則表達式將是相當混亂和難以理解,我已經看到了其他的例子不使用正則表達式是一樣尷尬找(如https://code.google.com/p/cipango/source/browse/trunk/cipango-diameter/src/main/java/org/cipango/diameter/util/AAAUri.java?r=763)。

所以想知道是否有更好的方法來做到這一點,就像一個URI驗證器庫,它需要一些規則(比如上面Diameter URI的規則),然後將它們應用於某些輸入來驗證它?

我已經看過谷歌Guava的圖書館,看看是否有什麼可以幫助,但我什麼都看不到。

非常感謝!

+2

您是否嘗試過簡單地使用'java.net.URI'構造函數,如果URI無效,會引發URISyntaxException? – Steinar 2013-03-24 18:34:18

+0

是的,java.net.URI與我的用例略有不同。例如,接受新的URI(「127.0.0.1」),但這不是有效的Diameter URI(開始時沒有方案部分) – user1977749 2013-03-24 19:20:22

+0

爲什麼不用正則表達式解析FQDN,如:'#aaas?://( [^;] +)(; transport = \ w +)?(; protocol = \ w +)?#'然後在新的URI構造函數中使用子組1來驗證它是否爲FQDN? – FrankieTheKneeMan 2013-03-24 20:21:43

回答

2

由於URI類是不夠的,並且實際上會爲有效的Diameter URI創建異常,所以這不是一件微不足道的任務。

我覺得reg.ex.是去這裏的方式,但由於複雜性,如果你把它放在助手類中,你可能會更好。我同意你鏈接的代碼看起來不太好 - 你可以做得更好! :)

看看下面的代碼示例,我已經將regEx分解爲其各個部分,以此來「記錄」發生了什麼。

它不是以任何方式完成,它是爲了符合你的例子而創建的。特別是IP6類型的地址需要工作。另外,您可能希望在驗證中提供更多信息;就像爲什麼它失敗了。

但至少這是一個開始,我認爲它比你鏈接的代碼好一點。它可能看起來像很多代碼,但其中大部分實際上是打印語句和測試... :)另外,由於每個部分都被分解並保存爲字段變量,因此您可以創建簡單的getter來訪問每個部分(如果這對你很重要)。

import java.net.URISyntaxException; 
import java.util.Arrays; 
import java.util.regex.Matcher; 
import java.util.regex.Pattern; 

public class DiameterUri { 

    private String diameterUri; 
    private String protocol; 
    private String host; 
    private String port; 
    private String[] params; 

    public DiameterUri(String diameterUri) throws URISyntaxException { 
     this.diameterUri = diameterUri; 
     validate(); 
     System.out.println(diameterUri); 
     System.out.println(" protocol=" + protocol); 
     System.out.println(" host=" + host); 
     System.out.println(" port=" + port); 
     System.out.println(" params=" + Arrays.toString(params)); 
    } 

    private void validate() throws URISyntaxException { 
     String protocol = "(aaa|aaas)://";    // protocol- required 
     String ip4 = "[A-Za-z0-9.]+";     // ip4 address - part of "host" 
     String ip6 = "\\[::1\\]";      // ip6 address - part of "host" 
     String host = "(" + ip4 + "|" + ip6 + ")";  // host - required 
     String port = "(:\\d+)?";      // port - optional (one occurrence) 
     String params = "((;[a-zA-Z0-9]+=[a-zA-Z0-9]+)*)"; // params - optional (multiple occurrences) 
     String regEx = protocol + host + port + params; 
     Pattern pattern = Pattern.compile(regEx); 
     Matcher matcher = pattern.matcher(diameterUri); 
     if (matcher.matches()) { 
      this.protocol = matcher.group(1); 
      this.host = matcher.group(2); 
      this.port = matcher.group(3) == null ? null : matcher.group(3).substring(1); 
      String paramsFromUri = matcher.group(4); 
      if (paramsFromUri != null && paramsFromUri.length() > 0) { 
       this.params = paramsFromUri.substring(1).split(";"); 
      } else { 
       this.params = new String[0]; 
      } 
     } else { 
      throw new URISyntaxException(diameterUri, "invalid"); 
     } 
    } 

    public static void main(String[] args) throws URISyntaxException { 
     new DiameterUri("aaa://server.com"); 
     new DiameterUri("aaa://127.0.0.1"); 
     new DiameterUri("aaa://server.com:1234"); 
     new DiameterUri("aaas://server.com:1234;transport=tcp"); 
     new DiameterUri("aaas://[::1]"); 
     new DiameterUri("aaas://[::1]:1234"); 
     new DiameterUri("aaas://[::1]:1234;transport=tcp;protocol=diameter"); 
     try { 
      new DiameterUri("127.0.0.1"); 
      throw new RuntimeException("Expected URISyntaxException"); 
     } catch (URISyntaxException ignore) {} 
    } 

} 
+0

非常感謝Steinar,我認爲像這樣的東西可能是最好的方法(你是對的,它比我鏈接的代碼更清潔!) – user1977749 2013-03-24 21:57:50