You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Apache Sling会忽略HTL中data-sly-use的adaptable参数?

问题分析与解决方案

你猜的没错!这个问题确实是因为**SlingModelsUseProvider的服务优先级高于JavaUseProvider**导致的,咱们来一步步拆解原因和解决办法:

核心原因

在Sling 11中,SlingModelsUseProvider(负责处理Sling Model作为HTL Use对象)的默认服务排名是100,而支持adaptable参数的JavaUseProvider默认排名是200——OSGi中服务排名数值越小,优先级越高。

当你在HTL中写data-sly-use.c="${'com.adobe.examples.htl.core.models.HelloWorldModel' @ adaptable=child}"时,优先级更高的SlingModelsUseProvider会先接手处理,但它完全不支持adaptable这个参数,所以直接忽略了你的配置,还是从默认的Adaptable(当前页面的资源)去适配Sling Model,这就导致你拿到的始终是页面的resourceType。

解决方案

方案1:调整JavaUseProvider的优先级(快速适配原有代码)

通过修改OSGi配置,让JavaUseProvider的优先级超过SlingModelsUseProvider,这样它就能处理你的adaptable参数了:

  1. 创建或修改OSGi配置文件org.apache.sling.scripting.sightly.impl.engine.extension.use.JavaUseProvider.cfg.json,内容如下:
{
  "service.ranking": 90
}
  1. 把这个文件放到你的Sling项目的config目录下,或者通过Felix Console(系统配置)找到Apache Sling HTL Java Use Provider,手动将其服务排名改为90(比100小即可)。

这样修改后,JavaUseProvider会优先处理你的Use API请求,adaptable=child就能正常生效,你的原有代码不需要任何改动。

方案2:改用Sling Model参数注入(更符合最佳实践)

既然SlingModelsUseProvider不支持adaptable,咱们可以换一种Sling Model原生支持的方式——通过参数注入传递子资源:

首先修改你的HelloWorldModel,添加一个接受Resource参数的构造方法:

@Model(adaptables = {Resource.class, SlingHttpServletRequest.class})
public class HelloWorldModel {
    private static Logger log = LoggerFactory.getLogger(HelloWorldModel.class);
    @OSGiService
    private SlingSettingsService settings;
    @SlingObject
    private ResourceResolver resourceResolver;
    private String resourceType;
    private String message;

    // 注入传入的子资源
    @Inject
    public HelloWorldModel(@Named("resource") Resource resource) {
        ValueMap valueMap = resource.getValueMap();
        this.resourceType = valueMap.get("sling:resourceType", "No resourceType");
    }

    @PostConstruct
    public void init() {
        log.info("Reached init of HelloWorldModel");
        message = "\tHello World!\n";
        message += "\tResource type is: " + resourceType + "\n";
        message += "\tUser id is " + resourceResolver.getUserID() + "\n";
    }

    public String getResourceType() {
        return resourceType;
    }

    public String getMessage() {
        log.info("Inside getMessage() method");
        return message;
    }
}

然后修改HTL代码,通过@ resource=child传递子资源:

<div data-sly-list.child="${resource.listChildren}">
    <sly data-sly-use.c="${'com.adobe.examples.htl.core.models.HelloWorldModel' @ resource=child}" />
    ${c.resourceType}
</div>

这种方式不需要依赖adaptable参数,完全符合Sling Model的设计规范,也能完美解决你的问题。

方案3:禁用SlingModelsUseProvider(不推荐)

如果你的项目中完全不需要用Sling Model作为HTL Use对象,可以考虑在OSGi中禁用SlingModelsUseProvider。但这种方式会影响其他依赖Sling Model的代码,所以只适合非常单一的场景。

总结

你的初始怀疑完全正确,优先级问题导致adaptable参数被忽略。推荐优先选择方案2(更符合Sling生态的最佳实践),如果想快速复用原有代码,方案1也是个不错的选择。

内容的提问来源于stack exchange,提问作者Spinner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:08:13