Search code examples
spring-mvcsap-commerce-cloud

Customizing Hybris accelerator storefront controllers in an addon


I'm using Hybris 6.3 and would like to follow the best practice of customizing the accelerator storefront controllers using an addon. This is done to make upgrading to a newer storefront much easier.

For example, the accelerator defines a Minicart controller similar to

package com.custom.storefront.controllers.misc;

@Controller
public class MiniCartController extends AbstractController
{
    @RequestMapping(value = "/cart/miniCart/{totalDisplay:.*}", method = RequestMethod.GET)
    public String getMiniCart(@PathVariable final String totalDisplay, final Model model)
    {
        //default functionality
    }
}

In my addon, I would like to map that same URL pattern to a new controller that will override the functionality.

package com.custom.storefrontaddon.controllers.misc;

@Controller
public class MyCustomMiniCartController extends AbstractController
{
    @RequestMapping(value = "/cart/miniCart/{totalDisplay:.*}", method = RequestMethod.GET)
    public String getMiniCart(@PathVariable final String totalDisplay, final Model model)
    {
        //overriding functionality, different from the default accelerator storefront
    }
}

This question has been asked here, and the accepted advice was to do as follows:

  • In addon-web-spring.xml, override the controller bean like
    <bean name="miniCartController" class="com.custom.storefrontaddon.controllers.misc.MyCustomMiniCartController"/>
  • In addon-web-spring.xml, add a SimpleUrlHandlerMapping like
    <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="mappings">
            <props>
                <prop key="/cart/miniCart/**">miniCartController</prop>
            </props>
        </property>
    </bean>
  • The addon controller will now be called instead of the default accelerator controller for the target URL.

My Question

How does this mechanism work when the Spring documentation explicitly says that

There are also several things no longer possible:
- Select a controller first with a SimpleUrlHandlerMapping or BeanNameUrlHandlerMapping and then narrow the method based on @RequestMapping annotations.

Spring is using RequestMappingHandlerMapping by default in the accelerator storefront, and in the addon we are introducing SimpleUrlHandlerMapping. I want to understand why this works, when every other forum post I've read says that you cannot override @RequestMapping URLs in a different controller, or you will get an exception thrown for the duplicate URL.


Solution

  • In my answer, I will suppopse that you made a typo, and you meant MyCustomMiniCartController instead of MiniCartController in:

    <bean name="miniCartController" class="com.custom.storefrontaddon.controllers.misc.MyCustomMiniCartController"/>
    

    The thing here is that SimpleUrlHandlerMapping has nothing to do and its declaration in addon-web-spring.xml is completely useless.

    Redefining the miniCartController bean in the addon makes the bean definition overridden by the addon class, and so the request mapping that is declared in the addon class is the one "used" by the RequestMappingHandlerMapping.