フィルター/サーブレットでリクエストをインターセプトし、いくつかのパラメーターを追加したいと考えています。ただし、リクエストは「setParameter」メソッドを公開せず、パラメータ マップを操作すると、ロックされていることを示すエラーがスローされます。私が試すことができる代替手段はありますか?
6 に答える
メソッドをサブクラス化HttpServletRequestWrapper
し、オーバーライドしgetParameter
ます。このクラスの説明は次のとおりです。
要求をサーブレットに適合させたい開発者がサブクラス化できる HttpServletRequest インターフェースの便利な実装を提供します。
フィルターで、リクエストをサブクラスのインスタンスにラップします。
通常、元の HttpServletRequest を、元のリクエストのプロキシとして機能する新しい CustomHttpServletRequest にラップし、この新しい CustomHttpServletRequest をフィルター チェーンに渡します。
この CustomHttpServletRequest では、getParameterNames、getParameter、getParameterMap メソッドをオーバーライドして、必要なパラメーターを返すことができます。
これはフィルタの例です:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletRequest customRequest = new CustomHttpServletRequest(httpRequest);
customRequest.addParameter(xxx, "xxx");
chain.doFilter(customRequest, response);
}
HttpServletRequest を新しい HttpServletRequestWrapper オブジェクトにラップし、いくつかのメソッドを上書きできます。
次のコードはhttp://www.ocpsoft.org/opensource/how-to-safely-add-modify-servlet-request-parameter-values/からのものです。
フィルタにパラメータを追加するには:
public class MyFilter implements Filter {
...
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
if (request instanceof HttpServletRequest) {
HttpServletRequest httprequest = (HttpServletRequest) request;
Map<String, String[]> extraParams = new HashMap<String, String[]>();
extraParams.put("myparamname", String[] { "myparamvalue" });
request = new WrappedRequestWithParameter(httprequest, extraParams);
}
chain.doFilter(request, response);
}
...
class WrappedRequestWithParameter extends HttpServletRequestWrapper {
private final Map<String, String[]> modifiableParameters;
private Map<String, String[]> allParameters = null;
public WrappedRequestWithParameter(final HttpServletRequest request, final Map<String, String[]> additionalParams) {
super(request);
modifiableParameters = new TreeMap<String, String[]>();
modifiableParameters.putAll(additionalParams);
}
@Override
public String getParameter(final String name) {
String[] strings = getParameterMap().get(name);
if (strings != null) {
return strings[0];
}
return super.getParameter(name);
}
@Override
public Map<String, String[]> getParameterMap() {
if (allParameters == null) {
allParameters = new TreeMap<String, String[]>();
allParameters.putAll(super.getParameterMap());
allParameters.putAll(modifiableParameters);
}
// Return an unmodifiable collection because we need to uphold the interface contract.
return Collections.unmodifiableMap(allParameters);
}
@Override
public Enumeration<String> getParameterNames() {
return Collections.enumeration(getParameterMap().keySet());
}
@Override
public String[] getParameterValues(final String name) {
return getParameterMap().get(name);
}
}
}
まず、リクエストを受け取り、そのすべてのパラメータを読み取る必要があります。次に、元のパラメーターと新しいパラメーターを使用して別の要求を作成し、再度送信します。
HttpServletRequest は不変であり、変更する方法はありません。
変数をリクエスト パラメーターに追加するのではなく、単にリクエスト スコープ属性として保存しないのはなぜですか?
それ以外の場合は、厳密に型指定された setAttribute() メソッドを使用できます。したがって、 getAttribute() メソッドを使用できます...