Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/345.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 困惑于如何验证SpringMVC表单,我的选项是什么?_Java_Spring_Validation_Spring Mvc_Freemarker - Fatal编程技术网

Java 困惑于如何验证SpringMVC表单,我的选项是什么?

Java 困惑于如何验证SpringMVC表单,我的选项是什么?,java,spring,validation,spring-mvc,freemarker,Java,Spring,Validation,Spring Mvc,Freemarker,最新的spring mvc,使用freemarker 希望有人能告诉我,在使用SpringMVC验证表单方面,我有哪些选择,推荐的方法是什么 我有一个表单,它不直接映射到模型,它有输入字段,当发布时,将用于初始化2个模型对象,然后我需要验证它们,如果它们通过,我将保存它们 如果失败,我想返回表单,用用户输入的内容预填充值并显示错误消息 我在这里和那里读过两种方法,其中一种是我做过的,并且了解它是如何工作的: @RequestMapping(...., method = RequestMethod

最新的spring mvc,使用freemarker

希望有人能告诉我,在使用SpringMVC验证表单方面,我有哪些选择,推荐的方法是什么

我有一个表单,它不直接映射到模型,它有输入字段,当发布时,将用于初始化2个模型对象,然后我需要验证它们,如果它们通过,我将保存它们

如果失败,我想返回表单,用用户输入的内容预填充值并显示错误消息

我在这里和那里读过两种方法,其中一种是我做过的,并且了解它是如何工作的:

@RequestMapping(...., method = RequestMethod.POST)
public ModelAndView myMethod(@Valid MyModel, BindingResult bindingResult) {
  ModelAndView mav = new ModelAndView("some/view");
  mav.addObject("mymodel", myModel);

  if(bindingResult.hasErrors()) {
     return mav;
  }

}
现在,如果我的表单直接映射到该表单,则此操作有效,但在我的情况下,我有:

  • 表单字段不映射到任何特定模型,它们有两个模型中的一些属性

  • 在进行验证之前,我需要手动创建这两个模型,从表单中设置值,并手动设置一些属性:

  • 在两个模型(model1、model2)上调用validate,并将这些错误消息附加到errors集合中,如果出现问题,我需要将这些错误消息传递回同一视图页面

  • 当表单发布时,我必须进行一些数据库调用,并根据这些结果可能需要向errors集合添加额外的消息

  • 有人能告诉我如何进行这种验证吗

    伪代码如下:

       Model1 model1 = new Model1();
       Model2 model2 = new Model2();
    
       // manually or somehow automatically set the posted form values to model1 and model2.
    
       // set some fields manually, not from posted form
       model1.setProperty10(GlobalSettings.getDefaultProperty10());
       model2.setProperty11(GlobalSettings.getDefaultProperty11());
    
       // db calls, if they fail, add to errors collection
    
       if(bindingResult.hasErrors()) {
         return mav;
       }
    
       // validation passed, save
       Model1Service.save(model1);
       Model2Service.save(model2);
    
       redirect to another view
    
    更新

    我现在已经在我的模型上使用了JSR303注释,如果我仍然可以使用这些注释,那就太好了

    更新二


    请阅读下面的赏金描述,了解我所寻找的赏金的摘要。

    基于类似的经验,我提出以下建议,同时我对您想要采取的方法的最后一步发表了评论。我使用你编号的步骤列表

    步骤1:表单Bean

    有两种方法。简单的方法是定义一个表单bean(我想您已经这样做了):

    一种更精确的方法是实际定义
    MyModel
    ,这样我只借用
    Model1
    Model2
    中需要的字段,但我不确定这是否适合您的方式

    步骤2:数据绑定

    如果您的视图中有这样的
    表单
    结构,Spring会为您这样做:

    <form:form modelAttribute="myModel">
      <form:input path="model1.somePropertyToBeSet" />
    </form:form>
    
    然后为自定义约束注册自定义验证器:

    @interface Model1Constraint {}
    @interface Model2Constraint {}
    
    class MyModel1 {
    
      @Model1Constraint
      private Model1 model1;
    
      @Model2Constraint
      private Model2 model2;
    
      // ...
    
    }
    
    class Model1ConstraintValidator implements ConstraintValidator<Model1Constraint, Model1> {
    // implementation of isValid and initalize
    }
    
    class Model1ConstraintValidator实现ConstraintValidator{
    //isValid和initalize的实现
    }
    
    Model2Constraint
    也一样。使用自定义验证器,您可以检查在将
    MyModel
    传递到请求处理方法之前需要确保的逻辑。我还假设您使用了
    让Spring注册验证器;否则,您应该配置它们

    步骤4:请求处理之前的自定义模型处理

    您最初的想法是为这项工作使用一些数据绑定器。在您的描述中,您还提到此数据处理不依赖于来自表单数据的数据

    关于设计和模块化,我不认为数据绑定器是实现这一目的的好地方。其次,由于表单没有数据依赖性,因此主要原因是允许数据绑定错误处理

    因此,我的建议是,假设您现在处于
    公共模型和查看myMethod(@Valid MyModel model,BindingResult BindingResult)
    。大概您可以在这里访问其他服务bean。因此,您可以在一些服务bean中有一个方法,该方法可以
    优化
    准备
    (只是命名)您在这里填充的
    模型
    。基于异常或任何适合您的其他机制,您可以使用
    bindingResult
    再次返回错误

    另一个建议是,如果您希望使用更多的DI/IoC方法,您也可以利用。但通过这种方式,您应该从拦截中的
    model和view
    中提取
    MyModel
    ,然后继续


    我希望这会有所帮助。

    Hibernate Validator 4.2支持方法级验证。您可以稍微重构代码,将两个模型传递到一个方法中,并验证它们

    你可以吃这样的东西

    public void persistUser(@NotNull @Valid Model1 model1, @NotNull @Valid Model2 model2) {
    
          //continue ...
    }   
    

    这是一个不寻常的问题,因为验证用户输入通常最有意义,因为这是我们无法控制的数据。这么说吧,我相信你已经知道了

    一种选择是直接使用JSR303验证api在从用户输入、数据库等填充模型对象之后验证它们

    下面是一个例子:

    @RequestMapping(value=...)
    public String myMethod(MyForm form, Model m) {
    
        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        Validator validator = factory.getValidator();
    
        Model1 model1 = createModel1FromUserInput(form);
        Model2 model2 = createModel2FromUserInput(form);
    
        Set<ConstraintViolation<?>> modelViolations = validator.validate(model1);
        modelViolations.add(validator.validate(model2));
        if(modelViolations.size() != 0) {
            m.addAttribute("violations", modelViolations);
            m.addAttribute("form", myForm); // add the form back to the model so it is populated
            return "formPage";
        }
        return "successPage";
    }
    
    @RequestMapping(值=…)
    公共字符串myMethod(MyForm表单,模型m){
    ValidatorFactory=Validation.buildDefaultValidatorFactory();
    Validator Validator=factory.getValidator();
    Model1 Model1=createModel1FromUserInput(表单);
    Model2 Model2=createModel2FromUserInput(表单);
    
    在这里设置精彩的解释,请检查

    也请检查下面的示例

    @RequestMapping(value=...)
    public String myMethod(MyForm form, Model m) {
    
        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        Validator validator = factory.getValidator();
    
        Model1 model1 = createModel1FromUserInput(form);
        Model2 model2 = createModel2FromUserInput(form);
    
        Set<ConstraintViolation<?>> modelViolations = validator.validate(model1);
        modelViolations.add(validator.validate(model2));
        if(modelViolations.size() != 0) {
            m.addAttribute("violations", modelViolations);
            m.addAttribute("form", myForm); // add the form back to the model so it is populated
            return "formPage";
        }
        return "successPage";
    }
    
    BindingResult result = ... // not sure about the constructor
    for(ConstraintViolation<?> violation : modelViolations) {
            result.addError(new ObjectError(violation.getPropertyPath().toString(),violation.getMessage()));
    }
    
    <c:forEach items="${violations}" var="violation">
        ${violation.propertyPath}: ${violation.message} <br/>
    </c:forEach>