[解決済み] Java Web アプリケーションでアプリケーションサーバーの外側から静的データを提供する最も簡単な方法
質問
Tomcat 上で動作する Java Web アプリケーションを持っています。私は、Web UI とアプリケーションによって生成される PDF ファイルの両方に表示される静的画像をロードしたいと思っています。また、新しい画像は Web UI 経由でアップロードすることによって追加および保存されます。
静的データをWebコンテナ内に格納することでこれを行うのは問題ありませんが、Webコンテナの外からそれらを格納およびロードすることは頭痛の種です。
この際、静的データを提供するためにApacheなどの別のWebサーバーを使うのは避けたいですね。また、画像をバイナリでデータベースに保存するというアイデアも好きではありません。
画像ディレクトリを Web コンテナ外のディレクトリを指すシンボリック リンクにするというような提案をいくつか見ましたが、このアプローチは Windows と *nix 環境の両方で動作するのでしょうか?
画像配信を処理するためにフィルターやサーブレットを書くことを提案する人もいますが、これらの提案は非常に曖昧で、これを達成する方法に関するより詳細な情報へのポインタなしにハイレベルなものでした。
どのように解決するのですか?
イメージ ディレクトリを Web コンテナの外のディレクトリを指すシンボリック リンクにするなどの提案を見ましたが、この方法は Windows と *nix 環境の両方で機能するのでしょうか?
nix ファイルシステムのパス規則を遵守する場合 (すなわち、次のようにスラッシュのみを使用する)
/path/to/files
のようにスラッシュだけを使う)、Windows でも醜い
File.separator
といった文字列の連結をする必要がない。しかし、このコマンドを実行したのと同じ作業ディスク上でのみスキャンされます。したがって、例えばTomcatが以下の場所にインストールされている場合
C:
にインストールされている場合
/path/to/files
が実際に指すのは
C:\path\to\files
.
ファイルがすべてウェブアプリケーションの外部にあり、Tomcat の
DefaultServlet
で処理したい場合、Tomcat で基本的に必要なことは、以下の Context 要素を
/conf/server.xml
内部
<Host>
タグの中にあります。
<Context docBase="/path/to/files" path="/files" />
こうすることで、これらは
http://example.com/files/...
. JBoss EAP 6.x 以前の Tomcat ベースのサーバでは、基本的に同じ方法です。
ここで
. GlassFish/Payaraの設定例があります。
はこちら
と WildFly の設定例があります。
はこちら
.
ファイルの読み書きを自分で制御したい場合は、ファイル名を指定するための
Servlet
を作成する必要があります。
InputStream
を取得します。
FileInputStream
に書き出し、それを
OutputStream
の
HttpServletResponse
.
レスポンス上では
Content-Type
ヘッダを設定し、クライアントがどのアプリケーションが提供されたファイルに関連づけられるかを知ることができるようにします。そして
Content-Length
ヘッダを設定し、クライアントがダウンロードの進捗を計算できるようにします(そうしないと、不明になってしまいます)。そして
Content-Disposition
ヘッダを
attachment
が必要な場合は
として保存
ダイアログが必要な場合、そうでなければ、クライアントはそれをインラインで表示しようとします。最後に、ファイルの内容をレスポンス出力ストリームに書き込むだけです。
このようなサーブレットの基本的な例です。
@WebServlet("/files/*")
public class FileServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
String filename = URLDecoder.decode(request.getPathInfo().substring(1), "UTF-8");
File file = new File("/path/to/files", filename);
response.setHeader("Content-Type", getServletContext().getMimeType(filename));
response.setHeader("Content-Length", String.valueOf(file.length()));
response.setHeader("Content-Disposition", "inline; filename=\"" + file.getName() + "\"");
Files.copy(file.toPath(), response.getOutputStream());
}
}
にマップされた場合
url-pattern
にマップされた場合、例えば
/files/*
で呼び出すことができます。
http://example.com/files/image.png
. この方法では、リクエストをより細かく制御することができます。
DefaultServlet
が行うような、より詳細な制御が可能になります。
if (!file.exists()) file = new File("/path/to/files", "404.gif")
など)。を使うことも
request.getPathInfo()
よりも優先されます。
request.getParameter()
の方が SEO 対策になるし、そうでないと IE が正しいファイル名を選択できないからです。
として保存
.
同じロジックをデータベースからファイルを提供するために再利用することができます。単に
new FileInputStream()
を
ResultSet#getInputStream()
.
これが役立つといいのですが。
こちらもご覧ください。
関連
-
[解決済み] TomcatにおけるNIOとBIOの根本的な違いは何ですか?
-
[解決済み] ERROR: トランスポートエラー202: デバッグモードでTomcat 7を起動すると、バインドに失敗しました。
-
[解決済み] org.apache.catalina.connector.ClientAbortException: java.io.IOException。APRエラー: -32
-
メソッド名に無効な文字が見つかりました。HTTPメソッド名はトークンでなければなりません
-
NamingException: このクラスローダーにバインドされているネーミング・コンテキストがありません。
-
[解決済み] サーバー http:/localhost:8080 は、ユーザー名とパスワードが必要です。とサーバーは言っています。XDB
-
tomcat 起動エラー。ProtocolHandler["ajp-nio-8009"] に関連するエンドポイントの破棄に失敗しました (非常に簡単な解決方法)
-
[解決済み] IntelliJとTomcat...変更したファイルがTomcatで自動認識されない
-
[解決済み] 静的コンテンツ配信用サーブレット
-
[解決済み] Java Web アプリケーションでアプリケーションサーバーの外側から静的データを提供する最も簡単な方法
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
maven reports an error the goal you specified requires a project to execute but there is no POM in this direct...
-
NamingException: このクラスローダーにバインドされているネーミング・コンテキストがありません。
-
tomcat8 で X11GraphicsEnvironment の問題が発生し、クラス sun.awt.X11GraphicsEnvironment を初期化できない。
-
[解決済み] NetBeansからのTomcat起動エラー - '127.0.0.1*' が内部コマンドまたは外部コマンドとして認識されない
-
[解決済み] MaxMetaspaceSizeを設定した方が良いですか?
-
tomcat 起動エラー。ProtocolHandler["ajp-nio-8009"] に関連するエンドポイントの破棄に失敗しました (非常に簡単な解決方法)
-
[解決済み] Tomcat 7.0でのWebアプリケーションのコンテキストパスの設定方法
-
[解決済み] Tomcatのポートを8080から80に変更するには?
-
[解決済み] IntelliJとTomcat...変更したファイルがTomcatで自動認識されない
-
[解決済み] Java Web アプリケーションでアプリケーションサーバーの外側から静的データを提供する最も簡単な方法