2013-07-26 33 views
5

Tôi có một bộ điều khiển như thế này:Spring MVC có thể gọi @ModelAttribute sau khi @RequestMapping không?

@Controller 
public class HomeController { 

    @RequestMapping(value = "/update", method = RequestMethod.POST) 
    public String update(@RequestParam("user") User user, ModelMap model){ 
     SaveUserToDatabase(user); 
     return "index"; 
    } 

    @ModelAttribute("user") 
    String getUser() { 
     return LoadCurrentUserFromDataBase(); 
    } 
} 

Nói tóm lại, quan điểm của tôi sẽ làm cho user ở hầu hết mỗi hành động trong HomeController, nhưng tôi không muốn mã:

model.addAttribute("user", LoadCurrentUserFromDataBase()) 

trong mọi hành động, thay vào đó, tôi đang tìm cách như @ModelAttribute để hiển thị user cho tất cả các chế độ xem của tôi.

Tuy nhiên, theo tài liệu, các phương pháp @ModelAttribute trong bộ điều khiển được gọi trước các phương thức@RequestMapping, trong cùng một bộ điều khiển.

Với mã của tôi, getUser được gọi trước update, nhưng tôi muốn nhận người dùng được cập nhật.

Có cách nào để lộ các thuộc tính usersau hành động mà không cần gọi một cách rõ ràng model.addAttribute trong mỗi hành động?

Trả lời

5

Mỗi khi bạn thực hiện POST, hãy thực hiện chuyển hướng. Bằng cách đó, phương thức POST của bạn sẽ chỉ chịu trách nhiệm cập nhật dữ liệu và dữ liệu cập nhật sẽ được bộ điều khiển đích tải.

Vì vậy, trong trường hợp này, phương pháp update() sẽ chuyển hướng đến một bộ điều khiển khác gọi phương thức getUser() trước phương thức GET của nó.

1

Giải pháp Post/redirect/GET hợp lệ nếu nó phù hợp với bạn.

Tuy nhiên, tôi đã có một tình huống tương tự khi tôi có các thuộc tính mô hình cần được viết bởi tất cả các bộ điều khiển của tôi, sau khi xử lý yêu cầu (theo dõi thông tin chủ yếu). Những gì tôi đã làm là đăng ký giao diện tùy chỉnh (ví dụ: AdditionalModelDataSupplier), mà tôi áp dụng cho tất cả các trình điều khiển cần cung cấp dữ liệu bổ sung. Giao diện sẽ có một phương pháp như thế này:

void provideAdditionalData(Model model, HttpServletRequest request); 

Bây giờ, tôi đã viết một đánh chặn rằng trong phương pháp postHandle kiểm tra đậu khiển cho giao diện này và kêu gọi phương pháp này:

@Override 
public void postHandle(final HttpServletRequest request, final HttpServletResponse response, final Object handler, 
     final ModelAndView modelAndView) throws Exception { 

    AdditionalModelDataSupplier modelDataSupplier = findAdditionalModelDataSupplier(handler); 
    if (modelDataSupplier != null) { 
     final ModelMap modelMap = modelAndView.getModelMap(); 
     final Model targetModel; 
     if (modelMap instanceof Model) { 
      targetModel = (Model) modelMap; 
     } else { 

      // the modelmap doesn't implement model, so we need to provide a wrapper view 
      targetModel = new ForwardingModel(modelMap); 
     } 

     modelDataSupplier.provideAdditionalData(targetModel, request); 
    } 
} 
@Nullable 
private static AdditionalModelDataSupplier findAdditionalModelDataSupplier(final Object handler) { 
    if (handler instanceof AdditionalModelDataSupplier) { 
     return (AdditionalModelDataSupplier) handler; 
    } 

    if (handler instanceof HandlerMethod) { 
     HandlerMethod handlerMethod = (HandlerMethod) handler; 
     Object bean = handlerMethod.getBean(); 
     if (bean instanceof AdditionalModelDataSupplier) { 
      return (AdditionalModelDataSupplier) bean; 
     } 
    } 

    return null; 
} 

(lớp ForwardingModel đã đề cập ở trên là tầm thường để tạo, nó chỉ ủy quyền tất cả mọi thứ cho ModelMap)