1つの具象を除くすべてのURLに具象フィルターを適用する(つまり、/*
を除く/specialpath
)。
それを行う可能性はありますか?
サンプルコード:
<filter>
<filter-name>SomeFilter</filter-name>
<filter-class>org.somproject.AFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SomeFilter</filter-name>
<url-pattern>/*</url-pattern> <!-- the question is: how to modify this line? -->
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
標準のサーブレットAPIはこの機能をサポートしていません。 Tuckey's one (Apache HTTPDのmod_rewrite
によく似ています)のように、このために書き換えURLフィルターを使用するか、doFilter()
メソッドにチェックを追加することができます。 /*
でリッスンするフィルターの.
String path = ((HttpServletRequest) request).getRequestURI();
if (path.startsWith("/specialpath/")) {
chain.doFilter(request, response); // Just continue chain.
} else {
// Do your business stuff here for all paths other than /specialpath.
}
必要に応じて、無視するパスをフィルターのinit-param
として指定して、web.xml
で制御できるようにすることができます。次のようにフィルターで取得できます。
private String pathToBeIgnored;
public void init(FilterConfig config) {
pathToBeIgnored = config.getInitParameter("pathToBeIgnored");
}
フィルターがサードパーティAPIの一部であり、変更できない場合は、より特定のurl-pattern
にマッピングします。 /otherfilterpath/*
を選択し、/*
に新しいフィルターを作成して、サードパーティフィルターに一致するパスに転送します。
String path = ((HttpServletRequest) request).getRequestURI();
if (path.startsWith("/specialpath/")) {
chain.doFilter(request, response); // Just continue chain.
} else {
request.getRequestDispatcher("/otherfilterpath" + path).forward(request, response);
}
このフィルターが無限ループでそれ自体を呼び出すことを回避するには、REQUEST
のみでリッスン(ディスパッチ)し、FORWARD
のみでサードパーティのフィルターを使用する必要があります。
私はアプローチを使用しました Eric Daughertyによる説明 :403コードで常に応答する特別なサーブレットを作成し、そのマッピングを一般的なサーブレットの前に置きました。
マッピングフラグメント:
<servlet>
<servlet-name>generalServlet</servlet-name>
<servlet-class>project.servlet.GeneralServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>specialServlet</servlet-name>
<servlet-class>project.servlet.SpecialServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>specialServlet</servlet-name>
<url-pattern>/resources/restricted/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>generalServlet</servlet-name>
<url-pattern>/resources/*</url-pattern>
</servlet-mapping>
そしてサーブレットクラス:
public class SpecialServlet extends HttpServlet {
public SpecialServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.sendError(HttpServletResponse.SC_FORBIDDEN);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.sendError(HttpServletResponse.SC_FORBIDDEN);
}
}
このアプローチは、特定のフィルターと次のすべてのフィルターを防止する場合に機能します。あなたが例ならそれはうまくいくはずですアプリケーションロジック(GuiceFilterなどのフィルターを使用)を許可する代わりに、一部のコンテンツをサーブレットコンテナー内の静的リソースとして提供する場合:
静的リソースファイルを含むフォルダーをデフォルトのサーブレットにマップします。サーブレットフィルターを作成し、web.xmlでGuiceFilterの前に配置します。作成したフィルターでは、一部の要求をGuiceFilterに転送することと、他の要求を直接ディスパッチャーに転送することを区別できます。例が続きます...
web.xml
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/static/*</url-pattern>
</servlet-mapping>
<filter>
<filter-name>StaticResourceFilter</filter-name>
<filter-class>com.project.filter.StaticResourceFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>StaticResourceFilter</filter-name>
<url-pattern>/static/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>guiceFilter</filter-name>
<filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>guiceFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
StaticResourceFilter.class
public class StaticResourceFilter implements Filter {
private final static Logger LOGGER = LoggerFactory.getLogger(StaticResourceFilter.class);
private static final String RESOURCE_PATH = "/static/";
@Override
public void init(final FilterConfig filterConfig) throws ServletException {
LOGGER.info("StaticResourceFilter initialized");
}
@Override
public void doFilter(final ServletRequest request, final ServletResponse response,
final FilterChain chain) throws IOException, ServletException {
String path = ((HttpServletRequest) request).getServletPath();
if (path.toLowerCase().startsWith(RESOURCE_PATH)) {
request.getRequestDispatcher(path).forward(request, response);
} else {
chain.doFilter(request, response);
}
}
@Override
public void destroy() {
LOGGER.info("StaticResourceFilter destroyed");
}
}
残念ながら、後続のステップを保持しながら、フィルターチェーンの単一のステップをスキップするだけの場合、これは機能しません。
できるとは思わない、他の設定の代替手段は、フィルタリングしたいパスを列挙することなので、/*
の代わりに/this/*
と/that/*
などにいくつかを追加できます。 、しかし、それらのパスがたくさんある場合、それは十分な解決につながりません。
できることは、一致したパスのフィルター機能をスキップするために使用される式(正規表現など)を提供するフィルターにパラメーターを追加することです。サーブレットコンテナは引き続きこれらのURLのフィルターを呼び出しますが、構成をより適切に制御できます。
編集
フィルターを制御できないことを述べたので、できることは、スキップするURLパスが存在し、@などのフィルターチェーンに従う場合を除いて、そのメソッドでsuper
メソッドを呼び出すフィルターから継承することです。 BalusCは、同じ状況でフィルターとデリゲートをインスタンス化するフィルターを提案または構築しました。どちらの場合も、フィルターパラメーターには、追加する式パラメーターと、継承または委任するフィルターのパラメーターの両方が含まれます。
委任フィルター(ラッパー)を作成する利点は、ラップされたフィルターのフィルタークラスをパラメーターとして追加し、このような他の状況で再利用できることです。
また、Java codeのURLパターン(/ {servicename}/api/stats /)に基づいてフィルタリングする必要がありました。
if (path.startsWith("/{servicename}/api/statistics/")) {
validatingAuthToken(((HttpServletRequest) request).getHeader("auth_token"));
filterChain.doFilter(request, response);
}
しかし、奇妙なことに、そのサーブレットは(/ *)以外のURLパターンをサポートしていません。これは、サーブレットAPIの非常に一般的なケースです。
同じ問題が発生しましたが、下に表示されるアンサーが見つかります。
web.xml
<!-- set this param value for the filter-->
<init-param>
<param-name>freePages</param-name>
<param-value>
MainFrame.jsp;
</param-value>
</init-param>
filter.Java
strFreePages = config.getInitParameter("freePages"); //get the exclue pattern from config file
isFreePage(strRequestPage) //decide the exclude path
このようにして、具象Filterクラスに嫌がらせをする必要はありません。
何らかの理由で元のフィルターマッピング(私の場合は「/ *」)を変更できず、変更できないサードパーティのフィルターにディスパッチしている場合、次のことが役立ちます。
以下は、Weblogic 12.1.3で機能します。
import org.Apache.commons.lang3.reflect.FieldUtils; import javax.servlet.Filter; [...] @Override public void doFilter(ServletRequest request, ServletRespons response, FilterChain chain) throws IOException, ServletException { String path = ((HttpServletRequest) request).getRequestURI(); if(!bypassSWA(path)){ swpFilterHandler.doFilter(request, response, chain); } else { try { ((Filter) (FieldUtils.readField( (FieldUtils.readField( (FieldUtils.readField(chain, "filters", true)), "last", true)), "item", true))) .doFilter(request, response, chain); } catch (IllegalAccessException e) { e.printStackTrace(); } } }