资源是Sling的核心部分之一。从JCR的《一切都是内容》扩展到现在,Sling认为一切都是资源。因此,Sling维护着一个虚拟的资源树,它是JCR存储库中实际内容与所谓资源提供者提供的资源的合并。通过这样做,Sling非常适合REST体系结构的范式。
资源是资源树的一部分。这样,每个资源都有一条路径,该路径是通过将所有资源的名称沿根目录连接到以斜杠分隔的资源而形成的。好的,实际上,这很像URL路径或文件系统路径,其中斜杠(/)是分隔符。
资源的名称是路径中的最后一个元素(或段)。
每个资源都有一个资源类型,Servlet和脚本解析器使用它来查找适当的Servlet或脚本来处理对资源的请求。
资源的(可选的显式)超级类型。有关更多详细信息,请参见下面的资源类型部分。
资源是始终存在的Adaptable,因此可以适应不同的视图。有关更多详细信息,请参见下面的资源适配器部分。
通常,资源支持ResourceMetadata提供对值的访问,例如二进制资源的长度(可以流式传输)或资源的内容类型。
设置资源的资源类型的确切方法取决于实际的资源提供者。对于Sling提供的四个主要资源提供程序实现,分配如下:
提供者(JCR、File System、Bundle、Servlet)
资源类型 : sling:resourceType属性值或主节点类型(如果未设置属性)(名称空间分隔符冒号用斜杠替换,例如nt:file主节点类型映射到nt/file资源类型)
资源超类型: sling:resourceSuperType时访问的资源节点或资源超类型的资源的指向的资源类型(ResourceResolver.getResource(String)
资源类型 : 基于文件的资源是类型nt/file; 基于文件夹的资源的类型nt/folder与相应的JCR主节点类型相对应
资源超类型: 没有
资源类型 : 基于文件的资源是类型nt/file; 基于文件夹的资源的类型nt/folder与相应的JCR主节点类型相对应
资源超类型: 没有
资源类型 : 带后缀的资源的绝对路径 .servlet
资源超类型: sling/bundle/resource
资源可以适应的对象类型主要取决于提供资源的资源提供者。例如,所有基于JCR节点的资源始终适应javax.jcr.Node对象。
如果实际的Resource对象类实现是从该类扩展的SlingAdaptable,则在尝试适应Resource时,还将考虑所有AdapterFactory服务适应Resource对象。通常,建议资源提供者扩展其资源实现,AbstractResource以保证资源实现从SlingAdaptable适配器工厂扩展,从而支持适配器工厂。
要获得资源,您需要一个ResourceResolver。该接口定义了四种访问资源的方法:
绝对路径映射资源解析:调用resolve(HttpServletRequest, String)和resolve(String)方法以应用一些特定于实现的路径匹配算法来查找资源。这些方法主要用于将外部路径(例如请求URL的路径组成部分)映射到资源。为了支持创建可在URL中使用的外部路径,map(String)定义了第三个方法,该方法允许往返。
绝对或相对路径解析(包括搜索路径):getResource(String path)和getResource(Resource base, String path)方法可用于直接使用绝对路径访问资源。如果找不到,则假定该路径是相对路径,getSearchPath()并且从中检索的搜索路径用于检索资源。这种机制类似于使用PATH您喜欢的操作系统中的环境变量解析程序。
资源枚举:为了枚举资源并因此迭代资源树,listChildren(Resource)可以使用该方法。此方法返回Iterator列出所有资源的列表,这些资源的路径前缀是给定Resource的路径。当然,此方法还将跨越已注册ResourceProvider实例的边界,以实现对整个资源树的迭代。
资源查询:目前仅通过findResources(String query, String language)和queryResources(String query, String language)方法支持JCR资源查询资源。
通常,您可以ResourceResolver通过OSGi服务获得ResourceResolverFactory。该接口提供了创建ResourceResolver的不同方法:
ResourceResolverFactory.getResourceResolver(java.util.Map authenticationInfo)。您必须提供一些身份验证信息详细信息才能起作用。这些都高度依赖于实施ResourceProvider。有关更多详细信息,请参见以下各节。
ResourceResolverFactory.getServiceResourceResolver(java.util.Map authenticationInfo)。可以选择通过身份验证信息密钥进一步进行参数化sling.service.subservice。有关更多详细信息,请参阅ServiceAuthentication。
ResourceResolverFactory.getThreadResourceResolver()。使用绑定到当前线程的资源解析器。
已弃用ResourceResolverFactory.getAdministrativeResourceResolver(…)。而是使用方法2。
至关重要的ResourceResolver是,ResourceResolver.close()一旦不再使用通过这些方法之一检索的每个数据,就必须关闭它们。
正如人们所说的,绝对路径映射方法 resolve(HttpServletRequest, String) 和 ==resolve(String)==应用一些实施的具体路径匹配算法找到资源。两种方法之间的区别在于,前一种HttpServletRequest在解析资源时可能考虑到更多属性,而后一种则有绝对的工作路径。
这两种方法的一般算法如下:
调用HttpServletRequest.getScheme(), .getServerName(), getServerPort以获取请求URL中的绝对路径:[scheme] / [host]。[port] [path](resolve(HttpServletRequest, String)仅该方法)
检查是否有任何虚拟路径与绝对路径匹配。如果存在这样的匹配项,则使用该匹配项进入下一步。
应用映射列表以创建映射路径。假定解析为资源的第一个映射路径成功,并且返回找到的资源。
如果没有映射创建寻址现有资源的映射路径,则该方法将失败并返回NonExistingResource(对于
resolve(String)和resolve(HttpServletRequest,String))或null(对于getResource(String path)和getResource(Resource base, String path)方法)。
虚拟路径映射可用于为否则较长且复杂的URL创建快捷方式URL。此类URL的示例可能是CMS系统的主管理页面。因此,管理员可以访问Web应用程序的根目录并定向到主管理页面。
路径映射功能可用于从请求URL空间隐藏内部资源组织。例如,为了更好地控制存储库的结构,您可能决定将所有可访问的数据存储在/content子树中。为了向用户隐藏这一事实,可以定义一个映射以将所有传入路径作为前缀,/content以获取实际资源。
在map(String)应用于以相反的顺序的路径映射算法。即,首先将路径映射颠倒,然后检查所有虚拟映射。因此,/content/sample可能会映射路径/sample以反转/content前缀。或者主管理页面(例如/system/admin/main.html)可以映射到虚拟URL /。
有时需要解析到资源的相对路径。这种用例的一个示例是Script和Servlet解析,该解析以包含Resource类型,可选选择器和请求扩展或方法名称的相对路径开头。通过扫描这些相对路径的搜索路径,系统提供的资源可能会被某些用户定义的实现所覆盖。
例如,考虑系统将提供一个Servlet来呈现type的资源nt:file。该Servlet将在path下注册/libs/nt/file/html。对于某些Web应用程序,此默认HTML呈现可能不合适,因此将创建脚本/apps/nt/file/html.jsp和自定义HTML呈现。通过将搜索路径定义为[/apps,/libs]Servlet解析器,将ResourceResolver.getResource(String)使用相对路径调用该方法,nt/file/html并为其提供第一个匹配资源- /apps/nt/file/html.jsp在此示例中。
为了方便起见,ResourceResolver提供了两种资源查询方法,findResources并且queryResources这两种方法都将JCR查询字符串和查询语言名称作为参数。这些参数与QueryManager.createQuery(String statement, String language)JCR API方法的参数定义匹配。
这两种方法的返回值在用例中有所不同:
findResources返回Iteratory与查询匹配的所有资源中的一个。这种方法相当于调用getNodes()在QueryResult从执行JCR查询返回。
queryResources返回Iterator
请注意,当前仅基于存储库的资源支持资源查询。这些查询方法未反映在ResourceProvider用于将非资源库资源注入到资源树中的接口中。
资源访问器方法resolve并getResource提供访问权的虚拟资源树是由一组注册ResourceProvider实例实现的。主要的资源提供者当然是基于存储库的JcrResourceProvider,它支持基于节点和属性的资源。此资源提供程序始终在Sling中可用。其他资源提供者可能存在或可能不存在。
每个资源提供者都使用必需的服务注册属性注册为OSGi服务provider.roots。这是一个多值String属性,列出了绝对路径,资源树条目充当提供的子树的根。例如,如果使用服务注册属性provider.roots设置为/ some / root来注册/some/root资源提供程序,则首先在给定的资源提供程序中查找所有以开头的路径。
在已注册的资源提供者中查找资源时,会ResourceResolver应用最长前缀匹配算法以找到最佳匹配。例如,考虑以下三个注册的资源提供程序:
JCR资源提供者为 /
资源提供者R1为 /some
资源提供者R2为 /some/path
当使用路径访问资源时,首先会询问/some/path/resource资源提供者R2。如果不能提供资源,则询问资源提供者R1,最后询问JCR资源提供者。将使用具有带有所请求路径的资源的第一资源提供者。
基于JCR的资源带有default JcrResourceProvider。该资源提供者始终可用,并且总是被最后询问。也就是说,其他资源提供者提供的资源可能永远不会被基于存储库的资源所取代。
这些是的支持的authenticationInfo key(可与一起使用ResourceResolverFactory.getResourceResolver(java.util.Map authenticationInfo))JcrResourceProvider:
官方doc : https://sling.apache.org/documentation/tutorials-how-tos/46-line-blog.html