2

conversationContext適切なブラウザー キャッシュを提供するために、Apache MyFaces Orchestra が css ファイルへの要求に対してすべての要求に追加するパラメーターを削除したいと考えています。

Bozhoが示唆したように、Orchestrator が探している属性を設定するフィルターを実装しました。

public class ResourceFilter implements Filter {

@Override
public void doFilter(ServletRequest request, ServletResponse theResponse, FilterChain theChain) throws IOException, ServletException {
    if(shouldNotAppendConversation(request)) {
        request.setAttribute(RequestParameterServletFilter.REQUEST_PARAM_FILTER_CALLED, Boolean.TRUE);
    }

    theChain.doFilter(request, theResponse);
}

private boolean shouldNotAppendConversation(ServletRequest theRequest) {
    HttpServletRequest aRequest = (HttpServletRequest) theRequest;
    String aPath = aRequest.getRequestURI();
    if(aPath.endsWith(".css.jsf")) {
        return true;
    }

    return false;
}

@Override
public void init(FilterConfig theFilterConfig) throws ServletException {
}

@Override
public void destroy() {
}
}

それはうまくいきません.パラメータはまだすべてのリクエストに追加されています. デバッグ中に、フィルタが jsf サイトへのリクエストによって最初にヒットすることがわかりました。確かにそのリクエストに を含めたいconversation contextので、フィルターはリクエストをチェーン内の次のフィルターに直接転送します。フィルターにヒットする次のリクエスト (通常は css ファイルのリクエスト) は、すでにconversation contextリクエストに含まれています。

奇妙なことに、フィルターを変更して常に属性を設定すると、すべてのリクエストにconversation context属性がなくなります。ただし、これconversation contextは jsf サイトのリクエストにも含まれていないことを意味します (ただし、含まれている必要があります)。

conversation contextjsf サイトの生成された html 内の css ファイルへのリンクにも属性が含まれているか、フィルターの実装に依存していないことに気付きました。この理由で、2 番目のリクエストにはすでにconversation contextパラメータが含まれていると思いますか?

conversation context属性が設定されていないリクエストだけでなく、Orchestrator がすべてのリクエストにパラメーターを追加する理由がわかりません。

正しく機能するようにフィルターを実装するにはどうすればよいですか?

4

2 に答える 2

3

ページへのリクエストの後にフィルターにヒットする次のリクエスト (CSS ファイルなど) にはconversationContext、このリソースの URL が前のリクエストでページによってレンダリングされた方法であるため、パラメーターが既に含まれています。

したがって、制御conversationContextはレンダリング時に行う必要があります。次のソリューションは、JSF 2 で機能しています (Mojarra 2.1.11、myfaces-orchestra-core20 1.5、RichFaces 4.1.0.Final を使用しています)。特別なサーブレット フィルターはHttpServletResponse、独自のラッパーでラップするだけです。

public class RfOrchestraParamControlFilter implements Filter {
   ...
   @Override
   public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
      response = new RfOrchestraParamControlResponseWrapper((HttpServletResponse)response);
      chain.doFilter(request, response);
   }
   ...
}

応答ラッパーは、リッチフェイス リソースであるためにエンコードされる URL をテストし、エンコード時に現在のスレッドでOrchestra のConversationRequestParameterProvider分離モードをオンにします。

package ...
import javax.faces.application.ResourceHandler;
import org.richfaces.resource.ResourceHandlerImpl;
import org.apache.myfaces.orchestra.conversation.ConversationRequestParameterProvider;

public class RfOrchestraParamControlResponseWrapper extends HttpServletResponseWrapper {

   public RfOrchestraParamControlResponseWrapper(HttpServletResponse httpServletResponse) {
      super(httpServletResponse);
   }

   @Override
   public String encodeURL(String url) {
      if (url.contains(ResourceHandler.RESOURCE_IDENTIFIER) || url.contains(ResourceHandlerImpl.RICHFACES_RESOURCE_IDENTIFIER)) {
         boolean current = ConversationRequestParameterProvider.isInSeparationMode();
         /* Disable conversationContext parameter in current thread for the time of rendering link to a resource */
         ConversationRequestParameterProvider.setInSeparationMode(true);

         String result = super.encodeURL(url);

         /* Restore */
         ConversationRequestParameterProvider.setInSeparationMode(current);
         return result;
      }
      else return super.encodeURL(url);
   }

}

(コンテキスト パスとサーブレット パスがたまたま渡された URL の先頭に追加されるため、リソースであるために URL をテストするときのString.contains()代わりに使用する必要がありました。)String.startsWith()

しかし、それは現時点ではどちらも役に立ちません。その理由は、Orchestrator が で行われる独自の応答ラッピングを使用しRequestParameterFacesContextFactory、このラッピングがフィルターにヒットした後に行われるためです。このように、Orchestrator のラッパーは私たちのラッパーの外部にあることが判明し、その結果url、URL が既に傍受されてconversationContext追加されている場合、ラッパーの受信が遅すぎます。

これを回避するために、実際に同じ作業を行うRequestParameterFacesContextFactoryインターセプターからの効果を置き換えることにより、応答ラッパーを Orchestra のものの外部にする方法があります。残念ながら、別のフィルターを使用することは、そうでない場合でもそれほど精巧ではありませんが、これまでのところ別の方法は見当たりません。 RequestParameterServletFilter

したがって、オーケストラのフィルターのweb.xmlにフィルターを配置します。

<filter>
   <filter-name>requestParameterFilter</filter-name>
   <filter-class>org.apache.myfaces.orchestra.requestParameterProvider.RequestParameterServletFilter</filter-class>
</filter>
<filter>
   <filter-name>myOrchestraFilter</filter-name>
   <filter-class>mypkg.RfOrchestraParamControlFilter</filter-class>
</filter>

<filter-mapping>
   <filter-name>requestParameterFilter</filter-name>
   <servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
<filter-mapping>
   <filter-name>myOrchestraFilter</filter-name>
   <servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
于 2012-11-19T23:36:47.053 に答える