【发布时间】:2013-02-04 12:06:03
【问题描述】:
我有一个 JSF2 应用程序正在运行并且工作没有问题。我在 JSF 中遇到的问题是资源包。所有资源都附加了.xhtml 后缀。所以main.css 在浏览器中加载时变为main.css.xhtml。我想拥有它,这样.xhtml 就不会附加到资源中(不要介意页面本身)。
有没有办法让我们不将.xhtml 附加到资源中?
理想情况下,我不必更改网站的内部运作方式。我在下面列出了一些想法,但我不得不说我不是很喜欢这些。希望在某个地方找到解决方案?
我在 Glassfish 3.1.2.2 上使用 Majorra v.2.1.17。
在 web.xml 中加载当前 Faces Servlet(更新)
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/javax.faces.resource/*</url-pattern>
</servlet-mapping>
为什么这个问题与其他问题不同
- JSF 2 resources with CDN?。我不希望将我的资源放在 CDN 上,而是让我的资源保留在我的服务器上,但被推送到 CDN。
-
Change /javax.faces.resource prefix of resource URLs。我不想更改前缀。我只想更改后缀。我希望
<link type="text/css" rel="stylesheet" href="/javax.faces.resource/main03.css.xhtml?ln=styles">成为:<link type="text/css" rel="stylesheet" href="/javax.faces.resource/main03.css?ln=styles">没有.xhtml扩展。 - Changing JSF prefix to suffix mapping forces me to reapply the mapping on CSS background images。因为我没有加载资源的问题。该网站正常工作,我们只是很难区分网页和资源(因为我们只查看扩展名)。
推理
当然你可能会问我为什么需要这个。好吧,我们正在将我们的应用程序转移到由 Akamai CDN 提供服务。
我们在网站集成方面遇到的问题是我们试图在边缘服务器上缓存静态内容。这是通过匹配文件扩展名(即:.js、.doc、.png、css 等)来完成的。我们无法匹配xhtml,因为这将缓存所有页面以及静态内容。这会导致会话等问题。
尝试的解决方案
根据 BalusC 的回答,我已经按照建议实现了资源处理程序。我不会在这里重写代码,因为它在下面的答案中。
但是,我在加载复合组件时遇到错误。我收到这样的错误:
WARNING: StandardWrapperValve[Faces Servlet]: PWC1406: Servlet.service() for servlet Faces Servlet threw exception
java.lang.NullPointerException
at com.sun.faces.application.ApplicationImpl.createComponent(ApplicationImpl.java:975)
at com.sun.faces.facelets.tag.jsf.CompositeComponentTagHandler.createComponent(CompositeComponentTagHandler.java:162)
at com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.createComponent(ComponentTagHandlerDelegateImpl.java:494)
at com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.apply(ComponentTagHandlerDelegateImpl.java:169)
...
复合组件已正确加载,因为如果我“取消注册”我们刚刚创建的新 ResourceHandler,它将加载。堆栈跟踪使我相信它试图在 java 类中找到这个组件,而不是在资源中找到它。根据grepcode,这将是发生错误的最后一行(975):
String packageName = componentResource.getLibraryName();
String className = componentResource.getResourceName();
className = packageName + '.' + className.substring(0, className.lastIndexOf('.'));
意味着resourceName,又名className 是null,因为我得到的错误是java.lang.NullPointerException。我似乎无法弄清楚 ResourceHandler 相对于复合组件的调用方式/位置。对解决最后一个问题有帮助吗?
【问题讨论】:
-
创建自定义资源处理程序。
-
@BalusC 然后会产生类似的东西(例如在 css 文件中):
background: #14311b url("#{resource['templateImages:background.jpg']}") no-repeat 0 0;不起作用,因为 jsf 不会在“非 xhtml”文件上运行。那么添加“*.css”作为 jsf servlet 的模式是否是个好主意?还是简单地使用静态获取?位于ln=javax.faces的资源呢? -
自定义资源处理程序允许您将
/javax.faces.resource/*添加到 faces servlet 映射。 -
@BalusC。如果我这样做,我想我可以像这样访问我的资源:@987654346@。这不起作用,但
http://localhost:8080/myApp/javax.faces.resource/main03.css.xhtml?ln=styles可以。我知道我错过了什么。 -
更正。所以这是我的误解,只是添加前缀我仍然会以同样的方式使用它。所以
/javax.faces.resource/*被添加到servlet 映射中。但是现在要去:javax.faces.resource/resources/styles/main03.css访问这个表,样式表仍然没有被 jsf 处理