Java: Common way to validate and convert "host:port" to InetSocketAddress?

java.is.for.desktop picture java.is.for.desktop · Feb 26, 2010 · Viewed 31.1k times · Source

What is the common way in Java to validate and convert a string of the form host:port into an instance of InetSocketAddress?

It would be nice if following criteria were met:

  • No address lookups;

  • Working for IPv4, IPv6, and "string" hostnames;
    (For IPv4 it's ip:port, for IPv6 it's [ip]:port, right? Is there some RFC which defines all these schemes?)

  • Preferable without parsing the string by hand.
    (I'm thinking about all those special cases, when someone think he knows all valid forms of socket addresses, but forgets about "that special case" which leads to unexpected results.)

Answer

java.is.for.desktop picture java.is.for.desktop · Feb 27, 2010

I myself propose one possible workaround solution.

Convert a string into URI (this would validate it automatically) and then query the URI's host and port components.

Sadly, an URI with a host component MUST have a scheme. This is why this solution is "not perfect".

String string = ... // some string which has to be validated

try {
  // WORKAROUND: add any scheme to make the resulting URI valid.
  URI uri = new URI("my://" + string); // may throw URISyntaxException
  String host = uri.getHost();
  int port = uri.getPort();

  if (uri.getHost() == null || uri.getPort() == -1) {
    throw new URISyntaxException(uri.toString(),
      "URI must have host and port parts");
  }

  // here, additional checks can be performed, such as
  // presence of path, query, fragment, ...


  // validation succeeded
  return new InetSocketAddress (host, port);

} catch (URISyntaxException ex) {
  // validation failed
}

This solution needs no custom string parsing, works with IPv4 (1.1.1.1:123), IPv6 ([::0]:123) and host names (my.host.com:123).

Accidentally, this solution is well suited for my scenario. I was going to use URI schemes anyway.