Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【ITニュース解説】Building a static file server in Java with sockets

2025年09月19日に「Dev.to」が公開したITニュース「Building a static file server in Java with sockets」について初心者にもわかりやすく解説しています。

作成日: 更新日:

ITニュース概要

Javaとソケットで静的ファイルサーバーを構築する。クライアントからのHTTPリクエストを待ち受け、staticフォルダ内の要求ファイルを解析。その内容をHTTPレスポンスとして送り、ファイルがない場合は「404 Not Found」を返す。各処理を別々のクラスに分け実装する。

ITニュース解説

システムエンジニアを目指す皆さんは、普段インターネットを利用している中で、ウェブサイトが表示される仕組みについて考えたことがあるだろうか。今回解説する記事は、Javaというプログラミング言語を使って、静的ファイルサーバーを自力で構築する方法を紹介している。静的ファイルサーバーとは、ウェブブラウザからのリクエストに応じて、あらかじめ用意されたHTMLファイルやCSSファイル、画像ファイルなどをそのまま返すシンプルなサーバーのことだ。例えば、あなたがウェブサイトのURLを入力すると、そのウェブサイトのサーバーがHTMLファイルを返し、ブラウザはその内容を表示するが、このプログラムはその「返す」部分を自作するものだと考えると良い。

このプログラムは、いくつかの役割ごとにクラスファイルに分けられている。具体的には、Main.javaServer.javaFileUtil.javaRequestUtil.javaResponseUtil.javaSystemUtil.javaというファイル群で構成されている。これらのファイルはそれぞれ異なる責任を持ち、連携してサーバーとして機能する。また、ウェブサイトのコンテンツとなるHTMLファイルなどは、src/main/resources/staticという特定のフォルダに配置される。このstaticフォルダが、このサーバーが提供するすべてのファイルの「根っこ」となる場所だ。

プログラムの起動は、Main.javaという最もシンプルなクラスから始まる。このMainクラスの唯一の仕事は、Serverクラスのrunメソッドを呼び出し、サーバーを起動させることだ。例ではポート番号9090を指定してサーバーを動かしている。ポート番号とは、ネットワーク上で特定のサービスを識別するための番号で、これにより複数のサービスが同じコンピューター上で動くことができる。

サーバーの核心部分はServer.javaに記述されている。このクラスは、まずServerSocketという特別なソケットを作成し、指定されたポート(例では9090)でクライアントからの接続を待ち受ける。ServerSocketは「待ち合わせ場所」のようなもので、クライアント(ウェブブラウザなど)が接続を求めてきたときに、新しい通信用のソケット(Socketオブジェクト)を作成して、そのクライアントとの個別のやり取りを担当させる。これにより、一つのサーバーが複数のクライアントからの接続を同時に処理できる基盤が作られる。

サーバーが起動すると、最初にstaticフォルダの中にある全てのファイルをスキャンし、それぞれのファイルがどのURLでアクセスされるべきかを事前に把握する。この処理はFileUtil.javaが担当する。FileUtilは、staticフォルダ内のサブフォルダも含めて全てのファイルを探索し、それぞれのファイルの「相対パス」(例えば、index.htmlcss/style.cssといった、staticフォルダからの相対的な場所)をキーとして、実際のファイルの場所(絶対パス)を値とするマップ(対応表)を作成する。このマップを事前に作っておくことで、クライアントからファイルのリクエストがあった際に、高速に目的のファイルを見つけ出すことができる。OS(オペレーティングシステム)によってファイルパスの区切り文字(Windowsでは\、Linuxでは/)が異なるため、FileUtilではSystemUtil.javaを使ってOSを判別し、適切なパス変換を行っている。これにより、どんなOS環境でも正しく動作するように工夫されている。

クライアントからの接続が確立されると、次にRequestUtil.javaが登場する。このクラスの役割は、クライアントが何を要求しているのか、具体的にはどのファイルを欲しがっているのかを読み取ることだ。ウェブブラウザからのリクエストは「HTTPリクエスト」と呼ばれる形式で送られてくる。このHTTPリクエストの最初の行には、「GET /index.html HTTP/1.1」のように、どんな操作(GETはファイル取得を意味する)で、どのパス(/index.html)を、どのプロトコルバージョン(HTTP/1.1)で要求しているかが書かれている。RequestUtilは、この最初の行を解析し、要求されたファイルパス(例えばindex.html)を抽出する。

要求されたファイルパスがわかると、Serverクラスは先ほどFileUtilが作成したマップを使って、そのファイルがstaticフォルダ内に存在するかどうかを調べ、その実際の場所を特定する。ファイルが見つかれば、いよいよクライアントにファイルを送り返す段階に入る。

このファイルの送信を担当するのがResponseUtil.javaだ。ResponseUtilは、まずHTTPレスポンスのヘッダーと呼ばれる情報をクライアントに送る。ヘッダーには、「HTTP/1.1 200 OK」(成功したことを示す)や、ブラウザがファイルをキャッシュしないようにするための情報などが含まれる。このヘッダー情報の後に空行を一つ挟み、その後に実際のファイルの内容をバイトデータとして送り返す。これにより、ウェブブラウザは受け取った情報をHTMLファイルなどとして正しく解釈し、表示することができる。もし、クライアントが要求したファイルがstaticフォルダ内に見つからなかった場合は、ResponseUtilは「404 Not Found」というエラーを示すレスポンスをクライアントに送り返す。これは、ウェブサイトを見ているときに「ページが見つかりません」と表示されるのと同じ状況を作り出す処理だ。

このように、各クラスが明確な役割を持つことで、プログラム全体の見通しが良くなり、理解しやすく、保守しやすい構造になっている。このサーバーを実際に動かすには、staticディレクトリ内にindex.htmlのようなファイルを作成し、Mainクラスを実行するだけだ。その後、ウェブブラウザでhttp://localhost:9090/index.htmlにアクセスすれば、作成したindex.htmlの内容がブラウザに表示されることを確認できる。

このプロジェクトを通して、ソケット通信の基本、HTTPリクエストとレスポンスの構造、ファイルの読み書き、そして複数のクラスを連携させて一つの機能を作り上げるという、システムエンジニアにとって非常に重要な基礎知識とスキルを学ぶことができるだろう。複雑に見えるウェブサーバーも、基本的な要素に分解すれば一つ一つの処理は比較的シンプルであることが理解できるはずだ。この経験は、将来的にさらに高度なウェブアプリケーションやネットワークサービスを開発する上で貴重な土台となるに違いない。

関連コンテンツ

関連IT用語