JSR 303 Bean Validation + Javascript Client-Side Validation

后端 未结 7 1128
感情败类
感情败类 2021-01-30 20:48

What is the best way to perform client-side form validation using Javascript (with minimal code duplication) when using JSR 303 bean validation on the server side? I\'m currentl

相关标签:
7条回答
  • 2021-01-30 21:08

    Richfaces supports this. They have a small demo on their site.

    0 讨论(0)
  • 2021-01-30 21:08

    Edit:

    Indeed JSR 303 is the best way (IMO) to handle client side validation. The best thing is that if you have proper js libraries on the fronted you can use the same validation (the same code) on the server (if you would use node.js). I've created library @stopsopa/validation for this purposes I'm validating forms like this (In React.js):

    import React, { Component } from "react";
    import ReactDOM from "react-dom";
    
    import validator, {
      Collection,
      Required,
      Optional,
      NotBlank,
      Length,
      Email,
    } from "@stopsopa/validator";
    
    class App extends Component {
      constructor(...args) {
        super(...args);
        this.state = {
          data: {
            name: "",
            email: ""
          },
          errors: {},
          validate: false
        };
      }
      onSubmit = async e => {
        e.preventDefault();
    
        const errors = await validator(this.state.data, new Collection({
          name: new Required([
            new NotBlank(),
            new Length({min: 3}),
          ]),
          email: new Required([
            new NotBlank(),
            new Email(),
          ])
        }));
        this.setState({
          errors: errors.getFlat(),
          validate: true,
        });
    
        if ( ! errors.count()) {
    
          console.log('send data to server', this.state.data);
        }
      };
      onChange = (name, value) => {
        this.setState(state => ({
          ...state,
          data: { ...state.data, ...{ [name]: value } }
        }));
      };
      render() {
        const s = this.state;
        return (
          <form onSubmit={this.onSubmit}>
            <label>
              name:
              <input
                value={s.data.name}
                onChange={e => this.onChange("name", e.target.value)}
              />
            </label>
            {s.validate && s.errors.name && (
              <div className="error">{s.errors.name}</div>
            )}
            <br />
            <label>
              email:
              <input
                value={s.data.email}
                onChange={e => this.onChange("email", e.target.value)}
              />
            </label>
            {s.validate && s.errors.email && (
              <div className="error">{s.errors.email}</div>
            )}
            <br />
            <input type="submit" value="submit" />
          </form>
        );
      }
    }
    
    ReactDOM.render(<App />, document.getElementById("root"));
    

    live example is available here: https://codesandbox.io/s/ymwky9603j

    0 讨论(0)
  • 2021-01-30 21:17

    I would suggest that you look at Spring JS, which relies heavily on Dojo. A tutorial can be found here.

    Easiest way for yourself to start playing with it is to download Spring Roo, create the petclinic sample application with one of the example-scripts (this takes you 5 minutes) and then play around with how the javascript is integrated. Spring Roo creates an app with the same technology stack that you use (Spring+hibernate+implementation of jsr 303)

    0 讨论(0)
  • 2021-01-30 21:21

    Here's how I'm doing it using Spring MVC + JQuery + Bootstrap, partially based on a recent blog post at SpringSource:

    AddressController.java

    @RequestMapping(value="/validate")
    public @ResponseBody ValidationResponse processForm(Model model, @Valid AddressForm addressForm, BindingResult result) {
        ValidationResponse res = new ValidationResponse();
        if (result.hasErrors()) {
            res.setStatus("FAIL");
            for (ObjectError error : result.getAllErrors()) {
                if (error instanceof FieldError) {
                    FieldError fieldError = (FieldError) error;
                    res.addError(fieldError.getField(), fieldError.getDefaultMessage());
                }    
            }
        }
        else {
            res.setStatus("SUCCESS");
        }
        return res;
    }
    

    AddressForm.java

    public class AddressForm {
        @NotNull
        @Size(min=1, max=50, message="Address 1 is required and cannot be longer than {max} characters")
        private String address1;
    
        @Size(max=50, message="Address 2 cannot be longer than {max} characters")
        private String address2;
    
        // etc
    }
    

    ValidationResponse.java:

    public class ValidationResponse {
        private String status;
        private Map<String,String> errors;
        // getters, setters
    }
    

    address.jsp:

    <f:form commandName="addressForm">
        <div class="control-group">
            <label for="address1">Address 1</label>
            <div class="controls">
                <f:input path="address1" type="text" placeholder="Placeholder Address 1" class="wpa-valid" />
                <span class="help-inline"></span>
            </div>
        </div>
        <!-- etc -->
        <div class="form-actions">
            <button type="submit" class="btn btn-primary">Save</button>
            <button type="button" class="btn">Cancel</button>
        </div>
    </f:form>
    
    <script type="text/javascript">
    function collectFormData($fields) {
        var data = {};
        for (var i = 0; i < $fields.length; i++) {
            var item = $($fields[i]);
            data[item.attr("id")] = item.val();
        }
    
        return data;
    }
    
    function clearErrors($fields) {
        for (var i = 0; i < $fields.length; i++) {
            var item = $($fields[i]);
            $("#"+item.attr("id")).parents(".control-group").removeClass("error");
            $("#"+item.attr("id")).siblings(".help-inline").html("");
        }
    }
    
    function markErrors(errors) {
        $.each(errors, function(key, val) {
            $("#"+key).parents(".control-group").addClass("error");
            $("#"+key).siblings(".help-inline").html(val);
        });
    }
    
    $(document).ready(function() {
        var $form = $("form.validate");
        $form.bind("submit", function(e) {
            var $fields = $form.find(".validate");
    
            clearErrors($fields);
            var data = collectFormData($fields);
    
            var validationUrl = "validate";
            $.get(validationUrl, data, function(response) {
                $("#alert").removeClass();
    
                if (response.status == "FAIL") {
                    markErrors(response.errors);
    
                    $("#alert").addClass("alert alert-error");
                    $("#alert").html("Correct the errors below and resubmit.");
                } else {
                    $("#alert").addClass("alert alert-success");
                    $("#alert").html("Success!");
    
                    $form.unbind("submit");
                    $form.submit();
                }
            }, "json");
    
            e.preventDefault();
            return false;
        });
    });
    </script>
    

    It could use some refactoring, but this will do an ajax GET with the form data and update the page based on the result.

    0 讨论(0)
  • 2021-01-30 21:22

    PrimeFaces Client Side Validation Framework Supports Bean Validation.

    http://blog.primefaces.org/?p=2874

    0 讨论(0)
  • 2021-01-30 21:22

    Here is an open source alternative to JSR-303.

    This solution can perform all validation of the request message, but no hassle coding is required.

    https://github.com/ckpoint/CheckPoint

    With Check-Point, all validation is possible without further code, just by changing the annotation of the Controller method.

    After that, all validation settings can be easily made in Admin Page.

    I think this video can help your understand. https://youtu.be/I1aEIztXlhE

    Check-Point Admin-Page Setting Screen

    0 讨论(0)
提交回复
热议问题