CMS 组件渲染器与控制器之间的区别
Difference between CMS component Renderer vs Controller
我们使用的是 Hybris v5.7,我已经向项目添加了一个插件。我想渲染一些 CMS 组件,我发现有两种方法可以填充渲染组件的模型对象:创建 DefaultAddOnCMSComponentRenderer 或 AbstractCMSAddOnComponentController 的子 class 并将其注册为 bean。哪种方法更好?也许这些方法中的一种已经过时了?
@Controller
@RequestMapping("/view/MarketingNotificationFormComponentController")
public class MarketingNotificationFormComponentController extends AbstractCMSAddOnComponentController<MarketingNotificationFormComponentModel> {
@Override
protected void fillModel(HttpServletRequest request, Model model, MarketingNotificationFormComponentModel component) {
//populate model here
}
}
或
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;
}
}
Which approach is better? Maybe one of these approaches is outdated?
实际上,ComponentController 和 ComponentRenderer 都有不同的用途。
ComponentController 是您可以处理传入请求、操作数据或某些业务逻辑的地方,然后再将其提供给视图以呈现最终输出。这里需要在 JSP 文件中写入视图。参考CMSPageUrlResolvingController
、SimpleResponsiveBannerComponentController
、DynamicBannerComponentController
等
ComponentRenderer 用于视图。这意味着您将直接在渲染器内的页面上下文中编写视图内容。在这里,您不需要 JSP 来呈现视图。参考CMSParagraphComponentRenderer
、CMSLinkComponentRenderer
、ImageMapComponentRenderer
等
如果您只想将组件属性填充到模型,则不需要定义自定义控制器或渲染器,OOTB GenericCMSAddOnComponentController 会处理它。
请注意,如果已经定义了相应的自定义 componentRenderer,则不会调用 componentContoller,因为自定义 componentRenderer 和自定义 componentContoller 不能一起工作。
如何在内部调用自定义组件控制器或渲染器?
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);
}
}
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);
// ...
// ...
}
我们使用的是 Hybris v5.7,我已经向项目添加了一个插件。我想渲染一些 CMS 组件,我发现有两种方法可以填充渲染组件的模型对象:创建 DefaultAddOnCMSComponentRenderer 或 AbstractCMSAddOnComponentController 的子 class 并将其注册为 bean。哪种方法更好?也许这些方法中的一种已经过时了?
@Controller
@RequestMapping("/view/MarketingNotificationFormComponentController")
public class MarketingNotificationFormComponentController extends AbstractCMSAddOnComponentController<MarketingNotificationFormComponentModel> {
@Override
protected void fillModel(HttpServletRequest request, Model model, MarketingNotificationFormComponentModel component) {
//populate model here
}
}
或
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;
}
}
Which approach is better? Maybe one of these approaches is outdated?
实际上,ComponentController 和 ComponentRenderer 都有不同的用途。
ComponentController 是您可以处理传入请求、操作数据或某些业务逻辑的地方,然后再将其提供给视图以呈现最终输出。这里需要在 JSP 文件中写入视图。参考CMSPageUrlResolvingController
、SimpleResponsiveBannerComponentController
、DynamicBannerComponentController
等
ComponentRenderer 用于视图。这意味着您将直接在渲染器内的页面上下文中编写视图内容。在这里,您不需要 JSP 来呈现视图。参考CMSParagraphComponentRenderer
、CMSLinkComponentRenderer
、ImageMapComponentRenderer
等
如果您只想将组件属性填充到模型,则不需要定义自定义控制器或渲染器,OOTB GenericCMSAddOnComponentController 会处理它。
请注意,如果已经定义了相应的自定义 componentRenderer,则不会调用 componentContoller,因为自定义 componentRenderer 和自定义 componentContoller 不能一起工作。
如何在内部调用自定义组件控制器或渲染器?
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);
}
}
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);
// ...
// ...
}