CMS 组件渲染器与控制器之间的区别

Rom*_*nin 6 sap-commerce-cloud

我们正在使用 Hybris v5.7,我已经向项目添加了一个插件。我想渲染一些 CMS 组件,我发现有两种方法可以填充渲染组件的模型对象:创建 DefaultAddOnCMSComponentRenderer 或 AbstractCMSAddOnComponentController 的子类并将其注册为 bean。哪种方法更好?也许这些方法之一已经过时了?

@Controller
@RequestMapping("/view/MarketingNotificationFormComponentController")
public class MarketingNotificationFormComponentController extends AbstractCMSAddOnComponentController<MarketingNotificationFormComponentModel> {
    @Override
    protected void fillModel(HttpServletRequest request, Model model, MarketingNotificationFormComponentModel component) {
        //populate model here
    }
}
Run Code Online (Sandbox Code Playgroud)

或者

public class MarketingNotificationFormComponentRenderer extends DefaultAddOnCMSComponentRenderer<MarketingNotificationFormComponentModel> {
    @Override
    protected Map<String, Object> getVariablesToExpose(PageContext pageContext, MarketingNotificationFormComponentModel component) {
        Map<String, Object> variables = new HashMap<String, Object>();
        // populate model here
        return variables;
    }
}
Run Code Online (Sandbox Code Playgroud)

Hyb*_*elp 3

哪种方法更好?也许这些方法之一已经过时了?

实际上,ComponentController 和 ComponentRenderer 都有不同的用途。

ComponentController是您可以处理传入请求、操作数据或某些业务逻辑的地方,然后将其提供给视图以呈现最终输出。这里需要在JSP文件中写入视图。参考CMSPageUrlResolvingControllerSimpleResponsiveBannerComponentControllerDynamicBannerComponentController

ComponentRenderer是针对View的。这意味着您将直接在渲染器内的页面上下文上编写视图内容。在这里,您不需要 JSP 来呈现视图。参考CMSParagraphComponentRenderer,CMSLinkComponentRendererImageMapComponentRenderer

如果您只想将组件属性填充到模型,那么您不需要定义自定义控制器或渲染器,OOTB GenericCMSAddOnComponentController 将处理它。

请注意,如果已经定义了各自的自定义组件渲染器,则不会调用组件控制器,也就是说自定义组件渲染器和自定义组件控制器不能一起工作。


如何在内部调用自定义组件控制器或渲染器?

DefaultCMSComponentRendererRegistry.java

@Override
public void renderComponent(final PageContext pageContext, final C component)
{
    final String typeCode = getTypeService().getComposedTypeForClass(component.getClass()).getCode();
    final Map<String, CMSComponentRenderer> renderersMap = getRenderers();
    try
    {
        // To check for any custom renderer present
        if (renderersMap != null && renderersMap.containsKey(typeCode))
        {
            renderersMap.get(typeCode).renderComponent(pageContext, component);
        }
        else
        {
            // If no custom renderer, call GenericViewCMSComponentRenderer
            getDefaultCmsComponentRenderer().renderComponent(pageContext, component);
        }
    }
    catch (final Exception e)
    {
        handleException(e, component);
    }
}
Run Code Online (Sandbox Code Playgroud)

GenericViewCMSComponentRenderer.java
调用自定义组件控制器或默认控制器

    @Override
    public void renderComponent(final PageContext pageContext, final AbstractCMSComponentModel component)
            throws ServletException, IOException
    {

     // ...
     // ...

            final String typeCode = component.getTypeCode();
            String controllerName = typeCode + "Controller";
            if (!getBeanFactory().containsBean(controllerName))
            {
                if (LOG.isDebugEnabled())
                {
                    LOG.debug("No controller defined for ContentElement [" + typeCode + "]. Using default Controller");
                }
                controllerName = DEFAULT_CONTROLLER;
            }

            final String includePath = "/view/" + controllerName;

            if (LOG.isDebugEnabled())
            {
                LOG.debug("Rendering CMS Component type [" + typeCode + "] uid [" + component.getUid() + "], include path ["
                        + includePath + "]");
            }
            renderView(pageContext, component, includePath);

     // ...
     // ...

}
Run Code Online (Sandbox Code Playgroud)