Skip to content

User Guide

Markus Hager edited this page Jun 11, 2018 · 5 revisions

Using this guide you should be able to use the validation within just some minutes.

Maven Dependency

see Quick-Start

Structure

In the package at.meks.validation.validations are a package for validations for each java type. E.g. you'll find

  • date
  • list
  • number
  • string
  • common

The package common contains validations for the type Object.

In each of the packges you find 2 classes for your use:

  • *Validations and
  • *ValidationsWithErrorCode

If you need an error code in you validation result you should use the classes *ValidationsWithErrorCode. In both classes you find the same validations. The only difference is that in one class you can provide an error code and in the other class you can not.

Examples

Some of the examples can also be found in the maven module easy-validations-examples.

Simple Usage

Simple use cases can be found in the Quick Start.

custom messages

If you want to provide your own messages you just have to provide you own translation(resource bundl) in the directory at/meks/validation with the base name errors.

other languages than english and german

If you need another language for the error messages you just have to provide the language the the resource bundle in the directory at/meks/validation with the base name errors.

custom validations - Goal: extendable by custom validations without the need of forking this repo

Feel free to implement you own validation rules. You can either just implement them and use it, or you can fork the project. I would love to get new validations from you.

Let's assume you need a validation for your custom complex object person which validates that a persons job is beeing a police officer for at least 20 months.

import at.meks.validation.Validation;

import static at.meks.validation.SimpleValidation.from;
import static at.meks.validation.result.ErrorDescriptionBuilder.withMessage;
import static java.lang.String.format;

public class PersonValidations {

    static Validation<Person> isPoliceOfficer() {
        return from(person -> person.getProfession().equals("police officer"),
                () -> withMessage("must be a police officer"));
    }

    static Validation<Person> monthsInProfessionIsMoreThan(int minimumMonths) {
        return from(person -> person.getActiveMonthsInProfession() > minimumMonths,
                () -> withMessage(format("must be active in his profession for at least %s months", minimumMonths)));
    }

}

Using this implementation now you can use it like this:

import at.meks.validation.result.ValidationException;

import static at.meks.validation.customvalidations.PersonValidations.isPoliceOfficer;
import static at.meks.validation.customvalidations.PersonValidations.monthsInProfessionIsMoreThan;

public class MyPersonService {
    
    public void validateForTrusablePoliceOfficer(Person person) throws ValidationException {
        isPoliceOfficer().and(monthsInProfessionIsMoreThan(20)).test(person).throwIfInvalid("person");
    }
}

In this case for sure it wouldn't be necessary to implement your own rules. You could use the onboard rules to validate those things:

import at.meks.validation.result.ValidationException;

import static at.meks.validation.validations.common.CommonValidations.isEqualTo;
import static at.meks.validation.validations.common.CommonValidations.isGreaterThan;

public class MyPersonService {

    public void validateForTrusablePoliceOfficer(Person person) throws ValidationException {
        isEqualTo("police officer").test(person.getProfession()).throwIfInvalid("profession");
        isGreaterThan(20).test(person.getActiveMonthsInProfession()).throwIfInvalid("actice months in profession");
    }
}

Validation result - Goal: fail fast on error

The validation result is of type ValidationResult. You have the possibility either to do whatever you want with the validation, or simply let it throw an exception

//put the validation result to a list
validationResults.add(isNumeric().test("notNumericString"));
// or let it throw an error
isNumeric().test("notNumericString").throwIfInvalid("propertyDescription");

Setup once, execute it many times for different objects

In the case performance is an issue and you have to do the validation for million of objects you can setup the validations once and just invoke the test method many times, maybe threaded. Assume you get a file with millions of persons which you have to persist in your system if the validation doesn't fail.

public class PersonCreationValidator {
    private Validation<String> passwordValidation;
    private Validation<String> birthdaytValidation;
    private Validation<String> cityValidation;
    private Validation<String> postalCodeValidation;
    //and many more validations
    
    public PersonValidator() {
        setupValidation();
    }
    
    private void setupValidation() {
        passwordValidation = isNotBlank().and(containsDigits()).and(containsChars()).and(lengthIsMoreThan(12))
            .and(lengthIsLessThan(25));
        birthdaytValidation = isNotBank().and(isDate())
            .and(DateParser::parseDate, isGreaterThan(LocalDate.of(1,1, 1970)));
        cityValidation = isNotBlank().and(isValidCity());
        postalCodeValidation = isNotBlank().and(isValidPostalCode());
        //and so on
    }
    
    public void validate(PersonInput input) throws ValidationException {
        passwordValidation.test(input.getPassword());
        birthdaytValidation.test(input.getBirthday());
        cityValidation.test(input.getCity());
        postalCodeValidation.test(input.getPosalCode());
        // and so on
    }
}

Using error codes

All validations exist 2 times. Once as you have seen in the other examples, and once with the possibility to set an error code. E.g. the class StringValidations contains the same validations as StringValidationsWithErrorCode, but without the possibility to define an error code.

How to use it?

isNotBlank("000001").and(isNumeric("000002")).and(Integer::parseInt, isGreaterThan(15, "000003"));

For this example static imports of StringValidationsWithErrorCode and CommonValidationsWithErrorCode are used.