Filterはページ内のinclude方式の要求をブロックし,その要求のURLを取得する.
最近、プロジェクトにキャッシュフレームワークを作成し、プラグインで追加する必要があります.プロファイルを使用して、ページをキャッシュするURLを指定する必要があります.
そこで遮断器Filterを作りたいと思った.
このFilterは、まずすべてのリクエストをブロックしてからリクエストのURLを取得し、構成中のキャッシュが必要なURLと比較し、キャッシュが必要な場合はキャッシュ処理に入り、キャッシュが必要でない場合は次のFitlerに直接移行することができる.
具体的なキャッシュ処理は、オープンソースフレームワークOScacheを採用している.
案は比較的簡単です.テストでは、一般的なFitlerはブラウザのアドレスバーからのリクエストをブロックするしかないことがわかりました.ページの読み込み方法の要求ページは、ブロックできません.
関連資料の表示http://www.ibm.com/developerworks/java/library/j-tomcat2/結論を出す:
サーブレット2.3では,Fitlerはinclude,forward,error方式からの要求をブロックできない.
Sellvet 2.4では、上記の3つのリクエストをブロックできるようにFilterの機能が強化されています.ただし、プロファイルに構成を追加する必要があります.
この方式ではincludeリクエストをブロックできません.
次のように変更します.
コンフィギュレーション・ファイルで、コンフィギュレーションを追加します.
request Filterは、一致するrequest方式のリクエストのみをブロックします.デフォルトです.
include Filterは、一致するincldue方式のリクエストのみをブロックできます.
forward Filterは、一致するforward方式のリクエストのみをブロックできます.
error Filterは、一致するerror方式のリクエストのみをブロックできます.
dispatcherは、様々なニーズを組み合わせるために複数を構成することができる.
たとえば、上記の構成では、Fitlerはrequestおよびinclude方式のリクエストをブロックできます.
以上の構成により、Filterがincludeにブロックしたリクエストになります.(もちろんtomcatはservlet 2.4をサポートする必要があります)
これで問題を解決した.
その後のテストでは、Filterはincldueの要求をブロックしたが、FilterではそのincldueのURLを取得できないことが分かった.
プロジェクトのキャッシュスキームが必要であるため,URL要求を取得し,キャッシュが必要か否かを判断する.したがって、そのincludeリクエストのURLを取得する必要があります.
FilterではhttpRequest.getRequestURI(); 取り出したURL:
1.requestリクエストの場合、取得したURLは正しい.
2.include要求の場合、取得したURLは、そのinclude要素を含む元ページのURLである
例えばmain.jspページに
Fitlerがinclude要求をブロックすると、httpRequest.getRequestURI(); 得られたのはmainです.私が必要とするindexではなくjspです.jsp
でもhttpRequest.getParameter("type");入力されたパラメータ「test」が得られます.
ネットで半日探しても、答えはありません.
最後にOScacheソースコードで方法を発見した.
httpRequest.getAttribute("javax.servlet.include.request_uri")
この方法によりinclude要求のURL値を直接取り出すことができる.
それについては
javax.servlet.include.request_uri「パラメータがどのように設定されているのか、まだよく研究されていません.時間が緊張しているので、先に使って、後で検討しましょう.
もう一つの問題が見つかりました.
Filterでincldue方式のリクエストをブロックした後,受信したすべてのパラメータを取得するとrequestのリクエストパラメータも読み出される.
例えば、要求ページ/index.jsp?type 1=request¶m 1=test 1でindex.jspページに
アクセス/index.jsp?type 1=request¶m 1=test 1の場合、上記の方法でincludeリクエスト/mainをブロックする.jsp?type2=include¶m2=test2
Filterの中のこの要求のすべてのパラメータを取得する時、/index.jspのパラメータ(type 1=request¶m 1=test 1)も読みだします
このメソッドが返す結果は:/main.jsp?type2=include¶m2=test2&type1=request¶m1=test1
これで含む、indexが取得する.jspのパラメータ.
私は今include要求のパラメータ、すなわち/mainだけを取得したいと思っています.jsp?type 2=include¶m 2=test 2のパラメータ部分type 2=include¶m 2=test 2
でもrequest.getParameter()メソッドは,どのパラメータがinclude要求のパラメータであるか判断できない.
以上のヒントを得て、他のAttributeNameがincludeリクエストのパラメータだけを取得できるのではないかと思いました.
テストを通して、やはりこのAttributeName:“javax.servlet.include.query_string”が発見されました.
このパラメータ文字列は、一言で取得できます.
この結果は、type 2=include¶m 2=test 2がinclude要求のみに必要なパラメータである.
そこで遮断器Filterを作りたいと思った.
このFilterは、まずすべてのリクエストをブロックしてからリクエストのURLを取得し、構成中のキャッシュが必要なURLと比較し、キャッシュが必要な場合はキャッシュ処理に入り、キャッシュが必要でない場合は次のFitlerに直接移行することができる.
具体的なキャッシュ処理は、オープンソースフレームワークOScacheを採用している.
案は比較的簡単です.テストでは、一般的なFitlerはブラウザのアドレスバーからのリクエストをブロックするしかないことがわかりました.ページの読み込み方法の要求ページは、ブロックできません.
関連資料の表示http://www.ibm.com/developerworks/java/library/j-tomcat2/結論を出す:
サーブレット2.3では,Fitlerはinclude,forward,error方式からの要求をブロックできない.
Sellvet 2.4では、上記の3つのリクエストをブロックできるようにFilterの機能が強化されています.ただし、プロファイルに構成を追加する必要があります.
- <filter>
- <filter-name>Cachefilter-name>
- <filter-class>prx.cache.filter.CacheFilterfilter-class>
- <init-param>
-
- <param-name>refreshPeriodparam-name>
- <param-value>120param-value>
- init-param>
- filter>
-
- <filter-mapping>
- <filter-name>Cachefilter-name>
- <url-pattern>/*url-pattern>
- filter-mapping>
この方式ではincludeリクエストをブロックできません.
次のように変更します.
- <filter>
- <filter-name>Cachefilter-name>
- <filter-class>prx.cache.filter.CacheFilterfilter-class>
- <init-param>
-
- <param-name>refreshPeriodparam-name>
- <param-value>120param-value>
- init-param>
- filter>
-
- <filter-mapping>
- <filter-name>Cachefilter-name>
- <url-pattern>/index.jspurl-pattern>
- <dispatcher>requestdispatcher>
-
- <dispatcher>includedispatcher>
- filter-mapping>
コンフィギュレーション・ファイルで、コンフィギュレーションを追加します.
request Filterは、一致するrequest方式のリクエストのみをブロックします.デフォルトです.
include Filterは、一致するincldue方式のリクエストのみをブロックできます.
forward Filterは、一致するforward方式のリクエストのみをブロックできます.
error Filterは、一致するerror方式のリクエストのみをブロックできます.
dispatcherは、様々なニーズを組み合わせるために複数を構成することができる.
たとえば、上記の構成では、Fitlerはrequestおよびinclude方式のリクエストをブロックできます.
以上の構成により、Filterがincludeにブロックしたリクエストになります.(もちろんtomcatはservlet 2.4をサポートする必要があります)
これで問題を解決した.
その後のテストでは、Filterはincldueの要求をブロックしたが、FilterではそのincldueのURLを取得できないことが分かった.
プロジェクトのキャッシュスキームが必要であるため,URL要求を取得し,キャッシュが必要か否かを判断する.したがって、そのincludeリクエストのURLを取得する必要があります.
- public void doFilter(ServletRequest request, ServletResponse response,
- FilterChain chain) throws IOException, ServletException {
-
- HttpServletRequest httpRequest = (HttpServletRequest)request;
-
- // url , :/PrxWebCache/index.jsp
- String url = httpRequest.getRequestURI();
- System.out.println(url);
-
- int cacheGrade = CacheUtils.isNeedCacheUrl(url);
- if(cacheGrade != 0) { // url
- String key = CacheUtils.createKeyByUrl(httpRequest);
- boolean isInCache = CacheUtils.isInCache(httpRequest, key, cacheGrade);
- if(isInCache) {
- try {
- String content = (String)CacheUtils.getFromCache(httpRequest, key, cacheGrade, refreshPeriod);
- System.out.println(" ");
- response.getWriter().print(content);
- } catch (NeedsRefreshException e) { // ,
- System.out.println(" ");
- cacheAndResponseContent(httpRequest, response, chain, key, cacheGrade);
- }
- } else {
- // , ,
- cacheAndResponseContent(httpRequest, response, chain, key, cacheGrade);
- }
- } else {
- chain.doFilter(request, response);
- }
- }
FilterではhttpRequest.getRequestURI(); 取り出したURL:
1.requestリクエストの場合、取得したURLは正しい.
2.include要求の場合、取得したURLは、そのinclude要素を含む元ページのURLである
例えばmain.jspページに
Fitlerがinclude要求をブロックすると、httpRequest.getRequestURI(); 得られたのはmainです.私が必要とするindexではなくjspです.jsp
でもhttpRequest.getParameter("type");入力されたパラメータ「test」が得られます.
ネットで半日探しても、答えはありません.
最後にOScacheソースコードで方法を発見した.
httpRequest.getAttribute("javax.servlet.include.request_uri")
この方法によりinclude要求のURL値を直接取り出すことができる.
それについては
javax.servlet.include.request_uri「パラメータがどのように設定されているのか、まだよく研究されていません.時間が緊張しているので、先に使って、後で検討しましょう.
もう一つの問題が見つかりました.
Filterでincldue方式のリクエストをブロックした後,受信したすべてのパラメータを取得するとrequestのリクエストパラメータも読み出される.
例えば、要求ページ/index.jsp?type 1=request¶m 1=test 1でindex.jspページに
アクセス/index.jsp?type 1=request¶m 1=test 1の場合、上記の方法でincludeリクエスト/mainをブロックする.jsp?type2=include¶m2=test2
Filterの中のこの要求のすべてのパラメータを取得する時、/index.jspのパラメータ(type 1=request¶m 1=test 1)も読みだします
- /**
- * URL , :url=/index.jsp?type=1&searchWord=java, type=1&searchWord=java
- * @param request
- */
- private static String getSortedQueryString(HttpServletRequest request) {
- Map paramMap = request.getParameterMap();
-
- if (paramMap.isEmpty()) {
- return null;
- }
-
- Set paramSet = new TreeMap(paramMap).entrySet();
-
- StringBuffer buf = new StringBuffer();
-
- boolean first = true;
-
- for (Iterator it = paramSet.iterator(); it.hasNext();) {
- Map.Entry entry = (Map.Entry) it.next();
- String[] values = (String[]) entry.getValue();
-
- for (int i = 0; i
- String key = (String) entry.getKey();
-
- if ((key.length() != 10) || !"jsessionid".equals(key)) {
- if (first) {
- first = false;
- } else {
- buf.append('&');
- }
-
- buf.append(key).append('=').append(values[i]);
- }
- }
- }
-
- // We get a 0 length buffer if the only parameter was a jsessionid
- if (buf.length() == 0) {
- return null;
- } else {
- return buf.toString();
- }
- }
このメソッドが返す結果は:/main.jsp?type2=include¶m2=test2&type1=request¶m1=test1
これで含む、indexが取得する.jspのパラメータ.
私は今include要求のパラメータ、すなわち/mainだけを取得したいと思っています.jsp?type 2=include¶m 2=test 2のパラメータ部分type 2=include¶m 2=test 2
でもrequest.getParameter()メソッドは,どのパラメータがinclude要求のパラメータであるか判断できない.
以上のヒントを得て、他のAttributeNameがincludeリクエストのパラメータだけを取得できるのではないかと思いました.
テストを通して、やはりこのAttributeName:“javax.servlet.include.query_string”が発見されました.
このパラメータ文字列は、一言で取得できます.
- (String)request.getAttribute("javax.servlet.include.query_string");
この結果は、type 2=include¶m 2=test 2がinclude要求のみに必要なパラメータである.