投稿日:
2019年1月9日
最終更新日:
【Restful API】Java8でURLのパスの先頭や途中、末尾の文字列をPathsクラスを利用して分解・取得する方法【簡単便利】
YouTubeも見てね♪
ねこじゃすり
猫を魅了する魔法の装備品!
[ノースフェイス] THE NORTH FACE メンズ アウター マウンテンライトジャケット
防水暴風で耐久性抜群なので旅行で大活躍です!
ペヤング ソースやきそば 120g×18個
とりあえず保存食として買っておけば間違いなし!
レッドブル エナジードリンク 250ml×24本
翼を授けよう!
モンスターエナジー 355ml×24本 [エナジードリンク]
脳を活性化させるにはこれ!
ドラゴンクエスト メタリックモンスターズギャラリー メタルキング
みんな大好き経験値の塊をデスクに常備しておこう!
Bauhutte ( バウヒュッテ ) 昇降式 L字デスク ブラック BHD-670H-BK
メインデスクの横に置くのにぴったりなおしゃれな可動式ラック!
目次
URLに含まれるパスの文字列を取得したい
先日、URL文字列に含まれている文字列を取得したい、という要件が出てきました。
例えば、https://blogenist.jp/2018/12/02/7077
という文字列があった場合に、post_id
を表す7077
という値を取得したい、と言うケースです。
正規表現等を利用すれば力技で取得する事は可能ですが、黒魔術になりがちなので筆者としては避けたかった為、いろいろ調べてみたところ、Javaのjava.nio.file
パッケージに含まれるPaths
クラスを利用することで簡単に取得する事が出来ました。
手順
対象文字列をPathクラスにラップ
まずはこのURL文字列を扱いやすくするために、Paths
クラスのstatic
メソッドであるget
メソッドを利用してPath
クラスを生成しましょう。
1
2
3
4
5
6
7
8
9
10
11
|
import java.nio.file.Path;
import java.nio.file.Paths;
public class PathsSample{
public static void main(String... args)
{
final String TARGET = "https://blogenist.jp/2018/12/02/7077"; // 対象URL
Path path = Paths.get(TARGET); // Pathクラスを生成
}
}
|
getFileNameメソッドで末尾のパス文字列を取得
次にPath
クラスのgetFileName
メソッドを利用して、末尾の文字列情報を取得します。
ちなみに、このメソッドの戻り値はPath
クラスとなっているので、しっかりとtoString()
メソッドを利用して文字列化する必要があります。
1
2
3
4
5
6
7
8
9
10
11
12
|
import java.nio.file.Path;
import java.nio.file.Paths;
public class PathsSample{
public static void main(String... args)
{
final String TARGET = "https://blogenist.jp/2018/12/02/7077";
Path path = Paths.get(TARGET);
String result = path.getFileName().toString(); // 文字列取得
}
}
|
確認
では、result
変数を標準出力して動作確認をしてみましょう。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
import java.nio.file.Path;
import java.nio.file.Paths;
public class PathsSample{
public static void main(String... args)
{
final String TARGET = "https://blogenist.jp/2018/12/02/7077";
Path path = Paths.get(TARGET);
String result = path.getFileName().toString();
System.out.println(result); // 標準出力
}
}
|
1 |
7077 |
期待通りの値が取得できましたね♪
Paths.getはFileSystems.getDefault().getPathと同じ
今回利用したPaths.get
メソッドはFileSystems.getDefault().getPath
の省略表現となっています。
なので、FileSystems.getDefault().getPath
を利用しても同じ動きは取れます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
import java.nio.file.Path;
//import java.nio.file.Paths;
import java.nio.file.FileSystems;
public class PathsSample{
public static void main(String... args)
{
final String TARGET_WITH_SLASH = "https://blogenist.jp/2018/12/02/7077/";
//Path path = Paths.get(TARGET_WITH_SLASH);
Path path = FileSystems.getDefault().getPath(TARGET_WITH_SLASH);
String result = path.getFileName().toString();
System.out.println(result);
}
}
|
1 |
7077 |
ですが、直感的にもわかりやすいので、Paths.get
メソッドを使うことを推奨します。
スラッシュ(/)終わりの場合はどうなる?
URLによってはスラッシュ(/)終わりの場合もありえますよね。
その場合も正しく動くか確認してみましょう。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
import java.nio.file.Path;
import java.nio.file.Paths;
public class PathsSample{
public static void main(String... args)
{
final String TARGET_WITH_SLASH = "https://blogenist.jp/2018/12/02/7077/";
Path path = Paths.get(TARGET_WITH_SLASH);
String result = path.getFileName().toString();
System.out.println(result);
}
}
|
1 |
7077 |
スラッシュ終わりでも、問題なく同様の値が取得できましたね♪
気にする必要は無さそうです。
他のメソッドも試してみよう。
Path
クラスには他にも様々なメソッドがあったのできになるものを試してみました。
getRoot
まずはgetRoot
メソッドです。
以下のようなソースで実行してみましょう。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
import java.nio.file.Path;
import java.nio.file.Paths;
public class PathsSample{
public static void main(String... args)
{
final String TARGET = "https://blogenist.jp/2018/12/02/7077";
Path path = Paths.get(TARGET);
System.out.println(String.format("targetUrl: [ %s ]", TARGET));
System.out.println("=================================");
String getRootResult = path.getRoot().toString(); URLに対してgetRootを行うとNULLが返る
System.out.println(String.format("getRoot: [ %s ]", getRootResult));
}
}
|
1
2
3
4
|
targetUrl: [ https://blogenist.jp/2018/12/02/7077 ]
=================================
Exception in thread "main" java.lang.NullPointerException
at PathsSample.main(PathsSample.java:15)
|
まさかのぬるぽエラーです・・・!
どうやら、getRoot
メソッドは対象のパスがルート・コンポーネントを持たない場合はnull
を返します。
今回はURLパスのためルートの概念が存在しないためぬるぽが発生したと思われます。
以下のようなディレクトリパスの場合は正しく処理が実行されました。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.IntStream;
public class PathsSample{
public static void main(String... args)
{
final String TARGET = "/Users/blogenist/hoge/fuga";
Path path = Paths.get(TARGET);
System.out.println(String.format("targetUrl: [ %s ]", TARGET));
System.out.println("=================================");
String getRootResult = path.getRoot().toString(); //URLに対してgetRootを行うとNULLが返る
System.out.println(String.format("getRoot: [ %s ]", getRootResult));
}
}
|
1
2
3
|
targetUrl: [ /Users/blogenist/hoge/fuga ]
=================================
getRoot: [ / ]
|
URLパスの場合に、getRoot
メソッドでドメインが取得出来るわけではないので、気をつけたほうが良いですね。!
ドメインを取得したい」場合は後述のgetName
メソッドを利用することで取得が可能です。
getParent
次はgetParent
メソッドです。
getParent
メソッドは現在パスの親のパスを返します。
親を持たないパスの場合はNULL
が返ってきます。。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
import java.nio.file.Path;
import java.nio.file.Paths;
public class PathsSample{
public static void main(String... args)
{
final String TARGET = "https://blogenist.jp/2018/12/02/7077";
Path path = Paths.get(TARGET);
System.out.println(String.format("targetUrl: [ %s ]", TARGET));
System.out.println("=================================");
while(path.getParent() != null)
{
String getParentResult = path.getParent().toString();
System.out.println(String.format("getParent: [ %s ]", getParentResult));
path = path.getParent();
}
}
}
|
1
2
3
4
5
6
7
|
targetUrl: [ https://blogenist.jp/2018/12/02/7077 ]
=================================
getParent: [ https:/blogenist.jp/2018/12/02 ]
getParent: [ https:/blogenist.jp/2018/12 ]
getParent: [ https:/blogenist.jp/2018 ]
getParent: [ https:/blogenist.jp ]
getParent: [ https: ]
|
path.getParent() != null
がnull
の場合は親が存在しないので終了します。
getNameCount
次はgetNameCount
メソッドです。
getNameCount
メソッドは対象のパスに含まれる名前要素の個数を返してくれます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.IntStream;
public class PathsSample{
public static void main(String... args)
{
final String TARGET = "https://blogenist.jp/2018/12/02/7077";
Path path = Paths.get(TARGET);
System.out.println(String.format("targetUrl: [ %s ]", TARGET));
System.out.println("=================================");
int getNameCountResult = path.getNameCount();
System.out.println(String.format("getNameCount: [ %s ]", getNameCountResult));
}
}
|
1
2
3
|
targetUrl: [ https://blogenist.jp/2018/12/02/7077 ]
=================================
getNameCount: [ 6 ]
|
スラッシュ(/)で区切られた数だけカウントしているようですね。
getName
最後はgetName
メソッドです。
getName
メソッドは引数に渡したインデックス番号の名前要素を返してくれます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.IntStream;
public class PathsSample{
public static void main(String... args)
{
final String TARGET = "https://blogenist.jp/2018/12/02/7077";
Path path = Paths.get(TARGET);
System.out.println(String.format("targetUrl: [ %s ]", TARGET));
System.out.println("=================================");
IntStream.range(0, path.getNameCount())
.forEach(index -> {
String getNameResult = path.getName(index).toString();
System.out.println(String.format("getName(%s): [ %s ]", index, getNameResult));
});
}
}
|
1
2
3
4
5
6
7
8
|
targetUrl: [ https://blogenist.jp/2018/12/02/7077 ]
=================================
getName(0): [ https: ]
getName(1): [ blogenist.jp ]
getName(2): [ 2018 ]
getName(3): [ 12 ]
getName(4): [ 02 ]
getName(5): [ 7077 ]
|
先ほど、getRoot
メソッドでは取得出来なかったドメイン名は、インデックス番号を1
で指定することで取得する事が出来そうですね。
ちなみに、存在しないインデックス番号を指定すると以下のようなjava.lang.IllegalArgumentException
エラーが発生します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.IntStream;
public class PathsSample{
public static void main(String... args)
{
final String TARGET = "https://blogenist.jp/2018/12/02/7077";
Path path = Paths.get(TARGET);
System.out.println(String.format("targetUrl: [ %s ]", TARGET));
System.out.println("=================================");
IntStream.range(0, path.getNameCount())
.forEach(index -> {
String getNameResult = path.getName(index).toString();
System.out.println(String.format("getName(%s): [ %s ]", index, getNameResult));
});
String getNameResult = path.getName(path.getNameCount()).toString();
System.out.println(String.format("getName(%s): [ %s ]", path.getNameCount(), getNameResult));
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
|
targetUrl: [ https://blogenist.jp/2018/12/02/7077 ]
=================================
getName(0): [ https: ]
getName(1): [ blogenist.jp ]
getName(2): [ 2018 ]
getName(3): [ 12 ]
getName(4): [ 02 ]
getName(5): [ 7077 ]
Exception in thread "main" java.lang.IllegalArgumentException
at sun.nio.fs.UnixPath.getName(UnixPath.java:323)
at sun.nio.fs.UnixPath.getName(UnixPath.java:43)
at PathsSample.main(PathsSample.java:20)
|
終わりに
以上のように、Java標準のPath
クラスを利用する事でURLパス操作を簡単に行う事が出来ました。
正規表現を使うより、可読性や保守性が上がるので是非Pathクラスを利用してみてください♪