静态服务JSF组件框架Javascript和CSS
我使用的是RichFaces 3.3.1,我试图找出是否有一种方法可以将RichFaces CSS和Javascript作为静态资源从另一个web服务器(如Apache或Nginx)托管 我尝试将web.xml中的静态服务JSF组件框架Javascript和CSS,jsf,richfaces,webserver,Jsf,Richfaces,Webserver,我使用的是RichFaces 3.3.1,我试图找出是否有一种方法可以将RichFaces CSS和Javascript作为静态资源从另一个web服务器(如Apache或Nginx)托管 我尝试将web.xml中的org.ajax4jsf.RESOURCE\u URI\u PREFIX初始化参数设置为另一个web服务器,但URI仍然是相对于web应用程序的 我还尝试从RichFaces jar中提取两个Javascript文件 framework.pack.js ui.pack.js 将以下
org.ajax4jsf.RESOURCE\u URI\u PREFIX
初始化参数设置为另一个web服务器,但URI仍然是相对于web应用程序的
我还尝试从RichFaces jar中提取两个Javascript文件
- framework.pack.js
- ui.pack.js
<context-param>
<param-name>org.richfaces.LoadScriptStrategy</param-name>
<param-value>NONE</param-value>
</context-param>
org.richfaces.LoadScriptStrategy
没有一个
然后在xhtml中包含来自另一台服务器的Javascript文件。不幸的是,在我这么做之后,许多RichFaces组件都无法工作
还有其他的想法吗?
有人用JSF组件框架成功地做到了这一点吗?我意识到这不是版本3.3中的答案,但如果您可以升级到Richfaces 4 final,那么他们有一个漂亮的小功能,您可以将其添加到web.xml:
<context-param>
<param-name>org.richfaces.staticResourceLocation</param-name>
<param-value>#{resourceLocation}</param-value>
</context-param>
编辑: 我有时做的另一件事(在JSF2中)就是抑制库提供者包含的资源的版本。然后我只是创建一个静态版本,并将其包含在我的facelets模板中,或者在项目中有意义的任何地方。它不那么优雅,但如果您将资源组合在一起以获得性能或类似性能,它会工作得很好 为此,我首先通过将以下内容添加到faces-config.xml中,为脚本和样式表定义一些客户呈现器: faces config.xml
<render-kit>
<renderer>
<component-family>javax.faces.Output</component-family>
<renderer-type>javax.faces.resource.Script</renderer-type>
<renderer-class>com.davemaple.jsf.resource.ScriptRenderer</renderer-class>
</renderer>
<renderer>
<component-family>javax.faces.Output</component-family>
<renderer-type>javax.faces.resource.Stylesheet</renderer-type>
<renderer-class>com.davemaple.jsf.resource.StylesheetRenderer</renderer-class>
</renderer>
</render-kit>
<context-param>
<param-name>com.davemaple.jsf.resource.suppressedScriptResourceClasses</param-name>
<param-value></param-value>
</context-param>
<context-param>
<param-name>com.davemaple.jsf.resource.suppressedScripts</param-name>
<param-value>javax.faces:jsf.js :jquery.js :richfaces.js :richfaces-event.js :richfaces-base-component.js org.richfaces:message.js org.richfaces:richfaces-csv.js</param-value>
</context-param>
<context-param>
<param-name>com.davemaple.jsf.resource.suppressedStylesheetResourceClasses</param-name>
<param-value></param-value>
</context-param>
<context-param>
<param-name>com.davemaple.jsf.resource.suppressedStylesheets</param-name>
<param-value>org.richfaces:msg.ecss</param-value>
</context-param>
javax.faces.Output
javax.faces.resource.Script
com.davemple.jsf.resource.ScriptRenderer
javax.faces.Output
javax.faces.resource.Stylesheet
com.davemple.jsf.resource.StylesheetRenderer
然后,我向web.xml添加了一些要抑制的文件或类:
<context-param>
<param-name>org.richfaces.staticResourceLocation</param-name>
<param-value>#{resourceLocation}</param-value>
</context-param>
web.xml
<render-kit>
<renderer>
<component-family>javax.faces.Output</component-family>
<renderer-type>javax.faces.resource.Script</renderer-type>
<renderer-class>com.davemaple.jsf.resource.ScriptRenderer</renderer-class>
</renderer>
<renderer>
<component-family>javax.faces.Output</component-family>
<renderer-type>javax.faces.resource.Stylesheet</renderer-type>
<renderer-class>com.davemaple.jsf.resource.StylesheetRenderer</renderer-class>
</renderer>
</render-kit>
<context-param>
<param-name>com.davemaple.jsf.resource.suppressedScriptResourceClasses</param-name>
<param-value></param-value>
</context-param>
<context-param>
<param-name>com.davemaple.jsf.resource.suppressedScripts</param-name>
<param-value>javax.faces:jsf.js :jquery.js :richfaces.js :richfaces-event.js :richfaces-base-component.js org.richfaces:message.js org.richfaces:richfaces-csv.js</param-value>
</context-param>
<context-param>
<param-name>com.davemaple.jsf.resource.suppressedStylesheetResourceClasses</param-name>
<param-value></param-value>
</context-param>
<context-param>
<param-name>com.davemaple.jsf.resource.suppressedStylesheets</param-name>
<param-value>org.richfaces:msg.ecss</param-value>
</context-param>
com.davemple.jsf.resource.suppressedScriptResourceClasses
com.davemple.jsf.resource.suppressedScripts
javax.faces:jsf.js:jquery.js:richfaces.js:richfaces-event.js:richfaces-base-component.js org.richfaces:message.js org.richfaces:richfaces-csv.js
com.davemple.jsf.resource.suppressedStylesheetResourceClasses
com.davemple.jsf.resource.suppressedStylesheets
org.richfaces:msg.ecss
ScriptRenderer.java
/**
* A Customer ScriptRenderer that allows specific resources to be
* suppressed and managed manually (CDN, Static Resource Server, Combining resources)
*
*/
public class ScriptRenderer extends ScriptStyleBaseRenderer {
private static final String DELIMITER = " ";
private static final String LIBRARY_DELIMITER = ":";
private static final String SUPRESSED_CLASSES_INIT_PARAM = "com.davemaple.jsf.resource.suppressedScriptResourceClasses";
private final List<Class<?>> supressedClasses = new ArrayList<Class<?>>();
private static final String SUPRESSED_SCRIPTS_INIT_PARAM = "com.davemaple.jsf.resource.suppressedScripts";
private final List<String> suppressedScriptNames = new ArrayList<String>();
/**
* Constructor
*/
public ScriptRenderer() {
super();
String suppressedClasses =
FacesContext.getCurrentInstance().getExternalContext().getInitParameter(SUPRESSED_CLASSES_INIT_PARAM);
if (suppressedClasses != null
&& !suppressedClasses.isEmpty()) {
for (String suppressedClassString : suppressedClasses.split(DELIMITER)) {
try {
this.supressedClasses.add(Class.forName(suppressedClassString));
} catch (ClassNotFoundException ex) {
}
}
}
String suppressedScripts =
FacesContext.getCurrentInstance().getExternalContext().getInitParameter(SUPRESSED_SCRIPTS_INIT_PARAM);
if (suppressedScripts != null
&& !suppressedScripts.isEmpty()) {
for (String suppressedScript : suppressedScripts.split(DELIMITER)) {
this.suppressedScriptNames.add(suppressedScript);
}
}
}
/**
* Returns a boolean indicating if the component should
* be encoded and thus rendered
*
* @param component
* @return isSuppressed
*/
protected boolean isSuppressed(UIComponent component) {
if (this.supressedClasses.contains(component.getClass())) {
return true;
}
if (component.getAttributes().containsKey("name")
&& component.getAttributes().containsKey("library")) {
String key = component.getAttributes().get("library") + LIBRARY_DELIMITER + component.getAttributes().get("name");
if (this.suppressedScriptNames.contains(key)) {
return true;
}
}
if (component.getAttributes().containsKey("name")
&& !component.getAttributes().containsKey("library")) {
String key = LIBRARY_DELIMITER + component.getAttributes().get("name");
if (this.suppressedScriptNames.contains(key)) {
return true;
}
}
return false;
}
@Override
protected void startElement(ResponseWriter writer, UIComponent component) throws IOException {
writer.startElement("script", component);
writer.writeAttribute("type", "text/javascript", "type");
}
@Override
protected void endElement(ResponseWriter writer) throws IOException {
writer.endElement("script");
}
@Override
public void encodeBegin(FacesContext context, UIComponent component) throws IOException {
if (!this.isSuppressed(component)) {
super.encodeBegin(context, component);
}
}
@Override
public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
if (!this.isSuppressed(component)) {
Map<String, Object> attributes = component.getAttributes();
Map<Object, Object> contextMap = context.getAttributes();
String name = (String) attributes.get("name");
String library = (String) attributes.get("library");
String key = name + library;
if (null == name) {
return;
}
// Ensure this script is not rendered more than once per request
if (contextMap.containsKey(key)) {
return;
}
contextMap.put(key, Boolean.TRUE);
// Special case of scripts that have query strings
// These scripts actually use their query strings internally, not
// externally
// so we don't need the resource to know about them
int queryPos = name.indexOf("?");
String query = null;
if (queryPos > -1 && name.length() > queryPos) {
query = name.substring(queryPos + 1);
name = name.substring(0, queryPos);
}
Resource resource = context.getApplication().getResourceHandler()
.createResource(name, library);
ResponseWriter writer = context.getResponseWriter();
this.startElement(writer, component);
String resourceSrc;
if (resource == null) {
resourceSrc = "RES_NOT_FOUND";
} else {
resourceSrc = resource.getRequestPath();
if (query != null) {
resourceSrc = resourceSrc
+ ((resourceSrc.indexOf("?") > -1) ? "+" : "?") + query;
}
}
writer.writeURIAttribute("src", resourceSrc, "src");
this.endElement(writer);
super.encodeEnd(context, component);
}
}
}
/**
* A Customer StylesheetRenderer that allows specific resources to be
* suppressed and managed manually (CDN, Static Resource Server, Combining resources)
*
*/
public class StylesheetRenderer extends ScriptStyleBaseRenderer {
private static final String DELIMITER = " ";
private static final String LIBRARY_DELIMITER = ":";
private static final String SUPRESSED_CLASSES_INIT_PARAM = "com.davemaple.jsf.resource.suppressedStylesheetResourceClasses";
private final List<Class<?>> supressedClasses = new ArrayList<Class<?>>();
private static final String SUPPRESSED_STYLESHEETS_INIT_PARAM = "com.davemaple.jsf.resource.suppressedStylesheets";
private final List<String> suppressedStylesheets = new ArrayList<String>();
/**
* Constructor
*/
public StylesheetRenderer() {
super();
String suppressedClasses =
FacesContext.getCurrentInstance().getExternalContext().getInitParameter(SUPRESSED_CLASSES_INIT_PARAM);
if (suppressedClasses != null
&& !suppressedClasses.isEmpty()) {
for (String suppressedClassString : suppressedClasses.split(DELIMITER)) {
try {
this.supressedClasses.add(Class.forName(suppressedClassString));
} catch (ClassNotFoundException ex) {
}
}
}
String suppressedStylesheets =
FacesContext.getCurrentInstance().getExternalContext().getInitParameter(SUPPRESSED_STYLESHEETS_INIT_PARAM);
if (suppressedStylesheets != null
&& !suppressedStylesheets.isEmpty()) {
for (String suppressedStylesheet : suppressedStylesheets.split(DELIMITER)) {
this.suppressedStylesheets.add(suppressedStylesheet);
}
}
}
/**
* Returns a boolean indicating if the component should
* be encoded and thus rendered
*
* @param component
* @return isSuppressed
*/
protected boolean isSuppressed(UIComponent component) {
if (this.supressedClasses.contains(component.getClass())) {
return true;
}
if (component.getAttributes().containsKey("name")
&& component.getAttributes().containsKey("library")) {
String key = component.getAttributes().get("library") + LIBRARY_DELIMITER + component.getAttributes().get("name");
if (this.suppressedStylesheets.contains(key)) {
return true;
}
}
if (component.getAttributes().containsKey("name")
&& !component.getAttributes().containsKey("library")) {
String key = LIBRARY_DELIMITER + component.getAttributes().get("name");
if (this.suppressedStylesheets.contains(key)) {
return true;
}
}
return false;
}
@Override
protected void startElement(ResponseWriter writer, UIComponent component)
throws IOException {
writer.startElement("style", component);
writer.writeAttribute("type", "text/css", "type");
}
@Override
protected void endElement(ResponseWriter writer) throws IOException {
writer.endElement("style");
}
@Override
protected String verifyTarget(String toVerify) {
return "head";
}
@Override
public void encodeBegin(FacesContext context, UIComponent component) throws IOException {
if (!this.isSuppressed(component)) {
super.encodeBegin(context, component);
}
}
@Override
public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
if (!this.isSuppressed(component)) {
Map<String, Object> attributes = component.getAttributes();
Map<Object, Object> contextMap = context.getAttributes();
String name = (String) attributes.get("name");
String library = (String) attributes.get("library");
String key = name + library;
if (null == name) {
return;
}
// Ensure this stylesheet is not rendered more than once per request
if (contextMap.containsKey(key)) {
return;
}
contextMap.put(key, Boolean.TRUE);
Resource resource = context.getApplication().getResourceHandler()
.createResource(name, library);
ResponseWriter writer = context.getResponseWriter();
writer.startElement("link", component);
writer.writeAttribute("type", "text/css", "type");
writer.writeAttribute("rel", "stylesheet", "rel");
writer.writeURIAttribute("href",
((resource != null) ? resource.getRequestPath()
: "RES_NOT_FOUND"), "href");
writer.endElement("link");
super.encodeEnd(context, component);
}
}
}
/**
*一种客户脚本呈现程序,允许特定资源
*手动抑制和管理(CDN、静态资源服务器、合并资源)
*
*/
公共类ScriptRenderer扩展了ScriptStyleBaseRenderer{
私有静态最终字符串分隔符=”;
私有静态最终字符串库_DELIMITER=“:”;
私有静态最终字符串suppressed_CLASSES_INIT_PARAM=“com.davemple.jsf.resource.suppressedScriptResourceClasses”;
私人最终名单>();
私有静态最终字符串suppressed_SCRIPTS_INIT_PARAM=“com.davemple.jsf.resource.suppressedScripts”;
private final List suppressedScriptNames=new ArrayList();
/**
*建造师
*/
公共脚本渲染器(){
超级();
字符串抑制类=
FacesContext.getCurrentInstance().getExternalContext().getInitParameter(suppressed_CLASSES_INIT_PARAM);
if(suppressedClasses!=null
&&!suppressedClasses.isEmpty()){
for(字符串suppressedClassString:suppressedClasses.split(分隔符)){
试一试{
add(Class.forName(suppressedClassString));
}捕获(ClassNotFoundException ex){
}
}
}
字符串抑制脚本=
FacesContext.getCurrentInstance().getExternalContext().getInitParameter(suppressed_SCRIPTS_INIT_PARAM);
if(suppressedScripts!=null
&&!suppressedScripts.isEmpty()){
for(字符串suppressedScript:suppressedScripts.split(分隔符)){
this.suppressedScriptNames.add(suppressedScript);
}
}
}
/**
*返回一个布尔值,指示组件是否应
*被编码并如此呈现
*
*@param组件
*@return-isSuppressed
*/
受保护的布尔值isSuppressed(UIComponent组件){
if(this.supersedClasses.contains(component.getClass())){
返回true;
}
if(component.getAttributes().containsKey(“名称”)
&&component.getAttributes().containsKey(“库”)){
字符串键=component.getAttributes().get(“库”)+库分隔符+component.getAttributes().get(“名称”);
if(this.suppressedScriptNames.contains(key)){
返回true;
}
}
if(component.getAttributes().containsKey(“名称”)
&&!component.getAttributes().containsKey(“库”)){
String key=LIBRARY_DELIMITER+component.getAttributes().get(“name”);
if(this.suppressedScriptNames.contains(key)){
返回true;
}
}
返回false;
}
@凌驾
受保护的void startElement(ResponseWriter编写器、UIComponent组件)引发IOException{
startElement(“脚本”,组件);
writeAttribute(“type”、“text/javascript”、“type”);
}
@凌驾
受保护的void endElement(ResponseWriter写入程序)引发IOException{
作者:恩德莱恩(“剧本”);
}
@凌驾
public void encodeBegin(FacesContext上下文,UIComponent)引发IOException{
如果(!this.isSuppressed(组件)){
super.encodeBegin(上下文、组件);
}
}
@凌驾
public void encodeEnd(FacesContext上下文,UIComponent)引发IOException{
如果(!t