2014-07-25 53 views
2

我正在为Spring MVC使用Java配置。我无法使Bean Validation正常工作。我有一个我注释过的域类,我想在我的控制器中使用@Valid。我知道使用XML配置,我会设置验证器这种方式<mvc:annotation-driven validator="validator"/>使用Java配置进行Spring MVC Bean验证

我该如何做到这一点与Java配置。我没有收到任何错误,验证只是不起作用。提前致谢!

这里是我的设置:

域类注释:

public class Product { 

    @Pattern(regexp="P[1-9]+", message="{Pattern.Product.productId.validation}") 
    @ProductId 
    private String productId; 

    @Size(min=4, max=50, message="{Size.Product.name.validation}") 
    private String name; 

    @Min(value=0, message="Min.Product.unitPrice.validation}") 
    @Digits(integer=8, fraction=2, message="{Digits.Product.unitPrice.validation}") 
    @NotNull(message= "{NotNull.Product.unitPrice.validation}") 
    private BigDecimal unitPrice; 
    private String description; 
    private String manufacturer; 
    private String category; 
    private long unitsInStock; 

这里是我的控制器使用@Valid:

@Controller 
@RequestMapping("/products") 
public class ProductController { 

..... (shortened) 

@RequestMapping(value = "/add", method = RequestMethod.GET) 
    public String getAddNewProductForm(@ModelAttribute("newProduct") Product newProduct) { 
     return "addProduct"; 
    } 

    @RequestMapping(value = "/add", method = RequestMethod.POST) 
    public String processAddNewProductForm(@ModelAttribute("newProduct") @Valid Product productToBeAdded, BindingResult result, HttpServletRequest request) { 
     if(result.hasErrors()) { 
      return "addProduct"; 
     } 

     String[] suppressedFields = result.getSuppressedFields(); 

     if (suppressedFields.length > 0) { 
      throw new RuntimeException("Attempting to bind disallowed fields: " + StringUtils.arrayToCommaDelimitedString(suppressedFields)); 
     } 

     MultipartFile productImage = productToBeAdded.getProductImage(); 
     String rootDirectory = request.getSession().getServletContext().getRealPath("/"); 

      if (productImage!=null && !productImage.isEmpty()) { 
       try { 
       productImage.transferTo(new File(rootDirectory+"resources\\images\\"+productToBeAdded.getProductId() + ".png")); 
       } catch (Exception e) { 
       throw new RuntimeException("Product Image saving failed", e); 
      } 
      } 


     productService.addProduct(productToBeAdded); 
     return "redirect:/products"; 
    } 

这是我与@EnableWebMVC配置类:(***更新为获得验证程序***

@SuppressWarnings("deprecation") 
@Configuration 
@ComponentScan(basePackages = {"com.nam.webstore"}) 
@EnableWebMvc 
public class WebConfig extends WebMvcConfigurerAdapter { 

..... (shortened) 

    @Bean(name = "validator") 
    public LocalValidatorFactoryBean localValidatorFactoryBean() { 
     LocalValidatorFactoryBean lvfb = new LocalValidatorFactoryBean(); 

     lvfb.setValidationMessageSource(resourceBundleMessageSource()); 

     return lvfb; 
    } 

    (***** Updated *****) 
    @Override 
    public Validator getValidator() { 
     return localValidatorFactoryBean(); 
    } 
} 

下面是错误标签的jsp:

..... (shortened) 

<section class="container"> 
    <form:form modelAttribute="newProduct" class="form-horizontal" enctype="multipart/form-data"> 
     <fieldset> 
      <legend>Add new product</legend> 

      <form:errors path="*" cssClass="alert alert-danger" element="div"/> 
      <div class="form-group"> 
       <label class="control-label col-lg-2 col-lg-2" for="productId"><spring:message code="addProduct.form.productId.label"/></label> 
       <div class="col-lg-10"> 
        <form:input id="productId" path="productId" type="text" class="form:input-large"/> 
        <form:errors path="productId" cssClass="text-danger"/> 
       </div> 
      </div> 

      <div class="form-group"> 
       <label class="control-label col-lg-2" for="name"><spring:message code="addProduct.form.name.label"/></label> 
       <div class="col-lg-10"> 
        <form:input id="name" path="name" type="text" class="form:input-large"/> 
        <form:errors path="name" cssClass="text-danger"/> 
       </div> 
      </div> 

      <div class="form-group"> 
       <label class="control-label col-lg-2" for="unitPrice"><spring:message code="addProduct.form.unitPrice.label"/></label> 
       <div class="col-lg-10"> 
        <div class="form:input-prepend"> 
         <form:input id="unitPrice" path="unitPrice" type="text" class="form:input-large"/> 
         <form:errors path="unitPrice" cssClass="text-danger"/> 
        </div> 
       </div> 
      </div> 

      <div class="form-group"> 
       <label class="control-label col-lg-2" for="description"><spring:message code="addProduct.form.description.label"/></label> 
       <div class="col-lg-10"> 
        <form:textarea id="description" path="description" rows = "2"/> 
       </div> 
      </div> 

更新 记录器设置为DEBUG后,这是我所看到的在控制台中。我可以看到它启动了验证,但我不知道为什么它说我将空值返回给DispatcherServlet?我正在返回视图名称。在对象“新品推荐”现场“单价”

字段错误:拒绝 值[空]。代码 [NotNull.newProduct.unitPrice,NotNull.unitPrice,NotNull.java.math.BigDecimal,NotNull]; 参数 [org.springframework.context.support.DefaultMessageSourceResolvable: codes [newProduct.unitPrice,unitPrice];参数[];默认信息 [unitPrice]];预设讯息[单价无效。它不能为 为空。]字段'productId'上的对象'newProduct'中的字段错误: rejected value [];代码 [Pattern.newProduct.productId,Pattern.productId,Pattern.java.lang.String,Pattern]; 参数 [org.springframework.context.support.DefaultMessageSourceResolvable: codes [newProduct.productId,productId];参数[];默认消息 [productId],[Ljavax.validation.constraints.Pattern $ Flag; @ 3641ef8a,P [1-9] +]; 默认消息[产品ID无效。它应该以字符P 后跟数字开始。]字段 'name'的对象'newProduct'中的字段错误:rejected value [];代码 [Size.newProduct.name,Size.name,Size.java.lang.String,Size];参数 [org.springframework.context.support.DefaultMessageSourceResolvable: codes [newProduct.name,name];参数[];默认信息 [name],50,4];默认信息[产品名称无效。它应该是 最少4个字符到最多50个字符长。] 2014-07-25 15:03:36调试ResponseStatusExceptionResolver:134 - 解决 异常处理程序[public java.lang.String com.nam.webstore.controller .ProductController.processAddNewProductForm(com.nam.webstore.domain.Product,org.springframework.ui.ModelMap,org.springframework。validation.BindingResult,javax.servlet.http.HttpServletRequest)〕: org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult:3级中的错误对象 '新品推荐' 现场 '单价' 字段错误:拒绝 值[null];代码 [NotNull.newProduct.unitPrice,NotNull.unitPrice,NotNull.java.math.BigDecimal,NotNull]; 参数 [org.springframework.context.support.DefaultMessageSourceResolvable: codes [newProduct.unitPrice,unitPrice];参数[];默认信息 [unitPrice]];预设讯息[单价无效。它不能为 为空。]字段'productId'上的对象'newProduct'中的字段错误: rejected value [];代码 [Pattern.newProduct.productId,Pattern.productId,Pattern.java.lang.String,Pattern]; 参数 [org.springframework.context.support.DefaultMessageSourceResolvable: codes [newProduct.productId,productId];参数[];默认消息 [productId],[Ljavax.validation.constraints.Pattern $ Flag; @ 3641ef8a,P [1-9] +]; 默认消息[产品ID无效。它应该以字符P 后跟数字开始。]字段 'name'的对象'newProduct'中的字段错误:rejected value [];代码 [Size.newProduct.name,Size.name,Size.java.lang.String,Size];参数 [org.springframework.context.support.DefaultMessageSourceResolvable: codes [newProduct.name,name];参数[];默认信息 [name],50,4];默认信息[产品名称无效。它应该是 最少4个字符到最多50个字符长。] 2014-07-25 15:03:36 DEBUG DefaultHandlerExceptionResolver:134 - 解决 异常处理程序[public java.lang.String com.nam.webstore.controller .ProductController.processAddNewProductForm(com.nam.webstore.domain.Product,org.springframework.ui.ModelMap,org.springframework.validation.BindingResult,javax.servlet.http.HttpServletRequest)]: org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult:3个错误 字段'unitPrice'上对象'newProduct'中的字段错误:被拒绝 value [null];代码 [NotNull.newProduct.unitPrice,NotNull.unitPrice,NotNull.java.math.BigDecimal,NotNull]; 参数 [org.springframework.context.support.DefaultMessageSourceResolvable: codes [newProduct.unitPrice,unitPrice];参数[];默认信息 [unitPrice]];预设讯息[单价无效。它不能为 为空。]字段'productId'上的对象'newProduct'中的字段错误: rejected value [];代码 [Pattern.newProduct.productId,Pattern.productId,Pattern.java.lang.String,Pattern]; 参数 [org.springframework.context.support.DefaultMessageSourceResolvable: codes [newProduct.productId,productId];参数[];默认消息 [productId],[Ljavax.validation.constraints.Pattern $ Flag; @ 3641ef8a,P [1-9] +]; 默认消息[产品ID无效。它应该以字符P 后跟数字开始。]字段 'name'的对象'newProduct'中的字段错误:rejected value [];代码 [Size.newProduct.name,Size.name,Size.java.lang.String,Size];参数 [org.springframework.context.support.DefaultMessageSourceResolvable: codes [newProduct.name,name];参数[];默认信息 [name],50,4];默认信息[产品名称无效。它应该是 最少4个字符到最多50个字符长。] 2014-07-25 15:03:36 DEBUG DispatcherServlet:1012 - 空ModelAndView返回到 名称为“DispatcherServlet”的DispatcherServlet:假设 HandlerAdapter完成请求处理2014-07-25 15:03:36调试 DispatcherServlet:991 - 成功完成请求

回答

4

在你WebMvcConfigurerAdapter可以重写getValidator()方法使其返回您的自定义Validator

LocalValidatorFactoryBean,你可以拨打afterPropertiesSet()getObject()得到真正的Validator

+0

索蒂里奥斯,我已经更新了代码,你建议。现在,我获得了400的地位。如果我删除了有效的注释,我可以提交,但验证仍然无效。我也尝试使用有效注释作为第一个参数。 – NuAlphaMan

+0

@NuAlphaMan将您的记录器级别调试。 Spring会报告为什么它返回了400. –

+0

我已经将它改为调试,并且它说我返回null,这是我没有得到的。在控制器中,我返回视图名称。 – NuAlphaMan

1

老问题,但我有同样的问题,所以我会贴这个bean

@Override 
public Validator getValidator() { 
    LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); 
    validator.setValidationMessageSource(messageSource()); 
    return validator; 
}