Java:どうなるかという点に集中しての検証と変換する"主催:ポート"のInetSocketAddress?
-
23-09-2019 - |
質問
何が共通の方法でJavaの検証と変換形式の文字列 host:port
へのインスタンス InetSocketAddress
?
なものがもっと増えると嬉しいで下記の要件を満たした:
ないルックアップアドレス;
作業のためのIPv4、IPv6、文字列"と"ホスト名;
(IPv4でip:port
, は、IPv6で[ip]:port
, ですよね?あRFCで定義するすべてのこれらのスキームは?)好ましく構文解析の文字列です。
(まっていて、スゴく楽しかったすべての特別な場合に、誰かにいって有効な形態のソケットアドレスのものを忘れている"特別の場合"への予期しない結果になります。
解決
私自身を提案可能な回避策。
に変換する文字列をURI(これの検証を自動でそのクエリのURIのホストとポート。
悲し、URIとホストコンポーネントになっています。そこで本ソリューションは、"なり"です。
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
}
このソリューション 必要のないカスタム文字列の構文解析, 作品と IPv4 (1.1.1.1:123
), IPv6 ([::0]:123
) ホスト名 (my.host.com:123
).
偶然生じているため、このソリューションに適したマシナリオ。たちの利用URIスキーム。
他のヒント
正規表現はかなりきれいにこれを行います。
Pattern p = Pattern.compile("^\\s*(.*?):(\\d+)\\s*$");
Matcher m = p.matcher("127.0.0.1:8080");
if (m.matches()) {
String host = m.group(1);
int port = Integer.parseInt(m.group(2));
}
することはできなポートオプションを作るか、ホスト上でいくつかの検証を行うなど、多くの点で、このます。
それは正確に質問に答えていませんが、この答えはまだちょうどホストとポートを解析したい私のような便利な他、必ずしも必要ではないが、完全なInetAddress
である可能性があります。グアバは HostAndPort のクラスを持っていますparseString
方法でます。
もう一人は、私はもともとホストに関する質問をするときに実行するために何をしていたかである正規表現の答えを与えています。それは少しより高度であり、あなたが扱っている種類のアドレスの内容を決定することができます正規表現の例ですので、私はまだやるべきでしょう。
String ipPattern = "(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}):(\\d+)";
String ipV6Pattern = "\\[([a-zA-Z0-9:]+)\\]:(\\d+)";
String hostPattern = "([\\w\\.\\-]+):(\\d+)"; // note will allow _ in host name
Pattern p = Pattern.compile( ipPattern + "|" + ipV6Pattern + "|" + hostPattern );
Matcher m = p.matcher( someString );
if( m.matches() ) {
if( m.group(1) != null ) {
// group(1) IP address, group(2) is port
} else if( m.group(3) != null ) {
// group(3) is IPv6 address, group(4) is port
} else if( m.group(5) != null ) {
// group(5) is hostname, group(6) is port
} else {
// Not a valid address
}
}
ポートはオプションになるように修正することは、かなり簡単です。 ":(\ dは+)" として "(?::(\ D +))?" ラップそしてその後、等、グループ(2)にnullをチェックします。
編集:私はそこに私の知ることは、「一般的な方法」の方法ですませんが、上記の私が持っていた場合、私はそれを行うだろうかであることに注意しましょう。
また注:ホストとIPv4の場合は実際には同じに処理される場合にはIPv4の場合は削除することができます。あなたはIPアドレスを持って知っていれば、時にはあなたは、究極のホストルックアップを避けることができるので、私はそれらを分割します。
new InetSocketAddress(
addressString.substring(0, addressString.lastIndexOf(":")),
Integer.parseInt(addressString.substring(addressString.lastIndexOf(":")+1, addressString.length));
?私はおそらくいくつかの小さな愚かなミスを犯しました。そして、私はあなただけだけという形式の文字列のうち、新規たInetSocketAddressオブジェクトを望んでいたと仮定しています。ホスト:ポート
独特の牛車のすべての種類、および他の場所で提供エレガントが、危険なソリューションを提供しています。時々、無粋ブルートフォースソリューションの方法です。
public static InetSocketAddress parseInetSocketAddress(String addressAndPort) throws IllegalArgumentException {
int portPosition = addressAndPort.length();
int portNumber = 0;
while (portPosition > 1 && Character.isDigit(addressAndPort.charAt(portPosition-1)))
{
--portPosition;
}
String address;
if (portPosition > 1 && addressAndPort.charAt(portPosition-1) == ':')
{
try {
portNumber = Integer.parseInt(addressAndPort.substring(portPosition));
} catch (NumberFormatException ignored)
{
throw new IllegalArgumentException("Invalid port number.");
}
address = addressAndPort.substring(0,portPosition-1);
} else {
portNumber = 0;
address = addressAndPort;
}
return new InetSocketAddress(address,portNumber);
}
の オープンソースのIPAddress Javaアプリケーション は ホスト名 クラスなのに必要な構文解析.免責事項:私はプロジェクトマネージャーのIPAddress図書館があります。
で解析IPv4,IPv6と文字列のホスト名なポートがあります。まるまですべての業務にお応えで各種フォーマットのホストやスしています。ちなみありませんRFCことがRfcに適用される異なる。
String hostName = "[a:b:c:d:e:f:a:b]:8080";
String hostName2 = "1.2.3.4:8080";
String hostName3 = "a.com:8080";
try {
HostName host = new HostName(hostName);
host.validate();
InetSocketAddress address = host.asInetSocketAddress();
HostName host2 = new HostName(hostName2);
host2.validate();
InetSocketAddress address2 = host2.asInetSocketAddress();
HostName host3 = new HostName(hostName3);
host3.validate();
InetSocketAddress address3 = host3.asInetSocketAddress();
// use socket address
} catch (HostNameException e) {
String msg = e.getMessage();
// handle improperly formatted host name or address string
}