@Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp)
      throws ServletException, IOException {
    PrintWriter out = resp.getWriter();
    resp.setContentType("text/html");
    out.print("<html><head><title>SimpleBVServlet</title></head><body>");

    javax.validation.Validator beanValidator = configureValidation(req, resp);

    out.print("<h1>");
    out.print("Validating person class using validateValue with valid property");
    out.print("</h1>");

    List<String> listOfString = new ArrayList<String>();
    listOfString.add("one");
    listOfString.add("two");
    listOfString.add("three");

    Set<ConstraintViolation<Person>> violations =
        beanValidator.validateValue(Person.class, "listOfString", listOfString);

    printConstraintViolations(out, violations, "case1");

    out.print("<h1>");
    out.print("Validating person class using validateValue with invalid property");
    out.print("</h1>");

    try {
      violations = beanValidator.validateValue(Person.class, "nonExistentProperty", listOfString);
    } catch (IllegalArgumentException iae) {
      out.print("<p>");
      out.print("case2: caught IllegalArgumentException.  Message: " + iae.getMessage());
      out.print("</p>");
    }
    Person person = new Person();

    out.print("<h1>");
    out.print("Validating invalid person instance using validate.");
    out.print("</h1>");

    violations = beanValidator.validate(person);

    printConstraintViolations(out, violations, "case3");

    out.print("<h1>");
    out.print("Validating valid person.");
    out.print("</h1>");

    person.setFirstName("John");
    person.setLastName("Yaya");
    person.setListOfString(listOfString);

    violations = beanValidator.validate(person);
    printConstraintViolations(out, violations, "case4");

    out.print("</body></html>");
  }
 @Override
 public <T> Set<ConstraintViolation<T>> validateValue(
     final Class<T> beanType,
     final String propertyName,
     final Object value,
     final Class<?>... groups) {
   return delegate.validateValue(beanType, propertyName, value, groups);
 }
Example #3
0
 /**
  * 数据验证
  *
  * @param type 类型
  * @param property 属性
  * @param value 值
  * @param groups 验证组
  * @return 验证结果
  */
 protected boolean isValid(Class<?> type, String property, Object value, Class<?>... groups) {
   Set<?> constraintViolations = validator.validateValue(type, property, value, groups);
   if (constraintViolations.isEmpty()) {
     return true;
   } else {
     RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
     requestAttributes.setAttribute(
         CONSTRAINT_VIOLATIONS_ATTRIBUTE_NAME,
         constraintViolations,
         RequestAttributes.SCOPE_REQUEST);
     return false;
   }
 }
 @Override
 public void valueChanged(GraphBacked<T> graphBacked, Object oldVal, Object newVal) {
   if (validator == null) return;
   Set<ConstraintViolation<T>> constraintViolations =
       validator.validateValue((Class<T>) entityType, propertyName, newVal);
   if (!constraintViolations.isEmpty())
     throw new ValidationException(
         "Error validating field "
             + propertyName
             + " of "
             + entityType
             + ": "
             + constraintViolations);
 }
Example #5
0
  /**
   * <span class="changed_modified_2_3">Verify</span> that the value is valid according to the Bean
   * Validation constraints. <div class="changed_added_2_0">
   *
   * <p>Obtain a {@link ValidatorFactory} instance by calling {@link
   * javax.validation.Validation#buildDefaultValidatorFactory}.
   *
   * <p>Let <em>validationGroupsArray</em> be a <code>Class []</code> representing validator groups
   * set on the component by the tag handler for this validator. The first search component
   * terminates the search for the validation groups value. If no such value is found use the class
   * name of {@link javax.validation.groups.Default} as the value of the validation groups.
   *
   * <p>Let <em>valueExpression</em> be the return from calling {@link
   * UIComponent#getValueExpression} on the argument <em>component</em>, passing the literal string
   * &#8220;value&#8221; (without the quotes) as an argument. If this application is running in an
   * environment with a Unified EL Implementation for Java EE6 or later, obtain the <code>
   * ValueReference</code> from <em>valueExpression</em> and let <em>valueBaseClase</em> be the
   * return from calling <code>ValueReference.getBase()</code> and <em>valueProperty</em> be the
   * return from calling <code>ValueReference.getProperty()</code>. If an earlier version of the
   * Unified EL is present, use the appropriate methods to inspect <em>valueExpression</em> and
   * derive values for <em>valueBaseClass</em> and <em>valueProperty</em>.
   *
   * <p>If no <code>ValueReference</code> can be obtained, take no action and return.
   *
   * <p>If <code>ValueReference.getBase()</code> return <code>null</code>, take no action and
   * return.
   *
   * <p>Obtain the {@link ValidatorContext} from the {@link ValidatorFactory}.
   *
   * <p>Decorate the {@link MessageInterpolator} returned from {@link
   * ValidatorFactory#getMessageInterpolator} with one that leverages the <code>Locale</code>
   * returned from {@link javax.faces.component.UIViewRoot#getLocale}, and store it in the <code>
   * ValidatorContext</code> using {@link ValidatorContext#messageInterpolator}.
   *
   * <p>Obtain the {@link javax.validation.Validator} instance from the <code>validatorContext
   * </code>.
   *
   * <p>Obtain a <code>javax.validation.BeanDescriptor</code> from the <code>
   * javax.validation.Validator</code>. If <code>hasConstraints()</code> on the <code>BeanDescriptor
   * </code> returns false, take no action and return. Otherwise proceed.
   *
   * <p>Call {@link javax.validation.Validator#validateValue}, passing <em>valueBaseClass</em>,
   * <em>valueProperty</em>, the <em>value</em> argument, and <em>validatorGroupsArray</em> as
   * arguments.
   *
   * <p>If the returned <code>Set&lt;{@link
   * ConstraintViolation}&gt;</code> is non-empty, for each element in the <code>Set</code>, create
   * a {@link FacesMessage} where the summary and detail are the return from calling {@link
   * ConstraintViolation#getMessage}. Capture all such <code>FacesMessage</code> instances into a
   * <code>Collection</code> and pass them to {@link
   * ValidatorException#ValidatorException(java.util.Collection)}. <span
   * class="changed_added_2_3">If the {@link #ENABLE_VALIDATE_WHOLE_BEAN_PARAM_NAME} application
   * parameter is enabled and this {@code Validator} instance has validation groups other than or in
   * addition to the {@code Default} group, record the fact that this field failed validation so
   * that any <code>&lt;f:validateWholeBean /&gt;</code> component later in the tree is able to skip
   * class-level validation for the bean for which this particular field is a property. Regardless
   * of whether or not {@link #ENABLE_VALIDATE_WHOLE_BEAN_PARAM_NAME} is set, throw the new
   * exception.</span>
   *
   * <p class="changed_added_2_3">If the returned {@code Set} is empty, the {@link
   * #ENABLE_VALIDATE_WHOLE_BEAN_PARAM_NAME} application parameter is enabled and this {@code
   * Validator} instance has validation groups other than or in addition to the {@code Default}
   * group, record the fact that this field passed validation so that any <code>
   * &lt;f:validateWholeBean /&gt;</code> component later in the tree is able to allow class-level
   * validation for the bean for which this particular field is a property. </div>
   *
   * @param context {@inheritDoc}
   * @param component {@inheritDoc}
   * @param value {@inheritDoc}
   * @throws ValidatorException {@inheritDoc}
   */
  @Override
  public void validate(FacesContext context, UIComponent component, Object value) {

    if (context == null) {
      throw new NullPointerException();
    }
    if (component == null) {
      throw new NullPointerException();
    }
    ValueExpression valueExpression = component.getValueExpression("value");
    if (valueExpression == null) {
      return;
    }

    ValidatorFactory validatorFactory;
    Object cachedObject =
        context.getExternalContext().getApplicationMap().get(VALIDATOR_FACTORY_KEY);
    if (cachedObject instanceof ValidatorFactory) {
      validatorFactory = (ValidatorFactory) cachedObject;
    } else {
      try {
        validatorFactory = Validation.buildDefaultValidatorFactory();
      } catch (ValidationException e) {
        throw new FacesException("Could not build a default Bean Validator factory", e);
      }
      context.getExternalContext().getApplicationMap().put(VALIDATOR_FACTORY_KEY, validatorFactory);
    }

    ValidatorContext validatorContext = validatorFactory.usingContext();
    MessageInterpolator jsfMessageInterpolator =
        new JsfAwareMessageInterpolator(context, validatorFactory.getMessageInterpolator());
    validatorContext.messageInterpolator(jsfMessageInterpolator);
    javax.validation.Validator beanValidator = validatorContext.getValidator();
    Class[] validationGroupsArray = parseValidationGroups(getValidationGroups());

    // PENDING(rlubke, driscoll): When EL 1.3 is present, we won't need
    // this.

    ValueExpressionAnalyzer expressionAnalyzer = new ValueExpressionAnalyzer(valueExpression);

    ValueReference valueReference = expressionAnalyzer.getReference(context.getELContext());
    if (valueReference == null) {
      return;
    }
    if (isResolvable(valueReference, valueExpression)) {
      Set<ConstraintViolation<?>> violations = null;
      try {
        //noinspection unchecked
        violations =
            beanValidator.validateValue(
                valueReference.getBaseClass(),
                valueReference.getProperty(),
                value,
                validationGroupsArray);
      } catch (IllegalArgumentException iae) {
        String failureMessage =
            "Unable to validate expression "
                + valueExpression.getExpressionString()
                + " using Bean Validation.  Unable to get value of expression. "
                + " Message from Bean Validation: "
                + iae.getMessage();
        LOGGER.fine(failureMessage);
      }

      if (violations != null && !violations.isEmpty()) {
        ValidatorException toThrow;
        if (1 == violations.size()) {
          ConstraintViolation violation = violations.iterator().next();
          toThrow =
              new ValidatorException(
                  MessageFactory.getMessage(
                      context,
                      MESSAGE_ID,
                      violation.getMessage(),
                      MessageFactory.getLabel(context, component)));
        } else {
          Set<FacesMessage> messages = new LinkedHashSet<>(violations.size());
          for (ConstraintViolation violation : violations) {
            messages.add(
                MessageFactory.getMessage(
                    context,
                    MESSAGE_ID,
                    violation.getMessage(),
                    MessageFactory.getLabel(context, component)));
          }
          toThrow = new ValidatorException(messages);
        }

        // Record the fact that this field failed validation, so that multi-field
        // validation is not attempted.
        if (MultiFieldValidationUtils.wholeBeanValidationEnabled(context, validationGroupsArray)) {
          Map<Object, Map<String, Map<String, Object>>> multiFieldCandidates =
              MultiFieldValidationUtils.getMultiFieldValidationCandidates(context, true);
          Object val = valueReference.getBase();
          Map<String, Map<String, Object>> candidate =
              multiFieldCandidates.getOrDefault(val, new HashMap<>());
          Map<String, Object> tuple = new HashMap<>();
          tuple.put("component", component);
          tuple.put("value", FAILED_FIELD_LEVEL_VALIDATION);
          candidate.put(valueReference.getProperty(), tuple);
          multiFieldCandidates.putIfAbsent(val, candidate);
        }

        throw toThrow;
      }
    }

    // Record the fact that this field passed validation, so that multi-field
    // validation can be performed if desired
    if (MultiFieldValidationUtils.wholeBeanValidationEnabled(context, validationGroupsArray)) {
      Map<Object, Map<String, Map<String, Object>>> multiFieldCandidates =
          MultiFieldValidationUtils.getMultiFieldValidationCandidates(context, true);
      Object val = valueReference.getBase();
      Map<String, Map<String, Object>> candidate =
          multiFieldCandidates.getOrDefault(val, new HashMap<>());
      Map<String, Object> tuple =
          new HashMap<>(); // new ComponentValueTuple((EditableValueHolder) component, value);
      tuple.put("component", component);
      tuple.put("value", value);
      candidate.put(valueReference.getProperty(), tuple);
      multiFieldCandidates.putIfAbsent(val, candidate);
    }
  }
 @Test
 public void shouldUnwrapPropertyValuesDuringValueValidation() {
   Set<ConstraintViolation<Customer>> violations =
       validator.validateValue(Customer.class, "name", new StringProperty("Bob"));
   assertEquals(violations.size(), 1);
 }
 @Override
 public <T> Set<ConstraintViolation<T>> validateValue(
     Class<T> beanType, String propertyName, Object value, Class<?>... groups) {
   return validator.validateValue(beanType, propertyName, value, groups);
 }