4

I want to customize the page controller in a DXA JAVA implementation. Is that possible, and how?

I tried to extend the DXA PageController, but of course that does not work

@Controller
public class MyPageController extends PageController {

    @RequestMapping(
            value = {"/jan"},
            params = {"test"},
            produces = {"text/html", "*/*"}
    )
    @Override
    public String handleGetPage(HttpServletRequest request, HttpServletResponse response) throws Exception {
        // do your stuff
        return super.handleGetPage(request, response);
    }
}

The problem is that in Spring there is no way to override the @RequestMapping, and each mapping has to be unique.

@bearddev had a similar question for DXA .NET. The .NET answer does not apply to DXA JAVA as routing is not configured in a single place in DXA JAVA.

The DXA documentation mentions how to "Create a controller class", but that only applies to region and entity controllers.

2 Answers 2

6

The solution is surprisingly simple.

@Controller
public class MyPageController {

    @Autowired
    private PageController pageController;

    @RequestMapping(value = "/articles")
    public String handleGetPage(HttpServletRequest request, HttpServletResponse response) throws Exception {
        return pageController.handleGetPage(request, response);
    }
}

You only need to inject the controller you want to customize, define specifix mappings (PageController has least specific mapping /** and thus gets least priority) and delegate execution to original class if needed or define your own logic.

2
  • Thanks @Alexey! I would like my page controller to catch all page requests, as in @RequestMapping(value = "/**"). Is this possible at all given that the DXA controller already registered that route?
    – Jan H
    Commented Jan 8, 2018 at 21:40
  • I found a variant on your solution, with a catchall RequestMapping which has a more specific mapping than the catchall mapping from the DXA Page Contorller. It is posted as a separate answer.
    – Jan H
    Commented Jan 9, 2018 at 12:14
4

Thanks to @Alexey's answer which pushed me in the right direction.

This MyPageController controller does the trick. Just like the DXA PageController it is very greedy, that means it wants to match all requests. See code and explanation below.

@Controller
public class MyPageController {

    // Inject the PageController, because we cannot override and change the RequestMapping
    @Autowired
    private PageController pageController;

    // This mapping is more specific than the DXA PageController mapping
    @RequestMapping(
            value = {"/**"},
            produces = {"text/html", "*/*"},
            method = {RequestMethod.GET, RequestMethod.POST}
    )
    public String handleGetPage(HttpServletRequest request, HttpServletResponse response) throws Exception {
        String view = pageController.handleGetPage(request, response);

        PageModel pageModel = (PageModel) request.getAttribute("pageModel");
        pageModel = this.enrichModel(pageModel, request);
        request.setAttribute("pageModel", pageModel);

        return view;
    }

    // enrich the page model, with the DXA enrichModel() pattern 
    protected PageModel enrichModel(PageModel pageModel, HttpServletRequest httpServletRequest) throws Exception {

        //do your thing here
        pageModel.setTitle("Hello, World!");

        return pageModel;
    }
}

Indeed the @RequestMapping cannot be overridden, but like Alexey shows that is not needed.

The RequestMapping (route) needs to be unique which is a challenge, since the DXA PageController registers a greedy catchall route. By adding the request method to the RequestMapping, the MyPageController mapping is more specific than the DXA PageController one.

From the DXA PageController

@RequestMapping(
    value = {"/**"},
    produces = {"text/html", "*/*"}
)
public String handleGetPage(HttpServletRequest request, HttpServletResponse response) throws Exception {

From MyPageController

@RequestMapping(
        value = {"/**"},
        produces = {"text/html", "*/*"},
        method = {RequestMethod.GET, RequestMethod.POST}
)
public String handleGetPage(HttpServletRequest request, HttpServletResponse response) throws Exception {

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.