在Java中验证Diameter URI的方法?

时间:2013-03-24 18:23:14

标签: java regex uri guava diameter-protocol

我想知道是否有任何简单的方法可以使用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的规则),然后将它们应用于某些输入以验证它?

我已经看过谷歌番石榴图书馆,看看是否有什么可以提供帮助,但我看不到任何东西。

非常感谢!

1 个答案:

答案 0 :(得分: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) {}
    }

}