簡體   English   中英

用於onBind()的Spring MVC 3 Controller注釋 - 如何?

[英]Spring MVC 3 Controller annotation for onBind() - how to?

我正在從Spring 2.5升級到Spring 3.2。 我有一個MVC控制器,以前擴展了CancellableFormController 它分別聲明了initBinder()onBind()方法。 我重構了Controller以使用@Controller注釋,並將重寫的initBinder()方法切換為使用Spring MVC 3注釋@initBinder

我的具體問題是,在Spring MVC 3中,從Spring 2.5升級,如何重構重寫的onBind()方法以使用注釋等價物? 現有方法的簽名是:

@Override
protected void onBind(HttpServletRequest request, Object command, BindException errors)  throws Exception {
    MyCommand cmd = (MyCommand) command;
    ....
}

我想過使用@initBinder()並將之前的代碼放在onBind()這個帶注釋的方法中。 但我在這里的困惑是:

  1. 這樣做,代碼是否會像以前一樣在整個框架過程中同時被調用?
  2. 如何從@initBinder注釋方法獲取Command對象的句柄。

我可以將它聲明為方法簽名中的另一個參數,Spring MVC框架將確保我得到一個副本嗎? 似乎在舊的onBind()方法中已經創建了Command對象(通過formBackingObject方法)。 我可以安全地假設使用@initBinder方法時也是如此嗎?

感謝任何人的一些見解。 我正在努力加快Spring MVC流程的速度!

我現有的@initBinder方法簽名是這樣的:

@InitBinder
protected void initBinder(WebDataBinder binder) {
    // register custom editor here.. etc
}

我希望我可以這樣做:

@InitBinder
protected void initBinder(WebDataBinder binder, MyCommand cmd) {
   // register custom editor here.. etc
}

這是使用注釋升級cancellableformcontroller onBind()方法的標准最佳實踐方法嗎?

嘗試根據答案標記正確,仍然無法正常工作:

@InitBinder("myCommand")
protected void onBind(WebDataBinder binder) throws Exception {
    MyCommand cmd = (MyCommand) binder.getTarget();
    .... // do whatever was required here...
}

解決

請參閱下面我對zeroflag的評論。 使用onBind()中包含的相同邏輯創建一個私有方法,然后在onSubmit()注釋方法(POST / GET)中驗證命令對象后,調用現在已不存在的onBind()方法,將Command對象作為一個傳遞給參數。 類似於以下內容:

@RequestMapping(method=RequestMethod.POST) 
public ModelAndView onSubmit(@ModelAttribute("myCommand") MyCommand cmd, BindingResult result, <any other params> {

        new MyCommandValidator().validate(cmd, result);
        if (result.hasErrors()) {
            return new ModelAndView("context");
        }
        onBind(cmd, <any other params>);

        ... // do business stuff

}

它似乎是一個丑陋的解決方法,對我的特殊情況是好的。

您可以使用binder.getTarget()訪問命令對象。 為控制器方法的每個模型參數調用@InitBinder 我們假設以下代碼

@RequestMapping("/somePath")
public String myMethod(@ModelAttribute("user") User user,
                       @ModelAttribute("info") Info info) {

然后,您的initBinder方法至少被調用兩次:對於User對象和Info對象。 要僅為特定對象調用它,請添加模型名稱:

@InitBinder("user")

這樣只會為User對象調用它。 但請注意,該方法可能仍會被多次調用,即使目標對象為null也是第一次。

如果要確保未自動設置某些字段,則可以在initBinder方法中使用setDisallowedFields()

如果您想進行一些驗證,那么讓JSR 303(Bean Validation)完成這項工作。

根據您的想法,控制器中的@ModelAttribute方法可以是一個解決方案:

@ModelAttribute("user")
public User createUser(HttpServletRequest request /*or whatever*/) {
  User user = new User();
  //check some parameters and set some attributes
  return user;
}

綁定發生之前創建用戶對象。

最后一個解決方案可以是命令對象的消息或類型轉換器,它從請求中創建對象。 這實際上與上面的示例相似,但與控制器無關,並且對於使用轉換器創建的對象沒有綁定。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM