ruslanys
ruslanys

Reputation: 1211

Change model (@ModelAttribute) depending on a request parameter

help me please. I have the code of controller like this:

@RequestMapping(method = RequestMethod.GET)
public String showOrders(@RequestParam(value = "status", required = false) String status, Model model) {
    if(status != null) {
        Order.Status orderStatus = Order.Status.valueOf(status);
        if (orderStatus != null) model.addAttribute("currentStatus", orderStatus);
    }

    return "admin/orders";
}

@ModelAttribute("currentStatus")
public Order.Status populateCurrentStatus() {
    return Order.Status.PAYMENT;
}

@ModelAttribute("orders")
public List<Order> populateOrders(@ModelAttribute("currentStatus") Order.Status status) {
    return orderBo.getByStatus(status);
}

I want the default currentStatus to be equal to Order.Status.PAYMENT, but if the controller receives a GET request with the argument status (on method showOrders), then replace currentStatus in the model to the status transmitted in the request. And the populateOrders should return a different list of orders, in accordance with the new status. But unfortunately, this is not happening. Method populateOrders always gets currentStatus equal Order.Status.PAYMENT and it never changes.

Upvotes: 1

Views: 2556

Answers (1)

Krešimir Nesek
Krešimir Nesek

Reputation: 5502

You can add @RequestParam to your @ModelAttribute definition in order to populate @ModelAttribute differently, depending on a request parameter.

This should work:

@RequestMapping(method = RequestMethod.GET)
public String showOrders() {
    //no need to manually modify currentStatus in the model anymore
    return "admin/orders";
}

@ModelAttribute("currentStatus")
public Order.Status populateCurrentStatus(@RequestParam(value = "status", defaultValue = "PAYMENT") String status) {    
    return Order.Status.valueOf(status);
}

@ModelAttribute("orders")
public List<Order> populateOrders(@ModelAttribute("currentStatus") Order.Status status) {
    return orderBo.getByStatus(status);
}

Personal note:

I personally dislike Spring's @ModelAttribute system for defining default model attributes, especially in case of more complex models or in more complex controllers. It becomes hard to maintain because it's hard to control what exactly goes into the model (for example, for some requests, maybe you don't want the whole model populated, e.g. you only need currentStatus but not the list of orders. I prefer populating the model manually (Model.addAttribute(...)) - it's not much extra work and everything is explicit and easy to debug if a problem pops out later on.

Upvotes: 2

Related Questions