我遇到@InitBinder
和Spring验证问题。
首先,代码:
控制器:
@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.servlet.mvc.method.annotation.ExtendedServletRequestDataBinder@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.servlet.mvc.method.annotation.ExtendedServletRequestDataBinder@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 [pl.meble.taboret.validator.question.QuestionListValidator@1be6a65]: pl.meble.taboret.question.OpenQuestion@1f9cb2c]
因此看起来之前调用了init binder - 这是正常的,并且在方法return
语句之后。返回的字符串是Apache Tiles定义的名称。
同样奇怪的是,使用questionUnit
调用init绑定器,设置验证器,然后出现错误。
列表验证器看起来像这样
@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
参数的spring文档,此处为
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绑定器。以及在控制器方法返回String之后调用@InitBinder
的原因。
答案 0 :(得分:1)
除非您的参数具有@Valid注释,或者您明确调用它,否则不会调用验证器。在你的情况下,他们不应该被召唤。但是,对于您看到的每个参数,都将调用InitBinder方法。
在为方法参数设置验证器时,调用验证器的supports方法以确定验证器是否支持参数类型,即您可能看到正在调用支持,但验证方法将除非你还有@Validate注释
,否则不要调用