2013-03-24 57 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