{"id":22707599,"url":"https://github.com/xvik/guice-validator","last_synced_at":"2025-04-13T12:34:24.055Z","repository":{"id":38432760,"uuid":"21138704","full_name":"xvik/guice-validator","owner":"xvik","description":"Guice javax.validation method validation integration","archived":false,"fork":false,"pushed_at":"2025-02-04T04:13:56.000Z","size":536,"stargazers_count":37,"open_issues_count":5,"forks_count":8,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-03-27T03:35:15.392Z","etag":null,"topics":["guice","java","validator"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xvik.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-06-23T19:08:24.000Z","updated_at":"2025-02-04T04:13:53.000Z","dependencies_parsed_at":"2023-11-18T06:24:45.346Z","dependency_job_id":"9976bf44-5fcd-4144-9a78-e42186c58568","html_url":"https://github.com/xvik/guice-validator","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xvik%2Fguice-validator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xvik%2Fguice-validator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xvik%2Fguice-validator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xvik%2Fguice-validator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xvik","download_url":"https://codeload.github.com/xvik/guice-validator/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248714650,"owners_count":21149931,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["guice","java","validator"],"created_at":"2024-12-10T10:13:31.574Z","updated_at":"2025-04-13T12:34:24.030Z","avatar_url":"https://github.com/xvik.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Guice validator\n[![License](http://img.shields.io/badge/license-MIT-blue.svg)](http://www.opensource.org/licenses/MIT)\n[![CI](https://github.com/xvik/guice-validator/actions/workflows/CI.yml/badge.svg)](https://github.com/xvik/guice-validator/actions/workflows/CI.yml)\n[![Appveyor build status](https://ci.appveyor.com/api/projects/status/github/xvik/guice-validator?svg=true\u0026branch=master)](https://ci.appveyor.com/project/xvik/guice-validator)\n[![codecov](https://codecov.io/gh/xvik/guice-validator/branch/master/graph/badge.svg)](https://codecov.io/gh/xvik/guice-validator)\n\nSupport: [gitter chat](https://gitter.im/xvik/guice-validator)\n\n### About\n\nValidates service method parameters and return value using jakarta.validation 3.0 (the difference with 2.0 is only in api package) annotations.\nUsed with [hibernate-validator](http://hibernate.org/validator/) (currently, the only [certified implementation](https://beanvalidation.org/2.0/)).\n\nFeatures:\n\n* Service method call parameters and return value validation\n* Explicit and implicit validation modes (driven by additional annotation or directly by validation annotations)\n* Guice injections work in custom validators\n* Validation groups support (as context, like transactional calls)\n\nFor guice 5 (and 4) and java 8 (binary compatible with java 11)\n\n[Old version 1.2.0 docs](https://github.com/xvik/guice-validator/tree/1.2.0)\n\n### Important!\n\nSince Java EE 9 `javax.validation` was renamed to `jakarta.validation` and *Bean Validation* become 3.0.\n[Hibernate-validator 7.0 targets new package](https://in.relation.to/2021/01/06/hibernate-validator-700-62-final-released/).\n\nCurrent guice-validator (3.x) targets hibernate 7 (and `jakarta.validation`), but if you still\nuse hibernate-validator 6 (and `javax.validation`) then use previous version: \n\nVersion | Target\n----|----\nguice validator 3.x | Hibernate-validator 7, for `jakarta.validation`\n[guice-validator 2.x](https://github.com/xvik/guice-validator/tree/2.0.1) | Hibernate-validator 6.x, for `javax.validation` \n\n### Migration\n\nIf you migrating from hibernate-validator 6.x then change dependencies:\n\nBefore |  After\n---- | ------\nru.vyarus:guice-validator:2.0.1 | ru.vyarus:guice-validator:3.0.1\njavax.validation:validation-api:2.0.1.Final | jakarta.validation:jakarta.validation-api:3.0.0\norg.hibernate:hibernate-validator:6.2.0.Final|  org.hibernate:hibernate-validator:7.0.1.Final\norg.glassfish:javax.el:3.0.1-b12 |  org.glassfish:jakarta.el:4.0.2\n\nAnd rename `javax.validation` package to `jakarta.validation` everywhere. Everything else is the same.\n\n### Setup\n\n[![Maven Central](https://img.shields.io/maven-central/v/ru.vyarus/guice-validator.svg?style=flat)](https://maven-badges.herokuapp.com/maven-central/ru.vyarus/guice-validator)\n\nMaven:\n\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003eru.vyarus\u003c/groupId\u003e\n  \u003cartifactId\u003eguice-validator\u003c/artifactId\u003e\n  \u003cversion\u003e3.0.2\u003c/version\u003e\n\u003c/dependency\u003e\n\u003cdependency\u003e\n  \u003cgroupId\u003eorg.hibernate\u003c/groupId\u003e\n  \u003cartifactId\u003ehibernate-validator\u003c/artifactId\u003e\n  \u003cversion\u003e7.0.1.Final\u003c/version\u003e\n\u003c/dependency\u003e\n\u003cdependency\u003e\n  \u003cgroupId\u003eorg.glassfish\u003c/groupId\u003e\n  \u003cartifactId\u003ejakarta.el\u003c/artifactId\u003e\n  \u003cversion\u003e4.0.2\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nGradle:\n\n```groovy\nimplementation 'ru.vyarus:guice-validator:3.0.2'\nimplementation 'org.hibernate:hibernate-validator:7.0.1.Final'\nimplementation 'org.glassfish:jakarta.el:4.0.2'\n```\n\n#### Snapshots\n\nSnapshots could be used through JitPack:\n\n* Go to [JitPack project page](https://jitpack.io/#ru.vyarus/guice-validator)\n* Select `Commits` section and click `Get it` on commit you want to use (you may need to wait while version builds if no one requested it before)\n* Follow displayed instruction: \n    - Add jitpack repository: `maven { url 'https://jitpack.io' }`\n    - Use commit hash as version: `ru.vyarus:guice-validator:6933889d41`\n\n\n### Usage\n\nInstall module:\n\n```java\ninstall(new ValidationModule())\n```\n\n#### Implicit                     \n\nBy default, will work in \"implicit mode\": matching all methods with `@Valid` or `Constraint` (all validation \nannotations are annotated with `@Constraint` and so easy to recognize) annotations.\n\nFor example, \n\n```java\npublic class SomeService {\n    public SimpleBean beanRequired(@NotNull SimpleBean bean) {}\n} \n```\n\nWill throw `ConstraintViolationException` exception if called as: \n\n```java\nservice.beanRequired(null)\n```\n\nIf return value must be validated, method must contain `@Valid` or `Constraint` annotation:\n\n```java\n@NotNull\npublic SimpleBean beanRequired(SimpleBean bean) {\n    return null;\n}\n```     \n\nWill throw `ConstraintViolationException` exception when called (due to returned null).\n\n#### Explicit\n\nExplicit mode may be used if you need to manually control validated methods:\n\n```java\ninstall(new ValidationModule().validateAnnotatedOnly())\n```\n\nThis way only methods directly annotated with `@ValidateOnExecution` or methods inside annotated class\nwill trigger validation.\n\nFor example:\n\n```java\n@ValidateOnExecution \npublic class SampleService {\n    public void method1() {}\n    public void method2() {}\n}\n```\n\nBoth methods will trigger validation. \n\nNote that in contrast to implicit mode, existence of constraint annotations is not checked\n(simply nothing will happen on validation it not annotated, but validation will be called).\n\nAnd for method:\n\n```java\npublic class SampleService {\n    \n    @ValidateOnExecution\n    public void method1() {}\n\n    public void method2() {}\n}\n```\n\nNow only `method1` will trigger validation.\n\nNOTE: javadoc of `@ValidateOnExecution` contradicts with such usage, but its name is ideal for such usage\n(no need to introduce more annotations).\n\nIn case if you don't like default annotation, you can use your own:\n\n```java\ninstall(new ValidationModule().validateAnnotatedOnly(ToValidate.class))\n```\n\nNOTE Hibernate-validator provides annotation processor to perform additional checks in compile time: [see docs](https://docs.jboss.org/hibernate/validator/6.0/reference/en-US/html_single/#validator-annotation-processor)\nIn this case explicit mode could be used to differentiate compile time-only annotations from \nruntime checks (only methods annotated with `@ValidateOnExecution` will be validated at runtime).\n\n#### Validation factory\n\nIf you use custom validation factory then specify it directly:\n\n```java\ninstall(new ValidationModule(yourValidationFactory));\n```\n\nNOTE: even with custom validation factory, custom `ConstraintValidatorFactory` will be used\nin order to be able to wire injections inside custom validators.\n\nThis also means that validator obtained directly from your validator factory and \nvalidator actually used in guice will be different: directly obtained validator will not be able\nto inject guice dependencies.\n\n#### Reducing scope\n\nYou can specify additional class and method matchers to exclude classes or methods from \nvalidation triggering. This works in both implicit and explicit modes.\n\nFor example, introduce custom annotation to manually disable validations:\n\n```java\n@Target({ElementType.TYPE, ElementType.METHOD})\n@Retention(RetentionPolicy.RUNTIME)\npublic @interface SuppressValidation {} \n```\n\n```java\ninstall(new ValidationModule()\n        .targetClasses(Matchers.not(Matchers.annotatedWith(SuppressValidation.class)))\n        .targetMethods(Matchers.not(Matchers.annotatedWith(SuppressValidation.class))));\n```\n\nNow any annotated nethod (or all methods in annotated class) will not trigger validation:\n\n```java\npublic class SampleService {    \n    @SuppressValidation\n    public void method(@NotNull String arg) {}\n}\n```    \n\n### Bound objects\n\nBoth modules bind extra objects to context (available for injection) :\n\n* `jakarta.validation.Validator`\n* `jakarta.validation.executable.ExecutableValidator`\n* `jakarta.validation.ValidatorFactory`\n* `ru.vyarus.guice.validator.group.ValidationContext`\n\nFor example, `@Inject Validator validator` may be useful for manual object validations.\n\nNOTE: don't use `ValidatorFactory` directly, because it is not aware of guice and so \nwill not be able to wire guice injections into custom validators.    \n\n\n### Examples\n\n##### Object state\n\nIf parameter or returned object contains validation annotations, and it must be checked before/after method execution,\nadd `@Valid` annotation.\n\n```java\npublic SimpleBean beanRequired(@NotNull @Valid SimpleBean bean) \n```\n\n`@Valid` used on method means validation of returned object:\n\n```java\n@Valid @NotNull\npublic SimpleBean validReturn(SimpleBean bean)\n```\n\n[Full example](https://github.com/xvik/guice-validator/tree/master/src/test/java/ru/vyarus/guice/validator/simple)\n\n##### Annotations composition\n\nIf you often declare multiple annotations, then it could be simplier to introduce new \ncomposite validation.\n\nFor example, here is composition of `@NotNull` and `@Size(min = 2, max = 14)`:  \n\n```java\n@NotNull\n@Size(min = 2, max = 14)\n@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.PARAMETER})\n@Retention(RetentionPolicy.RUNTIME)\n@Constraint(validatedBy = {})\n@Documented\n@ReportAsSingleViolation //optional\npublic @interface ComposedCheck {\n    String message() default \"Composed check failed\";\n\n    Class\u003c?\u003e[] groups() default {};\n\n    Class\u003c? extends Payload\u003e[] payload() default {};\n}\n```     \n\n```java\npublic String checkParam(@ComposedCheck String string) {}\n```   \n\n* [Full example](https://github.com/xvik/guice-validator/tree/master/src/test/java/ru/vyarus/guice/validator/compositeannotation)\n\n##### Cross parameters check\n\nIf it is important to validate method parameters \"together\", then custom validator have to be declared:\n\n```java\n@SupportedValidationTarget(ValidationTarget.PARAMETERS)\npublic class CrossParamsValidator implements ConstraintValidator\u003cCrossParamsCheck, Object[]\u003e {\n\n    @Override\n    public void initialize(CrossParamsCheck constraintAnnotation) {}\n\n    @Override\n    public boolean isValid(Object[] value, ConstraintValidatorContext context) {\n        Integer param1 = (Integer) value[0];\n        Object param2 = value[1];\n        return param1 != null \u0026\u0026 param1 == 1 \u0026\u0026 param2 instanceof Integer;\n    }\n}\n```  \n\nValidation annotation:\n\n```java\n@Constraint(validatedBy = CrossParamsValidator.class)\n@Target({ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.ANNOTATION_TYPE })\n@Retention(RetentionPolicy.RUNTIME)\n@Documented\npublic @interface CrossParamsCheck {\n    String message() default \"Parameters are not valid\";\n\n    Class\u003c?\u003e[] groups() default { };\n\n    Class\u003c? extends Payload\u003e[] payload() default { };\n}\n```\n\nAnd now, it may be used to validated method parameters:\n\n```java\n@CrossParamsCheck\npublic void action(Integer param1, Object param2) {}\n```\n\n[Hibernate docs](https://docs.jboss.org/hibernate/validator/6.0/reference/en-US/html_single/#example-using-cross-parameter-constraint)\n\n[Full example](https://github.com/xvik/guice-validator/tree/master/src/test/java/ru/vyarus/guice/validator/crossparams)\n\n##### Scripted check\n\nBean level validation:\n\n```java\n@ScriptAssert(lang = \"javascript\", script = \"it.start.before(it.finish)\", alias = \"it\")\npublic class ScriptedBean {\n\n    private Date start;\n    private Date finish;\n    ...\n}\n```\n\nValidation could be triggered by `@Valid`:\n\n```java\npublic void method(@Valid ScriptedBean bean) {}\n```\n\nParameter level check:\n\n```java\n@ParameterScriptAssert(lang = \"javascript\", script = \"arg0.size() == arg1\")\npublic void paramsValid(List\u003cInteger\u003e list, int count) {}\n```\n\n[Hibernate docs](https://docs.jboss.org/hibernate/validator/6.0/reference/en-US/html_single/#section-builtin-method-constraints)\n\n[Full example](https://github.com/xvik/guice-validator/tree/master/src/test/java/ru/vyarus/guice/validator/script)\n\n### Custom validator\n\nGuice injections could be used when writing custom validators\n\n```java\npublic class ComplexBeanValidator implements ConstraintValidator\u003cComplexBeanValid, ComplexBean\u003e {\n\n    @Inject\n    private CustomService customService;\n\n    @Override\n    public void initialize(ComplexBeanValid constraintAnnotation) {\n        /* if annotation contains addition parameter it must be parsed here.. skipping for simplicity.\n          NOTE: in such simple case we can make validator singleton, because of no internal state */\n    }\n\n    @Override\n    public boolean isValid(ComplexBean value, ConstraintValidatorContext context) {\n        /* common convention is to treat null values as valid and explicitly check them with @NotNull */\n        return value == null || customService.getRequiredValue().equals(value.getUser());\n    }\n}\n\n@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})\n@Retention(RetentionPolicy.RUNTIME)\n@Constraint(validatedBy = {ComplexBeanValidator.class})\n@Documented\npublic @interface ComplexBeanValid {\n    /* ideally there should be just localization key, but for simplicity just message */\n    String message() default \"Bean is not valid\";\n\n    Class\u003c?\u003e[] groups() default {};\n\n    Class\u003c? extends Payload\u003e[] payload() default {};\n}\n```\n\n[Full example](https://github.com/xvik/guice-validator/tree/master/src/test/java/ru/vyarus/guice/validator/customtype)\n\n### Limitations\n\nGuice aop is applied only for objects constructed by guice, so validation will not work for types\nbound by instance:\n\n```java\nbind(MyType.class).toInstance(new MyType());\n```\n\n### Validation context\n\n[Validation groups](https://docs.jboss.org/hibernate/validator/6.0/reference/en-US/html_single/#chapter-groups) \ncould be used to apply different validations for the same object (or same method).\n\nFor example, we have model class with 2 validation groups\n```java\npublic class MyModel {\n    @NotNull\n    private String defField;\n    @NotNull(group = Group1.class)\n    private String group1Field;\n    @NotNull(group = Group2.class)\n    private String group2Field;\n}   \n```\n\nNote that Group1 and Group2 could be any classes or interfaces (it doesn't matter, because they simply define group by type).\n\nIf we use model in method like this:\n\n```java\npublic class MyService {\n    public void do(@Valid MyModel model) {...}\n}\n```\n\nOnly `defField` will be validated (because it implicitly belongs to default (`Default`) group).\n\n#### Groups annotation\n\nIn order to enable other groups use `@ValidationGroups` annotation.\n\nFor example,\n\n```java\n@ValidationGroups(Group1.class)\npublic void do(@Valid MyModel mode); {...}\n```\n\nThis enables `Group1` so `defField` and `group1Field` will be validated (default group included by default, but can be disabled (read below)).\n\nAnnotation could define more then one group: \n\n```java\n@ValidationGroups({Group1.class, Group2.class})\n```\n\nAnnotation may be used on class to affect all methods. Also, see advanced annotations usage below.\n\n#### Understanding context\n\n`@ValidationGroups` annotation affects not just one method, but all methods executed by this method or any subsequent method (in the same thread!).\nWe can say that annotation creates *validation context*.\n\nSuppose we have service without context:\n\n```java\npublic class MyService {\n    public void do(@Valid MyModel mode); {...}\n}\n```\n\nDefining upper level service with context:\n\n```java\n@ValidationGroups(Group1.class)\npublic class MyGroup1Service {\n    @Inject\n    private MyService service;\n    \n    public void foo(MyModel model) {\n        service.do(model);\n    }\n}\n```\n\nValidation context is defined for all methods in service (and all subsequent calls). \nSo when `foo` method call `service.do` method, validation context would be already defined and actual validation\nwould be performed with default and Group1 groups.\n\nThe same way, some other upper level service could define different groups. So upper levels define general validation context,\nwhile lower levels stay generic and re-usable.\n\nOverall, validation context works very much like `@Transactional` in guice-persist or spring.\n\n##### Context composition\n\nIn situation like this:\n\n```java\npublic class RootService {\n    @Inject\n    private MyGroup1Service service;\n    \n    @ValidationGroups(Group2.class)\n    public void bar(MyModel model) {\n        service.foo(model);\n    }\n}\n```\n\n* Method `RootService.bar` is under {`Group2`} context\n* Subsequent method `MyGroup1Service.foo` is under {`Group1`} context\n* (Sub)Subsequent `method MyService.do` performs validation\n\nBoth contexts will compose (merge) and last method will be called with default, Group1 and Group2 groups.\n\n##### Composition rules\n\nIf `@ValidationGroups` annotation defined both on type and method, then actual method context will use groups from both annotations.\n\nSubsequent validation contexts inherit all groups from upper context.\n\n##### Manual context definition\n\nValidation context could be defined manually, by using `ru.vyarus.guice.validator.group.ValidationContext` singleton:\n\n```java\npublic class ManualContextDemo {\n    @Inject\n    private ValidationContext context;\n    \n    public void foo() {\n        context.doWithGroups(new GroupAction\u003cVoid\u003e(){\n            public Void call() throws Throwable {\n                // all methods called here will be validated with specified groups\n                // this is equivalent to method annotation @ValidationGroups({Group1.class, Group10.class})\n            }\n        }, Group1.class, Group10.class)\n    }\n}\n```\n\n#### Default group specifics\n\nDefault behaviour is to always use default group. So when you define validation context with groups {Group1, Group2}, \nactual context would be {Group1, Group2, Default}. This was done in order to provide more intuitive behavior:\nvalidation context extends default validation scope.\n\nIf you want to prevent this behavior use `strictGroupsDeclaration` module option:\n\n```java\nnew ValidationModule().strictGroupsDeclaration()\n```\n\nExplicit module has the same option. If you disable default group addition, then default validations (annotations\nwhere you didn't specify group) will not be used, unless you specify Default group manually in validation context.\n\n#### Advanced annotations usage\n\nIn some cases it makes sense to use your own annotations for context definition, e.g.:\n* Because they are more descriptive in code\n* You want to group multiple groups (the same way as you can group multiple validations in jakarta validation).\n\nDue to the fact that any class could be used for group name, we can use our new annotation class itself as group name.\n\nFor example (example taken from [hibernate-validator docs](https://docs.jboss.org/hibernate/validator/7.0/reference/en-US/html_single/#chapter-groups)):\n```java\npublic class Person {\n    @NotNull\n    private String name;\n    @AssertTrue(group = DriverContext.class)\n    private boolean driverLicense;\n}\n```\n\nWe used annotation class as group name.\n\n```java\n@Target({TYPE, METHOD})\n@Retention(RetentionPolicy.RUNTIME)\n@ValidationGroups(DriverScope.class)\npublic @interface DriverScope {\n}\n```\n\nNote that annotation is annotated by `@ValidationGroups(DriverScope.class)`.\n\nGroups interceptor implementation is able to find such annotated annotations and use `@ValidationGroups` defined on them.\n\nSo in service you could simply use your annotation:\n\n```java\n@DriverContext\npublic class DriverService {\n    ...\n}\n```\n\nAll method called by driver service will be validated with `DriverContext` group.\n\nIf you don't like the idea of using annotations as validation groups, then you can still use your own annotations just\nfor grouping. For example:\n\n```java\n@Target({TYPE, METHOD})\n@Retention(RetentionPolicy.RUNTIME)\n@ValidationGroups({Group1.class, Group10.class})\npublic @interface MyCustomScope {\n}\n```\n\n#### Cache\n\nIn order to avoid `ValidationGroups` annotations lookup for each method call, resolution result is cached on first execution inside\n`ru.vyarus.guice.validator.group.annotation.MethodGroupsFactory`.\n\nIf you use JRebel or other class reloading tool (maybe some other reason) you will need to disable descriptors caching.\n\nTo do it set system property or environment variable:\n\n```\nru.vyarus.guice.validator.group.annotation.MethodGroupsFactory.cache=false\n```\n\nOr from code:\n\n```java\nMethodGroupsFactory.disableCache();\n```\n\nAlso, you can clear cache manually (on instance):\n\n```java\ninjector.getInstance(MethodGroupsFactory.class).clearCache()\n```\n\n### More\n\nMore examples could be found in tests.\n\nAlso, read hibernate-validator docs:\n\n* [Constraints](https://docs.jboss.org/hibernate/validator/6.0/reference/en-US/html_single/#section-declaring-bean-constraints)\n* [Declaration](https://docs.jboss.org/hibernate/validator/6.0/reference/en-US/html_single/#chapter-method-constraints)\n* [Validation factory configuration](https://docs.jboss.org/hibernate/validator/6.0/reference/en-US/html_single/#chapter-bootstrapping)\n\n### Supplement\n\n[validator-collection](https://github.com/jirutka/validator-collection) annotations to validate collections of simple types\n\n---\n[![java lib generator](http://img.shields.io/badge/Powered%20by-%20Java%20lib%20generator-green.svg?style=flat-square)](https://github.com/xvik/generator-lib-java)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxvik%2Fguice-validator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxvik%2Fguice-validator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxvik%2Fguice-validator/lists"}