Java 使用SpringMVC3进行正确的表单验证-捕获PersistenceException
我一直在寻找一种在SpringMVC3中使表单验证尽可能简单和不引人注目的方法。我喜欢spring处理Bean验证的方式,它通过将@Valid传递给我的模型(已使用验证器注释进行注释)并使用result.hasErrors()方法 我正在设置控制器操作,如下所示:Java 使用SpringMVC3进行正确的表单验证-捕获PersistenceException,java,spring,spring-mvc,Java,Spring,Spring Mvc,我一直在寻找一种在SpringMVC3中使表单验证尽可能简单和不引人注目的方法。我喜欢spring处理Bean验证的方式,它通过将@Valid传递给我的模型(已使用验证器注释进行注释)并使用result.hasErrors()方法 我正在设置控制器操作,如下所示: @RequestMapping(value = "/domainofexpertise", method = RequestMethod.PUT) public String addDomainOfExpertise(@ModelAt
@RequestMapping(value = "/domainofexpertise", method = RequestMethod.PUT)
public String addDomainOfExpertise(@ModelAttribute("domainOfExpertise")
@Valid DomainOfExpertise domainOfExpertise, final BindingResult result) {
if (result.hasErrors()) {
return "/domainofexpertise/add";
} else {
domainOfExpertiseService.save(domainOfExpertise);
return "redirect:/admin/domainofexpertise/list";
}
}
这就像一个符咒。数据库异常(如试图在字段上保存具有唯一约束的内容)仍然可以通过。有没有办法将捕获这些异常合并到幕后进行的验证过程中?这种验证方法非常简洁,因此我希望避免在控制器中手动捕获它们
有关于这方面的信息吗?下面是一个示例,我使用它将PersistentException转换为更友好的消息。这是一种进入控制器的方法。这对你有用吗
/**
* Shows a friendly message instead of the exception stack trace.
* @param pe exception.
* @return the exception message.
*/
@ExceptionHandler(PersistenceException.class)
@ResponseBody
@ResponseStatus(HttpStatus.BAD_REQUEST)
public String handlePersistenceException(final PersistenceException pe) {
String returnMessage;
if (pe.getCause()
instanceof ConstraintViolationException) {
ConstraintViolationException cve =
(ConstraintViolationException) pe.getCause();
ConstraintViolation<?> cv =
cve.getConstraintViolations().iterator().next();
returnMessage = cv.getMessage();
} else {
returnMessage = pe.getLocalizedMessage();
}
if (pe instanceof EntityExistsException) {
returnMessage = messages.getMessage("user.alreadyexists");
}
return returnMessage;
}
/**
*显示友好消息,而不是异常堆栈跟踪。
*@param-pe异常。
*@返回异常消息。
*/
@ExceptionHandler(PersistenceException.class)
@应答器
@ResponseStatus(HttpStatus.BAD_请求)
公共字符串handlePersistenceException(最终PersistenceException pe){
字符串返回消息;
if(pe.getCause()
instanceof ConstraintViolationException){
ConstraintViolationException cve=
(ConstraintViolationException)pe.getCause();
约束激振cv=
cve.getConstraintViolations().iterator().next();
returnMessage=cv.getMessage();
}否则{
returnMessage=pe.getLocalizedMessage();
}
if(实体存在异常的pe实例){
returnMessage=messages.getMessage(“user.alreadyexists”);
}
返回消息;
}
控制器上的验证是为了防止调用传播到数据库层,但是为什么要在这一层处理数据库异常呢。如果在DB层出现异常,则应传播到控制器,并显示错误或重定向到其他页面。如果你在这里做的话,我看到的是分离关注点的突破。只是我的想法。那么我应该在我的服务层的save方法中捕获持久性异常吗?执行此操作时,将异常返回控制器的正确方法是什么?有几种方法可以解释异常,其中一种是Luciano提到的定义通用异常处理程序的方法,另一种方法是捕获持久性异常,并将其作为特定于应用程序的运行时异常进行重试,然后在web.xml中声明一个通用页面,如“技术困难”来处理此问题,另一个是捕获并重新抛出特定于应用程序的已检查异常,并在控制器层进行适当处理,并向用户显示一条已解释的消息(我不喜欢这样,因为整个调用方法堆栈都应该声明抛出)