问题描述
假设以下应用程序格局:
Suppose the following application landscape:
+-----------------+
| App server |
+-----------------+
| | +-------+
| ear1 | | |
| +-web1 (/ctx1) +--<-- http://localhost/ctx1/xxx/ --+ +--<-- http://www.example.com/xxx/
| | | |
| | | proxy |
| ear2 | | |
| +-web2 (/ctx2) +--<-- http://localhost/ctx2/yyy/ --+ +--<-- http://abc.example.com/yyy/
| | | |
+-----------------+ +-------+
如您所见,代理(在我的情况下为nginx
)将请求转发到单个应用程序服务器实例,该实例又具有多个具有不同上下文路径的Web模块.当然,我不希望我的公共服务器公开内部上下文根,并且代理服务器可以很好地完成它的工作,包装和拆开http请求等.但是仍然存在一个大问题:JSF生成的html代码(链接,css,js资源,表单操作)包含上下文路径(在我的情况下为/ctx1
和/ctx2
).这就是我要避免的事情.
As you can see, proxy (nginx
in my case) is forwarding requests to to a single application server instance, which in turn has multiple web modules with different context paths. Of course I dont want my public server to expose internal context roots and proxy does it's job well, wraps and unwraps http requests, etc. But there is still one big problem: JSF-generated html code (links, css, js resources, form actions) contains context paths, /ctx1
and /ctx2
in my case. That's what I want to avoid.
除了使用越来越多的应用服务器实例(域),导致我的硬件资源逐渐消失之外,目前我没有任何解决方案.据我了解,我需要用一些包装器扩展我的JSF应用程序,这些包装器可能已在faces-config.xml
中注册,这将删除生成的html中的上下文前缀.也欢迎任何其他解决方案.
I nave no solution at this moment of time except of using more and more different instances (domains) of application server, causing my hardware resources to fade away. As i understand it, I need to extend my JSF applications with some wrappers, potentially registered in faces-config.xml
, which would remove context prefix in generated html. Any other solutions are also welcome.
请指向正确的方向.
推荐答案
我正在发布解决方案,该解决方案可能对其他面临相同问题的人有所帮助.我要做的就是实现自己的javax.faces.application.ViewHandler
并将其注册到faces-config.xml
:
I'm posting solution which may be helpful for others facing the same problem. All I needed to do is implementing my own javax.faces.application.ViewHandler
and register it in faces-config.xml
:
public class CustomViewHandler extends ViewHandlerWrapper {
private ViewHandler wrappped;
public CustomViewHandler(ViewHandler wrappped) {
super();
this.wrappped = wrappped;
}
@Override
public ViewHandler getWrapped() {
return wrappped;
}
@Override
public String getActionURL(FacesContext context, String viewId) {
String url = super.getActionURL(context, viewId);
return removeContextPath(context, url);
}
@Override
public String getRedirectURL(FacesContext context, String viewId, Map<String, List<String>> parameters, boolean includeViewParams) {
String url = super.getRedirectURL(context, viewId, parameters, includeViewParams);
return removeContextPath(context, url);
}
@Override
public String getResourceURL(FacesContext context, String path) {
String url = super.getResourceURL(context, path);
return removeContextPath(context, url);
}
private String removeContextPath(FacesContext context, String url) {
ServletContext servletContext = (ServletContext) context.getExternalContext().getContext();
String contextPath = servletContext.getContextPath();
if("".equals(contextPath)) return url; // root context path, nothing to remove
return url.startsWith(contextPath) ? url.substring(contextPath.length()) : url;
}
}
faces-config.xml:
faces-config.xml :
<faces-config xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
version="2.0">
<application>
<view-handler>test.CustomViewHandler</view-handler>
</application>
</faces-config>
这篇关于JSF所需的URL重写解决方案的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!