136

Tomcat で Java Web アプリケーションを実行しています。Web UI とアプリケーションによって生成された PDF ファイルの両方に表示される静的画像を読み込みたいと考えています。また、Web UI を介してアップロードすることにより、新しい画像が追加および保存されます。

静的データを Web コンテナー内に保管することによってこれを行うことは問題ではありませんが、それらを Web コンテナーの外部から保管およびロードすることは頭を悩ませています。

この時点では、静的データを提供するために Apache のような別の Web サーバーを使用したくありません。また、画像をデータベースにバイナリで保存するという考えも好きではありません。

画像ディレクトリを Web コンテナの外部のディレクトリを指すシンボリック リンクにするなどの提案を見てきましたが、このアプローチは Windows と *nix 環境の両方で機能しますか?

画像の提供を処理するためのフィルターまたはサーブレットを作成することを提案する人もいますが、これらの提案は非常に曖昧で高レベルであり、これを実現する方法に関する詳細情報へのポインターがありません。

4

10 に答える 10

172

画像ディレクトリを Web コンテナーの外部のディレクトリを指すシンボリック リンクにするなどの提案を見てきましたが、このアプローチは Windows と *nix 環境の両方で機能しますか?

*nix ファイルシステム パス ルールを順守する場合 (つまり、 のようにスラッシュのみを使用する場合)、醜い文字列連結/path/to/filesをいじる必要なく、Windows でも動作します。File.separatorただし、このコマンドが呼び出された場所と同じ作業ディスクでのみスキャンされます。したがって、たとえば Tomcat が にインストールされているC:場合、/path/to/filesは実際には を指しC:\path\to\filesます。

ファイルがすべて webapp の外にあり、DefaultServletそれらを Tomcat で処理したい場合、基本的に 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書き込むための を作成する必要があります。OutputStreamHttpServletResponse

応答では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.pngDefaultServletこのようにして、デフォルトのイメージを提供するなど、よりもリクエストをより詳細に制御できます(などif (!file.exists()) file = new File("/path/to/files", "404.gif"))。また、request.getPathInfo()上記の を使用することをお勧めします。request.getParameter()これは、より SEO フレンドリーであり、そうしないと IE が [名前を付けて保存] 中に正しいファイル名を選択しないためです。

データベースからファイルを提供するために同じロジックを再利用できます。に置き換えるだけnew FileInputStream()ですResultSet#getInputStream()

お役に立てれば。

以下も参照してください。

于 2009-11-28T11:57:53.137 に答える
9

イメージを固定パス (例: /var/images、または c:\images) に配置し、アプリケーション設定 (私の例では Settings.class で表されています) に設定を追加して、それらをロードすることで、これを行うことができます。そのように、HttpServletあなたのもので:

String filename = Settings.getValue("images.path") + request.getParameter("imageName")
FileInputStream fis = new FileInputStream(filename);

int b = 0;
while ((b = fis.read()) != -1) {
        response.getOutputStream().write(b);
}

または、画像を操作する場合:

String filename = Settings.getValue("images.path") + request.getParameter("imageName")
File imageFile = new File(filename);
BufferedImage image = ImageIO.read(imageFile);
ImageIO.write(image, "image/png", response.getOutputStream());

次に、htmlコードは次のようになります<img src="imageServlet?imageName=myimage.png" />

もちろん、さまざまなコンテンツ タイプ (たとえば、ファイル拡張子に基づく "image/jpeg") を提供することを検討する必要があります。また、キャッシュを提供する必要があります。

さらに、image.getScaledInstance(w, h, Image.SCALE_SMOOTHもちろんパフォーマンスを考慮して、幅と高さのパラメータを引数として指定し、) を使用することで、このサーブレットを使用して画像の品質を再スケーリングすることもできます。

于 2009-11-28T11:30:14.433 に答える
8

server.xml に追加:

 <Context docBase="c:/dirtoshare" path="/dir" />

web.xml で dir ファイル リスト パラメータを有効にします。

    <init-param>
        <param-name>listings</param-name>
        <param-value>true</param-value>
    </init-param>
于 2015-05-12T10:27:58.287 に答える
8

要件 : WEBROOT ディレクトリ外またはローカル ディスクから静的リソース (画像/ビデオなど) にアクセスできること

ステップ 1 :
tomcat サーバーの webapps の下にフォルダーを作成します。フォルダー名を myproj とします。

ステップ 2 :
myproj の下に、この下に WEB-INF フォルダーを作成し、単純な web.xml を作成します。

web.xml の下のコード

<web-app>
</web-app>

上記の 2 つの手順のディレクトリ構造

c:\programfile\apachesoftwarefoundation\tomcat\...\webapps
                                                            |
                                                            |---myproj
                                                            |   |
                                                            |   |---WEB-INF
                                                                |   |
                                                                    |---web.xml

ステップ 3:
次の場所に myproj.xml という名前の xml ファイルを作成します。

c:\programfile\apachesoftwarefoundation\tomcat\conf\catalina\localhost

myproj.xml のコード:

<Context path="/myproj/images" docBase="e:/myproj/" crossContext="false" debug="0" reloadable="true" privileged="true" /> 

ステップ 4:
4 A) ハードディスクの E ドライブに myproj という名前のフォルダーを作成し、新しいフォルダーを作成します。

imagesという名前のフォルダーを作成し、imagesフォルダーにいくつかの画像を配置します(e:myproj\images\)

myfoto.jpg が下に配置されているとします。e:\myproj\images\myfoto.jpg

4 B) WEB-INF という名前のフォルダーをe:\myproj\WEB-INF作成し、WEB-INF フォルダーに web.xml を作成します。

web.xml のコード

<web-app>
</web-app>

ステップ 5:
index.html という名前の .html ドキュメントを作成し、e:\myproj の下に配置します。

index.html の下のコード Myproj へようこそ

上記の手順 4 と手順 5 のディレクトリ構造は次のとおりです。

E:\myproj
    |--index.html
    |
    |--images
    |     |----myfoto.jpg
    |
    |--WEB-INF
    |     |--web.xml

ステップ 6:
Apache Tomcat サーバーを起動します

ステップ 7:
ブラウザーを開き、次のように URL を入力します。

http://localhost:8080/myproj    

次に、index.html で提供されるコンテンツを表示します

ステップ 8:
ローカル ハードディスク (webroot の外部) の下にあるイメージにアクセスするには

http://localhost:8080/myproj/images/myfoto.jpg
于 2013-03-16T04:46:25.003 に答える
2

にディスパッチすることにした場合は、シンボリックリンクをトラバースできるようにするためにFileServletも必要allowLinking="true"になります。context.xmlFileServlet

http://tomcat.apache.org/tomcat-6.0-doc/config/context.htmlを参照してください。

于 2011-01-25T17:03:01.620 に答える
-1

さらにシンプルにしました。問題: CSS ファイルに img フォルダーへの URL リンクが含まれていました。404 を取得します。

存在しないURL http://tomcatfolder:port/img/blablah.pngを見ました。しかし、それは実際には Tomcat の ROOT アプリを指しています。

そのため、webapp からその ROOT アプリに img フォルダーをコピーしました。動作します!

もちろん、本番環境にはお勧めしませんが、これは内部ツール開発アプリ用です。

于 2016-08-31T14:57:02.827 に答える