2012-09-27 21 views
0

我有一個@InitBinder和Spring驗證的問題。Spring MVC - 方法返回時的init綁定器

首先,代碼:

控制器:

@Controller 
@RequestMapping("/manage") 
public class QuestionManagementController { 
... 
    @InitBinder 
    protected void initBinder(WebDataBinder binder) { 
     System.out.println("======"+binder.getObjectName()); 
     binder.setValidator(new QuestionListValidator()); 
     System.out.println("======"+binder.getObjectName()); 
    } 
... 
    @RequestMapping(value = "question/{unitid}", method = RequestMethod.GET) 
    public String getQuestionEditor(@SessionAttribute("userEntity") 
    UserEntity loggedUser, Model model, @PathVariable("unitid") 
    long unitId) { 
     QuestionUnit qu = questionUnitDao.getQuestionUnitById(
       QuestionUnit.class, unitId); 
     QuestionList list = questionListDao.getParentQuestionList(qu); 
     if (!isOwner(loggedUser, list)) { 
      throw new Http404Exception("Nie znaleziono strony."); 
     } 
     else { 
      model.addAttribute("questionUnit", qu); 
      model.addAttribute("listid", list.getId()); 
      model.addAttribute("formUrl", "/manage/question/" + qu.getId()); 
      System.out.println("sdhfdsfihui"); 
      return "/question/adder/" 
        + questionAnnotationProcessor.getJSPName(qu.getClass()); 
     } 

    } 

現在,使用的println的力量我有這樣的事情時,這個方法被調用:

INFO : pl.meble.taboret.controller.QuestionManagementController - entering: initBinder 
INFO : pl.meble.taboret.controller.QuestionManagementController - w/args:[org.springframework.web[email protected]1dc696e] 
======unitid 
======unitid 
INFO : pl.meble.taboret.controller.QuestionManagementController - entering:getQuestionEditor 
INFO : pl.meble.taboret.controller.QuestionManagementController - w/args: [user, {}, 1245184] 
sdhfdsfihui 
INFO : pl.meble.taboret.controller.QuestionManagementController - entering: initBinder 
INFO : pl.meble.taboret.controller.QuestionManagementController - w/args: [org.springframework.web[email protected]404629] 
======questionUnit 
class pl.meble.taboret.question.OpenQuestion 
INFO : pl.meble.taboret.controller.QuestionManagementController - entering: handleMyException 
INFO : pl.meble.taboret.controller.QuestionManagementController - w/args: [java.lang.IllegalStateException: Invalid target for Validator [[email protected]5]: [email protected]] 

所以它看起來在init binder之前被調用 - 這是正常的,並且在方法return聲明之後。返回的字符串是Apache Tiles定義的名稱。

也很奇怪,init binder被調用questionUnit,驗證器被設置,然後出現錯誤。

名單驗證看起來像這樣

@Component 
public class QuestionListValidator implements Validator { 
    @Override 
    public boolean supports(Class<?> clazz) { 
     System.out.println(clazz.toString()); 
     return QuestionList.class.isAssignableFrom(clazz); 
    } 

    @Override 
    public void validate(Object target, Errors errors) { 
     ValidationUtils.rejectIfEmpty(errors, "name", "name.empty"); 
    } 
} 

,我們可以看到印刷類的名稱。

我不知道爲什麼這樣的行爲,但我敢肯定,這是@InitBinder沒有任何參數的錯誤。

我讀了春天文檔中關於這個註解value參數,這裏是

The names of command/form attributes and/or request parameters that this init-binder method is supposed to apply to. 
Default is to apply to all command/form attributes and all request parameters processed by the annotated handler class. Specifying model attribute names or request parameter names here restricts the init-binder method to those specific attributes/parameters, with different init-binder methods typically applying to different groups of attributes or parameters. 

那麼這是否意味着如果沒有參數,驗證驗證進來(請求參數)熄滅一切,一切(命令/表單屬性)?如果是這樣,爲什麼沒有使用userEntity參數的init綁定器的調用。爲什麼@InitBinder在控制器方法返回字符串後被調用。

回答

1

驗證器不會被調用,除非你的參數有一個@Valid註解,或者你明確地調用它。在你的情況下,他們不應該被召喚。但是,InitBinder方法將針對您所看到的每個參數進行調用。

在驗證程序設置爲方法參數的時候,將調用驗證程序的supports方法來確定驗證程序是否支持參數類型,即可能您正在看到支持被調用,但驗證方法將不會被調用,除非你有@Validate註解也

+0

在閱讀你的迴應,並打了一下這個註釋我現在知道它是如何工作的,謝謝。 – Andna

相關問題