11

カスタムHTTPリクエストヘッダーを検出し、ファイルが自動的にダウンロードされるようにレスポンスヘッダーを挿入するJava「フィルター」を作成しようとしています。このために最も重要な応答ヘッダーは、"Content-Type = Attachment" 応答ヘッダーです。カスタム ヘッダーを挿入する HTTP 要求オブジェクトを作成しました。

function myHttpObject(filePath){
function makeHttpObject() {
    return new XMLHttpRequest();
}

var request = makeHttpObject();

request.open("GET", filePath, false);
request.setRequestHeader("X-Wria-Download", "PDFdownload");
request.send(null);
window.open(filePath);
console.log(request.getAllResponseHeaders());
}

これにより、X-Wria-Download ヘッダーがリクエストに挿入されます。次に、そのリクエスト ヘッダーを検索し、レスポンス ヘッダーを「Content-Type=attachment」に設定する必要がある Java フィルターがあります。

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class Contenttypefilter implements Filter  {

protected FilterConfig filterConfig;

public void init(FilterConfig filterConfig) throws ServletException {
    this.filterConfig = filterConfig;
}

public void destroy() {
    //noop
}

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

    HttpServletRequest req = (HttpServletRequest) request;
    HttpServletResponse res = (HttpServletResponse) response;

    //get the headers we placed in the request
    //based on those request headers, set some response headers

    if(req.getHeader("X-Wria-Download") != null){
        res.setHeader("Content-Type", "application/pdf");
        res.setHeader("Content-Disposition", "attachment; filename=success.pdf");
    }

    chain.doFilter(req,res);
}


}

そしてもちろん、web.xml には、すべての jsp ファイルにフィルターを含めるためのコードがあります。

私を困惑させているのは、応答ファイルにヘッダーが設定されているのに、ダウンロードが正しく行われていないことです。res.setHeader("Content-Disposition", "attachment; filename=success.pdf"); 「if」ステートメントの外側に行を追加しても機能しますが、ダウンロード動作がすべての JSP に適用されますが、これは望ましくありません。

if ステートメントに res.setHeader がある場合、content-disposition を適用しても機能しないのはなぜですか。if ステートメントの外にあるときに動作しますか? 目的の動作を実現する方法についてのアイデアはありますか (カスタム リクエスト ヘッダーを適用した JSP にのみコンテンツの処理を適用します)。

4

4 に答える 4

12

あなたの問題は、フィルターの実行順序に関連していると思いますWeb Context。つまり、Web コンテキスト内の一部のフィルターは、フィルターの後に実行され、ヘッダーをオーバーライドします。

Servlet FilterChain of Responsibilityパターンの実装です

したがって、次のことを試みることができます。

  • chain.doFilter の呼び出し後にヘッダーを設定します。

.

...

chain.doFilter(req,res);

HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;

//get the headers we placed in the request
//based on those request headers, set some response headers

if(req.getHeader("X-Wria-Download") != null){
    res.setHeader("Content-Type", "application/pdf");
    res.setHeader("Content-Disposition", "attachment; filename=success.pdf");
}

このようにして、サーブレットが呼び出された後にコードが実行され、以下で説明するように、フィルターが web.xml で最初に宣言されている場合、setHeaderコードは最後に実行されます (下の画像を参照)。

  • サーブレットが実行された後、フィルターが最後に実行されることを確認してください。つまり、ここで説明するように宣言された最初のサーブレット Filter にする必要があります。

ここに画像の説明を入力

ご覧のとおり、Filter1 (web.xml で最初に宣言されたもの) は、サーブレットが実行される前に実行される最初のものであり、サーブレットが実行された後に最後に実行されるものです。したがって、確実にヘッダーを設定する最後のフィルターにしたい場合は、それを Filter1 として宣言します。

実行の順序は、配置記述子 (web.xml) での宣言の順序によって決まります。

サーブレット仕様 (セクション 6.2.4):

「コンテナが特定のリクエスト URI に適用されるフィルタのチェーンを構築する際に使用する順序は次のとおりです。

"1. 最初に、これらの要素がデプロイメント記述子に現れるのと同じ順序で一致するフィルター マッピング。

「2.次に、これらの要素がデプロイメント記述子に表示されるのと同じ順序で一致するフィルター マッピング。」

したがって、 .xml の最初のフィルターとして宣言するだけweb.xmlです。このようにして、ヘッダーを設定する最後のフィルターになります。そしてもちろん、chain.doFilter既に述べたように、 を呼び出した後にコードにヘッダーを設定します。

于 2012-11-20T22:09:14.037 に答える
0

問題は、フィルターが提供される前に、AjaxRequest (ここでは XMLHttpRequest) のヘッダー (X-Wria-Download) が HttpServletRequest オブジェクトに設定されていないことです。

専用サーブレットを使用して ajax request を処理する方が良いと思います。

于 2012-11-20T04:16:45.580 に答える
0

これを試してください: リクエスト ヘッダーが存在する場合は、リクエストに属性を設定します。次に、の後の属性を確認しchain.doFilter(...)、応答ヘッダーを設定します。

于 2012-11-19T21:57:28.833 に答える