The solution below has been implemented before finding mod_proxy_uml - but replaced by this one for three reasons:
- mod_proxy_html is far simpler to use, just one or two lines of Apache configuration;
- The application at jboss level runs unmodified, without needing to build a different ear for testing or production.
- It transfers part of the processing to the apache serve.r
Anyway, we publish the solution because it might be useful in some situations.
JSF pages are generated by a "view handler" and it is possible to write a custom implementation. Based on [1], we implemented a view handler that replaces the context path by an arbitrary value.
As we use Facelets, we extend the Facelet ViewHandler instead of the basical JSF one and just override the two relevant methods.
import javax.faces.application.ViewHandler;
import javax.faces.context.FacesContext;
import com.sun.facelets.FaceletViewHandler;
/**
* Replaces the context path in the links generated
* by JSF by an arbitrary value
* configured as context parameter.
*
* The alternative context path should be configured in
* web.xml with name "br.com.net2tel.PROXY_CONTEXT_PATH"
*
* (this is needed to use the app behind a reverse proxy,
* with a different context path).
*/
public class ReverseProxyViewHandler extends FaceletViewHandler {
private ViewHandler defaultHandler;
public ReverseProxyViewHandler(ViewHandler defaultHandler) {
super(defaultHandler);
this.defaultHandler = defaultHandler;
}
@Override
public String getActionURL(FacesContext context, String viewId) {
String actionURL = defaultHandler.getActionURL(context, viewId);
return getProxyiedURL(context, actionURL);
}
@Override
public String getResourceURL(FacesContext context, String path) {
return getProxyiedURL(context, path);
}
/**
* Actual string replacement. Simply replaces the context path
* in the passed URL. For the root context, (/) just removes
* the context path.
*
* @param context Faces context (used to retrieve application context path
* and init parameter)
* @param path Action or resource path to be modified
* @return URL with changed context path
*/
private String getProxyiedURL(FacesContext context, String path) {
String contextPath = context.getExternalContext().getRequestContextPath();
String proxyPath = context.getExternalContext().getInitParameter(
"br.com.net2tel.PROXY_CONTEXT_PATH");
// For root proxy context, simply remove context path
if ("/".equals(proxyPath))
return path.replaceFirst(contextPath, "");
else
return path.replaceFirst(contextPath, proxyPath);
}
}
Two additional steps are necessary: configure the init parameter in web.xml and register the view handler in
faces-config.xml
br.com.net2tel.portability.ui.viewhandlers.ReverseProxyViewHandler
web.xml
br.com.net2tel.PROXY_CONTEXT_PATH /
References:
[1] "Publishing JSF application from behind a proxy"
Ok, now we should have everything ok. We faced one more problem, solved in two lines of configuration (already included in "Basical Apache Setup"). This is the covered by the next post: Form-based Authentication

0 comments:
Post a Comment