読み込み中...

Javaで郵便番号から住所を取得!初心者でもわかる7選の方法

郵便番号から住所を取得の画像 Java
この記事は約38分で読めます。

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

本記事のサンプルコードを活用して機能追加、目的を達成できるように作ってありますので、是非ご活用ください。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を満たす現役のプログラマチームによって監修されています。

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

Javaで郵便番号から住所取得を行う処理は、入力値を整え、APIやデータベースから住所を受け取り、結果を画面や保存処理へ渡す構成にすると理解しやすくなります。初心者向けには、HTTP通信、JSON解析、入力チェック、例外処理を小さな部品に分ける読み方が向いています。

その構成を押さえると、コンソールのサンプルコードから、SwingのGUI、Webフォーム、データベース保存、地図表示まで同じ考え方で広げられますし、ここがポイントです。郵便番号と住所取得の対応は外部サービスの仕様に左右されるため、公式ドキュメントや利用規約を確認しながら実装する姿勢が欠かせません。

動作確認環境
  • Java 21 LTS
  • Jakarta Servlet 6.0 / MySQL Connector/J 8.4
  • Google Chrome 126相当のモダンブラウザ
📖 この記事で学べること
  • Javaで郵便番号から住所取得する基本構成
  • HTTP API、外部ライブラリ、JSON解析の使い分け
  • 初心者向けに押さえたい入力チェックと例外処理
  • 住所データをGUI、DB、地図表示へ広げる考え方
  • サンプルコードを安全に読むための注意点

Javaとは?

Javaは、クラス単位で処理を組み立てるオブジェクト指向のプログラミング言語です。コンパイル後の.classファイルはJVM上で動作するため、OS差を吸収しやすい仕組みを持ちます。

その特徴は、郵便番号から住所取得する処理にも関係します。通信処理を担当するHttpURLConnection、文字列を扱うString、例外を受けるtrycatchを組み合わせれば、小さなコンソールプログラムからGUIまで段階的に広げられますが、これは押さえたい点です。

公式ドキュメントによれば、Java SEの標準APIにはネットワーク、入出力、コレクション、SQL接続などのパッケージが用意されています。仕様を確認する場合はOracle Java 21 API Documentationを参照すると、java.netjava.ioの役割を確認できます。

Javaの基本的な特徴

基本的に、Javaのコードはclassmethodobjectの組み合わせで構成されますし、これが一つの目安です。住所取得の例では、通信クラス、解析クラス、表示クラスを分けると変更範囲が読み取りやすくなります。

一方、初心者がつまずきやすいのは、文法よりも処理の境界です。たとえばURLを作る処理、openConnectionで接続する処理、getInputStreamで本文を読む処理を混ぜると、エラー発生時の原因を追いにくくなります。

そのため、住所取得の徹底解説では、言語の説明だけでなく、入力、通信、解析、表示、保存の境界を意識して読み進めるのが自然です。Javaの標準APIは広いため、java.netjava.iojava.sqljavax.swingの役割を分けて把握すると、サンプルコードの意図が見えやすくなるのが目安です。

分類使う要素住所取得での役割初心者向けの見方注意点
実行基盤JVMコンパイル済みコードを動かしますOS差を吸収する層です実行環境のバージョンを確認します
入口mainサンプルコードの開始位置になります最初に読むメソッドです引数の有無を確認します
文字列String郵便番号や住所を保持します変更できない文字列です連結が多い場合は注意します
可変文字列StringBuilderAPIレスポンスを組み立てます読み込みループで使いますStringBufferとの違いを見ます
URLURLAPIの接続先を表します文字列から作る接続先ですURLエンコードを意識します
HTTPHttpURLConnectionGET通信を扱います標準APIの通信部品ですタイムアウト設定を検討します
HTTPメソッドGET住所APIへ問い合わせます取得用のリクエストです機密値をURLに含めません
応答コード200成功判定に使います通信成否の数字です4xxや5xxも分岐します
読み取りBufferedReaderレスポンス本文を読みます行単位で読む道具です文字コードを合わせます
入力変換InputStreamReaderバイト列を文字へ変換します文字化け対策に関わりますUTF-8を明示します
例外IOException通信失敗を受けますネットワーク系の失敗です画面には詳細を出し過ぎません
例外処理try/catch失敗時の処理を分けます異常系を読む場所です握りつぶしを避けます
正規表現matches7桁形式を判定します入力チェックの入口ですハイフン有無を決めます
コレクションMap複数件の結果を保持しますキーと値の組です順序が必要なら型を選びます
実装型HashMap郵便番号別に住所を格納します高速な辞書型です出力順は固定されません
繰り返しforEach複数の郵便番号を処理しますラムダ式と組み合わせます例外処理の位置を見ます
GUIJFrame入力画面を作りますSwingの窓ですEDTの扱いを意識します
入力欄JTextField郵便番号を入力しますフォームのテキスト欄です空文字を検査します
ボタンJButton住所取得を開始しますクリック操作の入口です連打対策を考えます
イベントActionListenerクリック時の処理を受けますGUIの反応を作ります通信処理を重くし過ぎません
JSONJSONObject住所フィールドを取り出しますレスポンス解析用ですnullや空配列を見ます
配列getJSONArray検索結果一覧を取り出します複数候補に対応します0件時に例外が出ます
SQL接続Connectionデータベースへ接続しますJDBCの入口です接続情報を直書きしません
SQL準備PreparedStatementINSERT文を扱います値を後から渡せますSQLインジェクション対策になります
更新executeUpdate保存処理を走らせます更新件数を返します戻り値も確認します
フォームformWeb入力を送りますServletへ値を渡しますmethodを意識します
入力属性type='text'郵便番号欄を作ります文字入力用ですinputmodeも検討します
CSS余白padding入力欄の内側を整えます読みやすさに関わります狭すぎる値を避けます
CSS表示displayラベルの並びを変えますフォーム配置の基礎です画面幅に合わせます
エンコードURLEncoder住所検索URLを安全に作ります日本語住所で必要になります未使用例は改善余地があります

Javaでの郵便番号と住所の関係性

郵便番号は住所を完全に一意に決める識別子ではなく、町域や事業所単位で複数の表記に分かれる場合があります。そのため、Java側では「1件返る」前提だけでなく、候補なし、複数候補、住所の一部欠落を扱える形にしておくと安定します。

これを踏まえると、住所取得の戻り値は単なる文字列よりも、都道府県、市区町村、町域、エラー種別を持つオブジェクトにすると拡張しやすくなるのがポイントです。初心者向けのサンプルコードでは短い文字列出力でも十分ですが、業務フォームでは内部構造を分ける設計が現実的です。

住所データを扱うAPIやライブラリは、提供元によってレスポンス形式が異なります。外部仕様を読むときは、JavaのHttpURLConnection APIと、利用する住所APIの仕様を並べて確認すると、通信側とデータ側の責務を分けて理解できます。

その関係性を理解しておくと、郵便番号を入力補助として使う範囲と、利用者が手入力で補う範囲を切り分けやすくなるのが一般的です。たとえば都道府県や市区町村はAPIで埋め、番地や建物名は利用者入力に任せる形にすると、誤った自動補完を避けながら住所入力の負担を下げられます。

Javaで郵便番号から住所を取得する基本的な方法

最小構成の結論は、郵便番号を文字列として受け取り、APIのURLへ組み込み、HTTPの成功時だけレスポンス本文を読み取る形です。この流れなら、Java初心者向けでも通信、条件分岐、文字列処理を一度に確認できます。

サンプルコード1:基本的なAPIを利用した住所取得

具体的には、URLからHttpURLConnectionを開き、setRequestMethodGETを設定するのが現実的です。成功時はBufferedReaderで本文を読み、失敗時はステータスコードを表示する構成です。

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class AddressFetcher {
    public static void main(String[] args) {
        try {
            URL url = new URL("http://api.zipaddress.net/?zipcode=1000001");
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            int responseCode = conn.getResponseCode();

            if (responseCode == 200) {
                BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                String inputLine;
                StringBuffer response = new StringBuffer();
                
                while ((inputLine = in.readLine()) != null) {
                    response.append(inputLine);
                }
                in.close();

                System.out.println("住所: " + response.toString());
            } else {
                System.out.println("エラー発生: " + responseCode);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

結果: 期待される出力は、APIが返したJSONまたは住所情報を含む文字列です。通信先のサービス状態やレスポンス仕様によって内容は変わるため、画面表示へ使う前にJSONの項目名を確認します。

このサンプルコードでは、住所取得の流れを1つのmainに集めています。そのため、学習時は読みやすい反面、実用化ではAPI URL、通信処理、表示処理を別メソッドへ移すほうが保守しやすくなると整理できます。

ただし、外部APIへアクセスするコードはネットワーク障害やサービス終了の影響を受けます。初心者向けの練習でも、connectTimeoutreadTimeout、HTTPの404500を考慮すると、住所取得の失敗理由を利用者へ伝えやすくなります。

サンプルコード2:外部ライブラリを利用した住所取得

外部ライブラリを使う方法では、通信や解析をライブラリ側へ任せられる場合があると理解できます。一方、次のjp.xxxxx.PostalCodeResolverは説明用の仮名であり、実際のプロジェクトでは配布元、ライセンス、更新状況を確認してから導入します。

import jp.xxxxx.PostalCodeResolver;

public class AddressFetcher {
    public static void main(String[] args) {
        PostalCodeResolver resolver = new PostalCodeResolver();
        String address = resolver.getAddress("100-0001");
        System.out.println("取得した住所: " + address);
    }
}

結果: 期待される出力は「取得した住所: 東京都千代田区千代田」のような形式です。実在しないパッケージ名のままではコンパイルできないため、利用するライブラリの正式なimport名へ置き換えます。

この形の利点は、呼び出し側のJavaコードが短くなることです。ただし、内部でどのAPIに接続しているか、郵便番号データをローカルに持つのか、更新頻度がどの程度かによって、住所取得の信頼性は変わります。

関連するJavaのコレクションや依存関係の読み方を補いたい場合は、Java List型完全ガイドJavaアノテーションの解説も併せて確認すると、ライブラリ利用時の型や設定の見通しが立てやすくなると覚えるとよいでしょう。

Javaでの郵便番号から住所を取得する高度な方法

基本構成に慣れたら、エラーハンドリング、一括処理、画面操作を組み合わせます。こうした拡張では、住所取得の成功だけでなく、失敗時に処理を止めるのか、別の郵便番号へ進むのかを先に決めておくと設計が崩れにくくなります。

サンプルコード3:エラーハンドリングを組み込んだ住所取得

エラーハンドリングでは、通信失敗とデータ不在を分けて扱いると考えられます。次のサンプルコードはIOExceptionと一般的なExceptionを分けていますが、Webページの構造に依存するスクレイピングは変更に弱いため、公開APIがある場合はAPI利用を優先します。

import java.io.IOException;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

public class AddressRetriever {
    public static void main(String[] args) {
        try {
            String postalCode = "1000001";
            Document doc = Jsoup.connect("https://www.post.japanpost.jp/cgi-zip/zipcode.php?zip=" + postalCode).get();
            String address = doc.select(".zipcode_result_address").text();
            if(address.isEmpty()) {
                throw new Exception("住所が見つかりませんでした。");
            }
            System.out.println("取得した住所: " + address);
        } catch(IOException e) {
            System.err.println("データの取得中にエラーが発生しました: " + e.getMessage());
        } catch(Exception e) {
            System.err.println("エラーが発生しました: " + e.getMessage());
        }
    }
}

結果: 期待される出力は「取得した住所: …」またはエラーメッセージです。対象サイトのHTML構造やアクセス制限に依存するため、安定運用では利用規約と提供APIの有無を確認します。

このコードはJsoupでHTMLを取得し、selectでCSSセレクタに一致する要素を読みます。APIのJSONレスポンスと異なり、画面表示用HTMLは変更されやすいため、住所取得の本番処理では監視と代替手段を用意する考え方が必要になると言えるでしょう。

⚠️ 注意: スクレイピングは対象サイトの規約、robots.txt、負荷への配慮が必要です。郵便番号データを継続利用する場合は、提供元が許可するAPIや正式なデータ配布を選ぶ構成にします。

サンプルコード4:複数の郵便番号から一括で住所を取得

複数件を処理する場合は、郵便番号をMapListに格納し、各要素に対して問い合わせを行います。その際、1件の失敗で全体を止めるか、失敗した番号だけ記録して続行するかを決めますが、覚えておくと役立つでしょう。

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.jsoup.Jsoup;

public class BulkAddressRetrieval {
    public static void main(String[] args) {
        Map<String, String> postalCodes = new HashMap<>();
        postalCodes.put("100-0005", "");
        postalCodes.put("150-0001", "");

        postalCodes.keySet().forEach(postalCode -> {
            try {
                String url = "https://api.zipaddress.net/?zipcode=" + postalCode;
                String json = Jsoup.connect(url).ignoreContentType(true).execute().body();
                postalCodes.put(postalCode, json);
            } catch (IOException e) {
                e.printStackTrace();
            }
        });

        postalCodes.forEach((key, value) -> {
            System.out.println("郵便番号: " + key + ", 住所: " + value);
        });
    }
}

結果: 期待される出力は、郵便番号ごとにAPIレスポンス文字列を並べた行です。レスポンスがJSON形式の場合、住所だけを表示するには別途JSON解析を挟みます。

一方、このサンプルコードはpostalCodes.keySet()を走査しながら同じHashMapへ値を書き戻しています。キーを増減していないため大きな問題になりにくい形ですが、件数が増える処理では結果用の別Mapを作るほうが読みやすくなるのが基本です。

大量データでは、リクエスト間隔、リトライ回数、タイムアウト、ログ出力を設計します。Javaでのバッチ処理や日付判定も関係するため、入力データの検査にはJavaでうるう年を判定する解説のような条件分岐の考え方も役立ちます。

サンプルコード5:ユーザーインターフェースを持った住所取得アプリケーションの作成

GUIを持つ住所取得アプリでは、入力欄、ボタン、結果表示の責務を分けますし、ここを基本と考えるとよいでしょう。Swingを使う場合、公式のCreating a GUI With Swingでコンポーネントとイベント処理の基礎を確認できます。

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class AddressApp {
    public static void main(String[] args) {
        JFrame frame = new JFrame("郵便番号から住所を取得");
        frame.setSize(300, 200);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel panel = new JPanel();
        frame.add(panel);
        placeComponents(panel);

        frame.setVisible(true);
    }

    private static void placeComponents(JPanel panel) {
        panel.setLayout(null);

        JLabel userLabel = new JLabel("郵便番号");
        userLabel.setBounds(10, 20, 80, 25);
        panel.add(userLabel);

        JTextField userText = new JTextField(20);
        userText.setBounds(100, 20, 165, 25);
        panel.add(userText);

        JButton loginButton = new JButton("住所取得");
        loginButton.setBounds(10, 80, 80, 25);
        panel.add(loginButton);

        loginButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                // ここに住所取得のコードを実装
            }
        });
    }
}

結果: 期待される表示は、郵便番号入力欄と「住所取得」ボタンを持つ小さなウィンドウです。ボタン内の処理は空なので、この段階では住所の表示までは行いません。

このUIはJFrameJPanelを載せ、JLabelJTextFieldJButtonを配置しています。ただし、nullレイアウトとsetBoundsは画面サイズやフォント差に弱いため、実用化ではBorderLayoutGridBagLayoutも検討します。

住所取得ボタンに通信処理を入れる場合は、クリック直後に入力値を検査し、処理中はボタンを無効化するのが目安です。この工夫により、同じ郵便番号への連続リクエストを抑えられます。

loginButton.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        String postalCode = userText.getText();
        try {
            URL url = new URL("http://zipcoda.net/api?zipcode=" + postalCode);
            HttpURLConnection con = (HttpURLConnection) url.openConnection();
            con.setRequestMethod("GET");

            BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
            String inputLine;
            StringBuffer content = new StringBuffer();
            while ((inputLine = in.readLine()) != null) {
                content.append(inputLine);
            }
            in.close();

            con.disconnect();

            JSONObject jsonResponse = new JSONObject(content.toString());
            String address = jsonResponse.getString("address");

            JOptionPane.showMessageDialog(frame, "住所: " + address);

        } catch (Exception ex) {
            JOptionPane.showMessageDialog(frame, "エラーが発生しました: " + ex.getMessage());
        }
    }
});

結果: 期待される表示は、取得できた住所を含むダイアログです。JSONObjectのライブラリ追加、URLBufferedReaderimport、APIのレスポンス項目名が一致していることを前提にします。

このとき、GUIイベント内で長い通信を直接扱うと画面が固まったように見える場合があります。SwingではSwingWorkerなどでバックグラウンド処理に分けると、入力画面の応答性を保ちやすくなるのがポイントです。

こうした高度な構成では、処理を増やすほど例外の種類も増えます。通信が失敗したのか、入力値が不正なのか、JSONに想定した項目がないのかを区別しておくと、利用者向けメッセージと開発者向けログを分けやすくなります。

注意点と対処法

郵便番号の住所取得で特に押さえたいのは、入力形式、通信制限、例外時の利用者向けメッセージです。Javaのサンプルコードは短く書けますが、入力に空白やハイフンが混ざるだけでAPIの結果が変わることがあるのが一般的です。

郵便番号の形式とバリデーション

一般に、日本の郵便番号は7桁の数字として扱えます。画面上は100-0001のようにハイフン付きで入力されても、APIへ送る前にreplaceでハイフンを取り除く設計がよく使われます。

public class PostalCodeValidator {
    public static boolean isValid(String postalCode) {
        return postalCode != null && postalCode.matches("\d{7}");
    }
}

結果: 期待される戻り値は、postalCodeが7桁数字ならtrue、それ以外ならfalseです。ハイフン付き入力を許可する場合は、判定前に整形する処理を追加するのが現実的です。

このバリデーションは、住所取得の前段として置くとAPIへの不要な通信を減らせます。初心者向けには、nullチェック、正規表現、戻り値の3点を分けて読むと理解しやすくなります。

public class Main {
    public static void main(String[] args) {
        String postalCode = "1234567";
        if (PostalCodeValidator.isValid(postalCode)) {
            System.out.println("郵便番号が正しいです");
        } else {
            System.out.println("郵便番号が正しくありません");
        }
    }
}

結果: 期待される出力は「郵便番号が正しいです」です。値を123-4567や空文字に変えると、現在の判定では「郵便番号が正しくありません」になる想定です。

ただし、入力チェックは形式だけでは完結しません。存在しない7桁でも形式上は通るため、住所APIの検索結果が0件だった場合の表示も合わせて用意します。

APIやライブラリの利用上の制限とその対処法

APIにはリクエスト回数、商用利用、キャッシュ、認証キーなどの条件があります。そのため、住所取得のロジックだけでなく、呼び出し頻度と失敗時の再試行方針をコードに反映させますし、ここがポイントです。

public class APIRequestHandler {
    private static final int REQUEST_LIMIT = 100;
    private static final long TIME_WINDOW = 3600000;
    private static int requestCount = 0;
    private static long startTime = System.currentTimeMillis();

    public static boolean isAllowedToRequest() {
        long currentTime = System.currentTimeMillis();
        if (currentTime - startTime > TIME_WINDOW) {
            startTime = currentTime;
            requestCount = 0;
        }
        if (requestCount < REQUEST_LIMIT) {
            requestCount++;
            return true;
        } else {
            return false;
        }
    }
}

結果: 期待される戻り値は、上限内ならtrue、上限到達後ならfalseです。複数スレッドで使う場合はsynchronizedAtomicIntegerを検討します。

このコードはメモリ上でカウントを持つため、アプリケーション再起動時に値が戻ります。Webアプリで厳密に制御したい場合は、DBやRedisのような共有ストアにカウントを持たせる構成が必要になるでしょう。

💡 Tips: API制限に対応する処理は、住所取得メソッドの内側へ直接書き込むより、リクエスト可否を判定する部品として分けるとテストしやすくなると整理できます。

こうした注意点を徹底解説の観点で整理すると、利用者入力、外部通信、結果解析、保存処理を同じ例外で扱わないことが要点になります。利用者には「入力形式が違う」「住所が見つからない」「通信に失敗した」のように原因を分けて返すと、再入力すべきか時間を置くべきか判断しやすくなります。

そのため、Java側では内部ログと画面メッセージを分けますが、これは押さえたい点です。内部ログにはresponseCodeや例外クラス名を残し、画面には個人情報やAPIキーを含めない文言を返す構成が安全です。

具体的には、入力チェックの失敗は400相当の扱い、外部APIの障害は503相当の扱い、解析エラーは仕様変更の可能性としてログ監視へ回す考え方があります。Javaの例外クラスを細かく分けるほど利用者向けの表示も整理できますが、過度に分けるとコードが読みにくくなるため、最初は入力、通信、解析、保存の単位で区切ると扱いやすくなります。

応用例:Javaでの住所情報のさらなる活用法

取得した住所は、画面へ表示するだけでなく、会員登録、配送先管理、問い合わせフォーム、店舗検索などへつなげられますし、これが一つの目安です。その場合、Java側では保存形式と利用目的を分けて考える必要があります。

具体的には、郵便番号、都道府県、市区町村、町域、建物名を別カラムで保持すると、検索や補正がしやすくなります。一方、利用者が入力した表記をそのまま残す欄も用意すると、配送や本人確認で必要な細部を失いにくくなると理解できます。

サンプルコード6:取得した住所情報のデータベース保存

データベースへ保存する場合は、DriverManagerで接続し、PreparedStatementでSQLへ値を渡します。文字列連結でSQLを作ると誤動作や攻撃の原因になるため、プレースホルダを使う書き方を選びます。

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class AddressDatabase {

    private static final String URL = "jdbc:mysql://localhost:3306/your_database";
    private static final String USER = "your_username";
    private static final String PASSWORD = "your_password";

    public static void main(String[] args) {
        try {
            Connection connection = DriverManager.getConnection(URL, USER, PASSWORD);
            String sql = "INSERT INTO address (postcode, address) VALUES (?, ?)";
            PreparedStatement preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setString(1, "100-0001");
            preparedStatement.setString(2, "東京都千代田区千代田");
            preparedStatement.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

結果: 期待される結果は、addressテーブルへ郵便番号と住所のレコードが追加されることです。実際の動作には、テーブル作成、JDBCドライバ、接続情報、DB権限がそろっている必要があります。

このサンプルコードは説明を短くするため、ConnectionPreparedStatementを明示的に閉じていません。実装ではtry-with-resourcesを使い、接続リークを防ぐ構成にします。

住所情報を保存する設計では、正規化しすぎると入力画面が複雑になり、文字列だけで持つと検索や集計が難しくなると覚えるとよいでしょう。Javaで扱うドメインクラスとDBテーブルの粒度を合わせると、後から住所取得ロジックを差し替える場合も影響を抑えられます。

その保存設計では、郵便番号を主キーの一部として扱うか、利用者住所の属性として扱うかも分かれます。前者は郵便番号マスタの管理に向き、後者は注文や会員情報の履歴保持に向きますが、覚えておくと役立つでしょう。住所は時間の経過で変更される場合があるため、現在の住所マスタだけで過去データを書き換えない配慮も必要です。

サンプルコード7:住所情報を元にしたマップ表示機能の実装

住所を地図表示へつなげる場合は、取得済みの住所文字列を検索URLへ渡す方法が最小構成になります。Google MapsのURLを開く形なら、Java側で地図描画を実装せずに既定ブラウザへ処理を渡せます。

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import javax.swing.JOptionPane;

public class MapDisplay {
    public static void main(String[] args) {
        String address = JOptionPane.showInputDialog("住所を入力してください");
        try {
            URI uri = new URI("https://www.google.com/maps/search/?api=1&query=" + address);
            java.awt.Desktop.getDesktop().browse(uri);
        } catch (IOException | URISyntaxException e) {
            e.printStackTrace();
        }
    }
}

結果: 期待される表示は、入力した住所を検索条件にしたGoogle Mapsの画面です。日本語住所や空白を含む場合は、URLEncoderでクエリをエンコードする改善が必要になります。

このコードではJOptionPane.showInputDialogで住所を受け取り、Desktop.getDesktop().browseでブラウザを開きます。ただし、サーバー環境やデスクトップ機能のない環境ではDesktopが使えない場合があるため、Webアプリではリンクを画面に表示する構成が向いていると考えられます。

地図連携では、住所の表記揺れが検索結果に影響します。郵便番号から得た都道府県、市区町村、町域を連結し、建物名や番地は利用者入力を組み合わせると、検索クエリの精度を保ちやすくなります。

Javaで郵便番号から住所を取得する際のカスタマイズ方法

住所取得のカスタマイズでは、返ってきたデータの見せ方と、入力フォームの扱いやすさを分けて考えますし、ここを基本と考えるとよいでしょう。Java側でJSONを整形し、HTMLやCSS側で入力欄の見た目を整えると、役割の境界が明確になります。

住所取得の結果をカスタマイズする方法

APIレスポンスは、都道府県、市区町村、町域が別フィールドで返る場合があります。その場合、Javaで必要な項目だけを取り出し、表示用の文字列へ組み立てますし、ここがポイントです。

import java.net.HttpURLConnection;
import java.net.URL;
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class AddressFetcher {
    public static void main(String[] args) {
        String zipcode = "1000001";
        String apiUrl = "http://zipcloud.ibsnet.co.jp/api/search?zipcode=" + zipcode;

        try {
            URL url = new URL(apiUrl);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));

            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }

            reader.close();
            connection.disconnect();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

結果: 期待される出力は、ZipCloud APIから返るJSON文字列です。statusmessageresultsなどの項目を確認し、0件時の分岐を追加します。

このサンプルコードはJSONをそのまま出力する段階です。画面に住所だけを出したい場合は、JSON解析ライブラリを通してaddress1address2address3を取り出します。

// org.jsonライブラリを利用すると言えるでしょう。
import org.json.JSONObject;

// ...中略...

String line;
StringBuilder result = new StringBuilder();
while ((line = reader.readLine()) != null) {
    result.append(line);
}

JSONObject json = new JSONObject(result.toString());
String address = json.getJSONArray("results").getJSONObject(0).getString("address1") + 
                 json.getJSONArray("results").getJSONObject(0).getString("address2") + 
                 json.getJSONArray("results").getJSONObject(0).getString("address3");
System.out.println("住所: " + address);

// ...中略...

結果: 期待される出力は「住所: 東京都千代田区千代田」のような住所文字列です。resultsnullまたは空配列の場合、getJSONObject(0)で例外が発生するため事前確認を入れます。

この処理を安全にするには、json.isNull('results')や配列長の確認を組み合わせます。文字列のエスケープ処理を学ぶ場合は、Javaエスケープ処理の解説を参照すると、JSONやURLで特殊文字を扱う感覚を補えますが、これは押さえたい点です。

徹底解説として補うなら、APIレスポンスをそのまま画面へ出す処理と、住所だけを整形して表示する処理は分けて考えます。前者は調査やログ確認に向き、後者は利用者の入力補助に向いています。

郵便番号入力フォームのデザインカスタマイズ

Webアプリで住所取得を使う場合、JavaのServletやControllerが受け取る値はHTMLフォームから送られますし、これが一つの目安です。入力欄は見た目だけでなく、ラベル、送信メソッド、名前属性をそろえることでサーバー側の処理と接続しやすくなります。

HTMLでのフォーム作成

HTMLフォームでは、formactionに送信先、methodPOSTを置きます。郵便番号欄のnameはJava側で読み取るキーになるため、Servletのrequest.getParameter('zipcode')と一致させますが、覚えておくと役立つでしょう。

<form action="AddressServlet" method="POST">
    <label for="zipcode">郵便番号:</label>
    <input type="text" id="zipcode" name="zipcode">
    <button type="submit">住所取得</button>
</form>

結果: 期待される表示は、郵便番号入力欄と送信ボタンを持つフォームです。送信時にはAddressServletzipcodeという名前で入力値が渡されます。

このフォームは最小構成ですが、実用面ではmaxlengthinputmode='numeric'autocomplete='postal-code'などの属性も候補になります。HTML仕様の確認にはWHATWG HTML formsが一次情報として使えるのが基本です。

CSSでのスタイル適用

CSSでは、ラベルを行単位で見せ、入力欄に余白を持たせ、ボタンの押しやすさを整えます。Javaの処理と見た目を混ぜないことで、住所取得ロジックを変えずにUIだけを調整できます。

label {
    display: block;
    margin-bottom: 5px;
}

input[type="text"] {
    width: 200px;
    padding: 5px;
    margin-bottom: 10px;
}

button {
    padding: 5px 10px;
}

結果: 期待される表示は、ラベルが入力欄の上に並び、テキストボックスとボタンに余白が付いたフォームです。画面幅が狭い場合は、widthを固定値ではなく100%max-widthの組み合わせにすると収まりやすくなるのが目安です。

フォームの見た目を変えても、送信されるnameが同じならJava側の住所取得処理は変えずに済みます。フォーム処理の責務を分ける考え方は、Javaのオーバーライド解説にあるメソッド設計の理解ともつながります。

ℹ️ 補足: 郵便番号フォームを公開する場合は、入力補助だけに頼らずサーバー側でも同じバリデーションを行いるのがポイントです。ブラウザ側の制御は改変できるため、Java側の検査を残す構成にします。

そのカスタマイズでは、デザインだけを優先して入力の意味が失われないようにします。ラベルと入力欄の関連付け、送信ボタンの文言、エラー表示の位置、再入力時に値を残す挙動を整えると、住所取得フォームとして扱いやすくなるのが一般的です。サンプルコードを学習用に使う段階でも、labelidnamebuttonの対応関係を確認すると、Java側の受け取り処理と画面側の役割を結び付けやすくなるのが基本です。

具体的には、郵便番号欄を半角数字だけに寄せる入力補助、ハイフンを自動除去する整形、住所欄へ反映する前の確認表示を組み合わせると、利用者の誤入力を減らせます。ただし、ブラウザ側の入力補助は無効化できるため、Java側でも同じ検査を行う構成が必要です。画面の見た目、入力値の整形、サーバー側検査を分けておくと、仕様変更時の修正範囲も抑えられます。

まとめ

Javaで郵便番号から住所取得する実装は、APIへ問い合わせる処理、入力を検査する処理、結果を表示または保存する処理に分けると理解しやすくなるのが現実的です。初心者向けの学習では、サンプルコードを短く動かすよりも、どの行が通信、解析、例外処理を担当しているかを見分けることが学習の軸になります。

そのうえで、外部APIやライブラリを使う場合は、レスポンス形式、利用制限、エラー時の戻り値を確認します。徹底解説として押さえるべき点は、住所が取れた場合だけでなく、取れない場合、遅い場合、複数候補が返る場合の分岐を用意することです。

これらを踏まえると、住所取得はコンソール出力、SwingのGUI、Servletのフォーム、JDBC保存、地図表示へ自然に発展すると整理できます。Javaの基礎文法と標準APIを確認しながら、小さな部品へ分けて作ると、郵便番号を起点にした入力補助を堅実に組み込めます。

その学習を続ける場合は、通信処理だけを増やすのではなく、入力値の扱い、レスポンスの解析、例外時の表示、保存時のトランザクションまで順に広げると理解がつながります。郵便番号から住所取得する処理は小さく見えますが、Javaアプリケーションで外部サービスと連携する典型的な題材として使いやすく、Webフォームや業務画面の入力補助にも応用できると理解できます。

関連記事

著者: Japanシーモア編集部

Japanシーモアは、Web/IoT/APP/SYS 分野のプログラミング情報を体系的に提供するメディアです。本記事は編集部による執筆とAI支援を組み合わせて制作し、公開前に編集部が校正しています。誤りや改善案がございましたらお問い合わせよりご連絡ください。

※本記事は実在のエンジニア複数名で構成される Japanシーモア編集部が、AI支援を活用して作成・校正・公開しています。