3秒でわかる
Java の Web アプリで、ブラウザから直接アクセスできないディレクトリ。設定ファイルやクラス、直接開かせたくない JSP をここに置きます。
もう少し詳しく
どういうものか
WEB-INF は、Java の Web アプリケーション (WAR ファイル) の中に置かれる決まった名前のディレクトリです。Servlet 仕様で「この配下は URL で直接要求されても返してはならない」と定められており、Tomcat や Jetty といったサーブレットコンテナがその遮断を行います。
中身は概ね決まっています。web.xml にサーブレットの割り当てや初期化パラメータを書き、classes/ にコンパイル済みの .class を置き、lib/ に依存する JAR を置きます。加えて、直接開かれたくない JSP をここに入れる使い方が広く行われています。
なぜ必要か
WAR の中の index.html や css/style.css は、置いた場所がそのまま URL になります。この仕組みのままだと、DB の接続情報を書いた設定ファイルやコンパイル済みクラスも、パスを推測されればブラウザから取得できてしまいます。
WEB-INF はその穴を塞ぐための領域です。ここに置いたファイルはサーバー内部からは読めますが、外からの URL では 404 になります。JSP を WEB-INF に置くのも同じ理由で、サーブレットを通さずに JSP を直接開かれると、ログイン判定や必要なデータの準備を飛ばした状態で画面が表示されてしまうためです。
具体例
一般的な WAR の構成と、内部から JSP へ転送するコードです。
myapp.war
├── index.html ← /index.html でアクセスできる
├── css/style.css ← /css/style.css でアクセスできる
└── WEB-INF/
├── <a href="/glossary/web-xml" class="text-primary font-medium underline underline-offset-2 hover:text-primary-dark">web.xml</a> ← URL では取得できない
├── classes/ ← コンパイル済みクラス
├── lib/ ← 依存 JAR
└── views/list.jsp ← /WEB-INF/views/list.jsp は 404 になる// サーブレットの内部からなら WEB-INF 配下へ転送できる
List<Item> items = itemService.findAll();
request.setAttribute("items", items);
request.getRequestDispatcher("/WEB-INF/views/list.jsp")
.forward(request, response);つまずきやすいところ
web-inf や WEB_INF と書いて機能しない。大文字とハイフンで WEB-INF と完全一致していないと、ただのフォルダとして公開されますsendRedirect("/WEB-INF/views/list.jsp") を使い 404 になる。リダイレクトはブラウザに再要求させる動作なので遮断されます。内部で完結する forward を使いますsrc/main/resources/templates などが対応する位置づけで、WEB-INF は登場しません覚え方
WEB-INF は「サーバーだけが入れる部屋」。ブラウザに直接取りに来てほしいものは外、それ以外は中、で振り分けます。