読者です 読者をやめる 読者になる 読者になる

URIクラスで出来る3つの操作

このクラスでサポートされる主要な操作は、「正規化」、「解決」、および「相対化」です。

http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/java/net/URI.html

以下いろいろ実験してみました。

import java.net.URI;

public class UriSamples {
    
    public static void main(String[] args) throws Exception {

        // コンストラクタ(1引数) → URI文字列を解析
        URI u = new URI("http://d.hatena.ne.jp/koseki#p1");
        System.out.println(u.getScheme()); // http
        System.out.println(u.getHost()); // d.hatena.ne.jp
        System.out.println(u.getPath()); // /koseki
        System.out.println(u.getFragment()); // p1

        // コンストラクタ(3引数) (スキーマ, スキーマ固有部分(ssp), フラグメント)
        u = new URI("mailto", "test@example.com", "dummy");
        System.out.println(u.toASCIIString()); // mailto:test@example.com#dummy
        
        // 3引数でもホスト・パスは認識される。
        u = new URI("http", "//d.hatena.ne.jp/koseki", "p1");
        System.out.println(u.getHost()); // d.hatena.ne.jp
        System.out.println(u.getPath()); // /koseki
        
        // コンストラクタ(4引数)
        u = new URI("http", "d.hatena.ne.jp", "/koseki", "p1");
        System.out.println(u.toASCIIString());
        // http://d.hatena.ne.jp/koseki#p1

        // コンストラクタ(7引数)
        u = new URI("http", "user:pass", "exmample.com", 8080, "/abc", "q=xxx", "p1");
        System.out.println(u.toASCIIString());
        // http://user:pass@exmample.com:8080/abc?q=xxx#p1

        // -1でポートを省略
        u = new URI("http", null, "exmample.com", -1, "/abc", null, null);
        System.out.println(u.toASCIIString());
        // http://exmample.com/abc
        
        // 相対URI
        u = new URI(null, null, "abc/../def", "xxx");
        System.out.println(u.toASCIIString());
        // abc/../def#xxx
        
        // 絶対URIなのに相対パスを指定すると例外が発生する。 
        try {
            u = new URI("http", "example.com", "abc", null);
        } catch (Exception e) {
            System.out.println(e);
            // java.net.URISyntaxException: Relative path in absolute URI: http://example.comabc
        }
        
        // 正規化(normalize)
        u = new URI(null, null, "abc/../xyz", null).normalize();
        System.out.println(u.toASCIIString()); // xyz
        
        // 解決(resolve)
        u = new URI("http", "example.com", "/abc/def/ghi", null);
        u = u.resolve("../xxx");
        System.out.println(u.toASCIIString()); // http://example.com/abc/xxx
        
        u = new URI("http", "example.com", "/abc/def/ghi/", null);
        u = u.resolve("../xxx");
        System.out.println(u.toASCIIString()); // http://example.com/abc/def/xxx

        // 既に絶対URIの場合はそのまま返る。
        u = new URI("http", "example.com", "/abc/def/ghi", null);
        u = u.resolve(new URI("http", "example.org", "/zzz", null));
        System.out.println(u.toASCIIString()); // http://example.org/zzz
        
        // 相対化
        URI u1  = new URI("http://example.com/abc/def/ghi");
        URI u2  = new URI("http://example.com/abc");
        URI rel = null;
        rel = u2.relativize(u1); // ベースURI(短い方)のメソッドを呼ぶ。
        System.out.println(rel.toASCIIString()); // def/ghi
        rel = u1.relativize(u2); // u1とu2が逆だとうまくいかない。
        System.out.println(rel.toASCIIString()); // http://example.com/abc

        
        // 不透明URI (cf. 階層URI)
        u = new URI("mailto:test@example.com");
        System.out.println(u.getScheme()); // mailto
        System.out.println(u.getSchemeSpecificPart()); // test@example.com 
        System.out.println(u.getHost()); // null
        System.out.println(u.getPath()); // null
        
        // スキーマ固有部分にコロンを含む場合がある。
        u = new URI("urn:isbn:096139210x");
        System.out.println(u.getScheme()); // urn
        System.out.println(u.getSchemeSpecificPart()); // isbn:096139210x
    }
}