To provide proper browser caching I want to get rid of the conversationContext
parameter, that Apache MyFaces Orchestra adds to every request, for requests to css files.
As Bozho suggested, I've implemented a filter that sets the attribute Orchestra is looking for.
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() {
}
}
That doesn't work the parameter is still appended to every request. While debugging, I've found out that the filter gets first hit by a request to the jsf site. For sure I want to include the conversation context
in that request, so the filter forwards the request directly to the next filter in the chain. The next request that hits the filter (usually the request for a css file) has already the conversation context
included in the request.
The strange thing is, if I modify the filter to always set the attribute, all request will not have the conversation context
attribute. But that means, the conversation context
is also not included in the request for the jsf site (but should).
I've noticed that the links to css files in the generated html of the jsf site also contains the conversation context
attribute or not depending on the filter implementation. I guess for this reason the second request has already included the conversation context
parameter?
I don't understand why Orchestra is appending the conversation context
parameter to every request and not just for the requests where the attribute is not set.
How can I implement the filter to work correctly?
The next request (e.g. for a CSS file) hitting your filter after the request to your page has already the
conversationContext
parameter included just because this is how the url for this resource has been rendered by the page in the previous request.So the control over
conversationContext
should be taken at render time. The following solution is working for me with JSF 2 (I am using Mojarra 2.1.11, myfaces-orchestra-core20 1.5, RichFaces 4.1.0.Final). A special servlet filter is doing nothing but wrapsHttpServletResponse
with our own wrapper:The response wrapper tests the url to be encoded for being a richfaces resource and turns Orchestra's
ConversationRequestParameterProvider
's separation mode on in the current thread for the time of encoding:(I've had to use
String.contains()
instead ofString.startsWith()
when testing the url for being a resource as context path and servlet path happen to prepend the passed url.)However that does not help either by this moment. The reason is that Orchestra uses its own response wrapping that takes place in its
RequestParameterFacesContextFactory
, and this wrapping happens after our filter is hit. In this way Orchestra's wrapper turns out to be external to our one which results in our wrapper receivingurl
too late, when the url has already been intercepted andconversationContext
appended.To avoid this we have a way to make our response wrapper external to Orchestra's one by replacing effect from
RequestParameterFacesContextFactory
interceptor withRequestParameterServletFilter
which actually does the same work. Unfortunately using another filter is not quite exquisite where we might not, but I don't see another way so far.So, in
web.xml
place your filter after Orchestra's one: