我在浏览JSF 2中的自定义资源处理程序时遇到了omnifaces的UnmappedResourceHandler。这是在这篇文章之后添加到Omnifaces的。
我注意到,与Omnifaces提供的其他两个ResourceHandlers(即CDNResourceHandler
和CombinedResourceHandler
)不同,这个ResourceHandlers需要对JSF资源URL前缀模式进行额外的映射:
<servlet-mapping>
<servlet-name>facesServlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
<url-pattern>/javax.faces.resource/*</url-pattern>
</servlet-mapping>
我不是JSF方面的专家,但是我很好奇为什么只需要这种类型,而不需要其他两种类型?
JSF资源也需要由FacesServlet
提供服务。它负责在/resources
文件夹中找到正确的文件,并将其与适当的缓存头一起返回。如果从资源URL中删除.xhtml
扩展名(或/faces
路径),则URL将不再与FacesServlet
的URL模式匹配,因此FacesServlet
将不会被调用,并且无法完成为资源提供服务的工作。你只会得到一个404 Not Found错误返回,因为"raw"资源url不匹配公共webcontent文件夹结构。
UnmappedResourceHandler
利用了JSF资源url具有公共前缀路径/javax.faces.resource
的事实,如ResourceHandler.RESOURCE_IDENTIFIER
所标识的那样。因此,为了调用FacesServlet
,即使没有.xhtml
扩展(或/faces
路径),您只需要将/javax.faces.resource/*
URL模式添加到映射中。
CDNResourceHandler
不需要更改映射,因为它不生成JSF资源url,而是真正的CDN url,如指向jQuery或Google CDN主机的url。无论如何,这些url不会(需要)击中FacesServlet
。
CombinedResourceHandler
只生成默认的JSF资源url,带有.xhtml
扩展名(或/faces
路径)。它只使用omnifaces.combined
的特殊library
名称,以便CombinedResourceHandler
可以识别它们