1

我正在开发一个组件,该组件需要一些属性(用户在运行时设置)才能按预期工作。

最初,我只是使用 aproperties.get('foo')从我的组件中获取所需的属性,但我试图从我的组件 jsp 文件中删除所有 script-let 代码的痕迹。

如何在我的 Java 代码中获取此属性“foo”(在我的组件运行时设置)?我记得在某处读到使用 ValueMap 是最好的方法,所以我尝试使用这个:-

public static Map<String, Object> getResourceProperties(String path,
            SlingHttpServletRequest request) {
        ResourceResolver resourceResolver = request.getResourceResolver();
        Map<String, Object> props= new HashMap<String, Object>();
        Resource resource = resourceResolver.getResource(path);
        if (null != resource) {
            props.putAll(resource.adaptTo(ValueMap.class));
        }
        return props;
    } 

这在我的jsp中: -<c:set var="refProperties" value="${xyz:getResourceProperties(properties.path,slingRequest)}" />

但这不会返回我想要的值。

4

5 回答 5

5

实现此目的的最简单方法是包含/libs/foundation/global.jsp并仅使用properties已在范围内的对象${properties.foo}

在组件 jsp 的顶部包含 global.jsp,如下所示:

<%@include file="/libs/foundation/global.jsp"%>

正如文件中的注释所示,它基本上注册了 Sling (sling)、CQ (cq) 和 JSTL (c,fmt,fn) 标记库名称空间以供在 JSP 中使用。

然后,在cq:defineObjectstaglib 的帮助下,它将许多有用的对象带入范围。

<cq:defineObjects />

这是列表:

@param slingRequest SlingHttpServletRequest
@param slingResponse SlingHttpServletResponse
@param resource the current resource
@param currentNode the current node
@param log default logger
@param sling sling script helper

@param componentContext component context of this request
@param editContext edit context of this request
@param properties properties of the addressed resource (aka "localstruct")
@param pageManager page manager
@param currentPage containing page addressed by the request (aka "actpage")
@param resourcePage containing page of the addressed resource (aka "myPage")
@param pageProperties properties of the containing page
@param component current CQ5 component
@param designer designer
@param currentDesign design of the addressed resource  (aka "actdesign")
@param resourceDesign design of the addressed resource (aka "myDesign")
@param currentStyle style of the addressed resource (aka "actstyle")

这意味着通过简单地使用 cq:defineObjects 标签库,您已经可以通过 JSP 表达式语言 (EL) 访问属性 ValueMap。访问 JSP 中的属性不需要额外的转换。

<c:out value="${properties.foo}" />

要访问您自己的 Java taglib 或 bean 中的属性,您只需使用标准 JSTL 标记将适当的对象传递给您的代码。您可以传递整个请求、当前资源或仅传递属性。传递整个请求使您的 Java 代码可以访问当前资源和由 cq:defineObjects 标签库创建的所有对象,包括属性 ValueMap。

在 JSP 中:

<jsp:useBean id="mybean" scope="request" class="com.my.impl.TheBean">
   <jsp:setProperty name="mybean" property="slingRequest" value="${slingRequest}"/>
   <jsp:setProperty name="mybean" property="resource" value="${resource}"/>
   <jsp:setProperty name="mybean" property="properties" value="${properties}"/>
</jsp:useBean>

在豆中:

public void setSlingRequest(final SlingHttpServletRequest slingRequest) {
    this.slingRequest = slingRequest;
    // Use the one created by cq:defineObjects
    this.properties = (ValueMap)this.slingRequest.getAttribute("properties");
    // OR adapt the resource
    this.properties = this.slingRequest.getResource().adaptTo(ValueMap.class);
}

public void setResource(final Resource resource) {
    this.resource = resource;
    this.properties = this.resource.adaptTo(ValueMap.class);
}

public void setProperties(final ValueMap properties) {
    this.properties = properties;
}
于 2013-10-09T14:36:58.203 回答
1

我会使用 useBean 标签来创建一个类的实例,它可以为您提供所需的任何信息:

<jsp:useBean id="mycomponent" scope="request" class="com.company.components.SomeComponent">
   <jsp:setProperty name="mycomponent" property="request" value="<%= slingRequest %>"/>
</jsp:useBean>

然后只需在类中创建一个设置器。

 public void setRequest(final SlingHttpServletRequest request) {
    this.request = request;
    //or more likely an init() method that inits all your props
    //you could even use reflection to look for props that match all the field names
    //to init them automatically
    ValueMap props=request.getResource().adaptTo(ValueMap.class)
    this.interestingProp= props.get("interestingProp");
}

public String getInterestingProp(){
   return this.interestingProp;
}

然后在你的jsp中:

<c:out value="${mycomponent.interestingProp}"/>
于 2013-10-07T11:21:02.340 回答
1

在这种特殊情况下,您正在尝试创建Map<String, Object>包含所有资源属性。该映射与propertiesobject (也是 a Map)相同,所以我猜整个方法是多余的(并且 - 正如您所写的那样 - 它不起作用)。properties对象不包含path方法,可能这就是它不起作用的原因。

更重要的是,您可能已经使用过request.getResource()(而不是通过路径获取解析器和资源)。此外,您可以从 JSP获得简单的传递,而不是适应您resourceValueMapproperties

更一般地说,如果你想从 JSP 中提取逻辑到 Java 类,我认为创建某种model类,传递slingRequest给它的构造函数,然后在 JSP 中调用它的方法是个好主意。例子:

获取.jsp

<c:set var="model" value="<%= new MyModel(slingRequest) %>" />
Result of the first method: ${model.firstValue}<br/>
Result of the second method: ${model.secondValue}

MyModel.java

public class MyModel {
    private final SlingHttpServletRequest request;

    private final Resource resource;

    private final ValueMap properties;

    public MyModel(SlingHttpServletRequest request) {
        this.request = request;
        this.resource = request.getResource();
        this.properties = resource.adaptTo(ValueMap.class);
    }

    public String getFirstMethod() {
        // do some clever things
        return "";
    }

    public String getSecondMethod() {
        // do more clever things
        return "";
    }
}

请注意,如果您调用${model.firstMethod},您需要get在方法名称 ( getFirstMethod()) 中添加前缀。

于 2013-10-07T06:49:24.667 回答
0

在您的 Java 文件中获取 JCR 会话,然后遍历节点,例如content/your_site_name/node/some_parsys. 然后您可以获取作者在运行时设置的值。

if(node.hasProperty("title")){
    String title=node.getProperty().getValue().getString();
}
于 2013-10-07T06:38:44.320 回答
0

好吧,我确实设法回答了我自己的问题。我所做的只是resource.path在我的jsp中使用。

这里的资源是指有问题的组件,因此使用路径我能够正确创建我的ValueMap

所以,我的jsp文件中的代码如下:-

<c:set var="refProperties" value="${xyz:getResourceProperties(resource.path,slingRequest)}"\>

使用它,我现在可以引用我想要的组件的任何属性:-

${refProperties.foo}

为了使用resource.path,我们还必须包含global.jsp,否则将无法识别。

于 2013-10-07T14:19:48.997 回答