Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9f2b752

Browse files
committed
Add a validator based on the Bean Validation API
Resolves BATCH-2690
1 parent 84d349e commit 9f2b752

File tree

8 files changed

+444
-1
lines changed

8 files changed

+444
-1
lines changed

build.gradle

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ allprojects {
7272
h2databaseVersion = '1.4.196'
7373
hibernateVersion = '5.2.12.Final'
7474
hibernateValidatorVersion = '6.0.4.Final'
75+
javaxElVersion = '3.0.0'
7576
hsqldbVersion = '2.4.0'
7677
jackson2Version = '2.9.2'
7778
gsonVersion = '2.8.5'
@@ -322,7 +323,8 @@ project('spring-batch-infrastructure') {
322323
testRuntime "com.sun.mail:javax.mail:$javaMailVersion"
323324
testRuntime "org.codehaus.groovy:groovy-jsr223:$groovyVersion"
324325
testRuntime "org.jruby:jruby:$jrubyVersion"
325-
326+
testRuntime "org.hibernate.validator:hibernate-validator:$hibernateValidatorVersion"
327+
testRuntime "org.glassfish:javax.el:$javaxElVersion"
326328
testRuntime "org.beanshell:bsh:$beanshellVersion"
327329

328330
optional "javax.jms:javax.jms-api:$jmsVersion"
@@ -604,6 +606,8 @@ project('spring-batch-samples') {
604606
testCompile "org.apache.activemq:activemq-kahadb-store:$activemqVersion"
605607

606608
testRuntime "com.sun.mail:javax.mail:$javaMailVersion"
609+
testRuntime "org.hibernate.validator:hibernate-validator:$hibernateValidatorVersion"
610+
testRuntime "org.glassfish:javax.el:$javaxElVersion"
607611

608612
provided "mysql:mysql-connector-java:$mysqlVersion"
609613
provided "com.h2database:h2:$h2databaseVersion"

spring-batch-docs/asciidoc/readersAndWriters.adoc

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2659,6 +2659,45 @@ public SpringValidator validator() {
26592659
}
26602660
----
26612661

2662+
You can also use the `BeanValidatingItemProcessor` to validate items annotated with
2663+
the Bean Validation API (JSR-303) annotations. For example, given the following type `Person`:
2664+
2665+
[source, java]
2666+
----
2667+
class Person {
2668+
2669+
@NotEmpty
2670+
private String name;
2671+
2672+
public Person(String name) {
2673+
this.name = name;
2674+
}
2675+
2676+
public String getName() {
2677+
return name;
2678+
}
2679+
2680+
public void setName(String name) {
2681+
this.name = name;
2682+
}
2683+
2684+
}
2685+
----
2686+
2687+
you can validate items by declaring a `BeanValidatingItemProcessor` bean in your
2688+
application context and register it as a processor in your chunk-oriented step:
2689+
2690+
[source, java]
2691+
----
2692+
@Bean
2693+
public BeanValidatingItemProcessor<Person> beanValidatingItemProcessor() throws Exception {
2694+
BeanValidatingItemProcessor<Person> beanValidatingItemProcessor = new BeanValidatingItemProcessor<>();
2695+
beanValidatingItemProcessor.setFilter(true);
2696+
2697+
return beanValidatingItemProcessor;
2698+
}
2699+
----
2700+
26622701
[[process-indicator]]
26632702
=== Preventing State Persistence
26642703

spring-batch-docs/asciidoc/whatsnew.adoc

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ The Spring Batch 4.1 release adds the following features:
1111
* A new `@SpringBatchTest` annotation to simplify testing batch components
1212
* A new `@EnableBatchIntegration` annotation to simplify remote chunking configuration
1313
* A new `JsonItemReader` and `JsonFileItemWriter` to support the JSON format
14+
* Add support for validating items with the Bean Validation API
1415

1516
[[whatsNewTesting]]
1617
=== `@SpringBatchTest` Annotation
@@ -160,3 +161,47 @@ Writing JSON data is also supported through the `JsonFileItemWriter`.
160161
For more details about JSON support, see the
161162
<<readersAndWriters.adoc#jsonReadingWriting,ItemReaders and ItemWriters>> chapter.
162163

164+
[[whatsNewBeanValidationApi]]
165+
=== Bean Validation API support
166+
167+
This release brings a new `ValidatingItemProcessor` implementation called
168+
`BeanValidatingItemProcessor` which allows you to validate items annotated with
169+
the Bean Validation API (JSR-303) annotations. For example, given the following
170+
type `Person`:
171+
172+
[source, java]
173+
----
174+
class Person {
175+
176+
@NotEmpty
177+
private String name;
178+
179+
public Person(String name) {
180+
this.name = name;
181+
}
182+
183+
public String getName() {
184+
return name;
185+
}
186+
187+
public void setName(String name) {
188+
this.name = name;
189+
}
190+
191+
}
192+
----
193+
194+
you can validate items by declaring a `BeanValidatingItemProcessor` bean in your
195+
application context and register it as a processor in your chunk-oriented step:
196+
197+
[source, java]
198+
----
199+
@Bean
200+
public BeanValidatingItemProcessor<Person> beanValidatingItemProcessor() throws Exception {
201+
BeanValidatingItemProcessor<Person> beanValidatingItemProcessor = new BeanValidatingItemProcessor<>();
202+
beanValidatingItemProcessor.setFilter(true);
203+
204+
return beanValidatingItemProcessor;
205+
}
206+
----
207+
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright 2018 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.batch.item.validator;
18+
19+
import javax.validation.Validator;
20+
21+
import org.apache.shiro.util.Assert;
22+
23+
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
24+
import org.springframework.validation.beanvalidation.SpringValidatorAdapter;
25+
26+
/**
27+
* A {@link ValidatingItemProcessor} that uses the Bean Validation API (JSR-303)
28+
* to validate items.
29+
*
30+
* @param <T> type of items to validate
31+
* @author Mahmoud Ben Hassine
32+
* @since 4.1
33+
*/
34+
public class BeanValidatingItemProcessor<T> extends ValidatingItemProcessor<T> {
35+
36+
private Validator validator;
37+
38+
/**
39+
* Create a new instance of {@link BeanValidatingItemProcessor} with the
40+
* default configuration.
41+
*/
42+
public BeanValidatingItemProcessor() {
43+
LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean();
44+
localValidatorFactoryBean.afterPropertiesSet();
45+
this.validator = localValidatorFactoryBean.getValidator();
46+
}
47+
48+
/**
49+
* Create a new instance of {@link BeanValidatingItemProcessor}.
50+
* @param localValidatorFactoryBean used to configure the Bean Validation validator
51+
*/
52+
public BeanValidatingItemProcessor(LocalValidatorFactoryBean localValidatorFactoryBean) {
53+
Assert.notNull(localValidatorFactoryBean, "localValidatorFactoryBean must not be null");
54+
this.validator = localValidatorFactoryBean.getValidator();
55+
}
56+
57+
@Override
58+
public void afterPropertiesSet() throws Exception {
59+
SpringValidatorAdapter springValidatorAdapter = new SpringValidatorAdapter(this.validator);
60+
SpringValidator<T> springValidator = new SpringValidator<>();
61+
springValidator.setValidator(springValidatorAdapter);
62+
springValidator.afterPropertiesSet();
63+
setValidator(springValidator);
64+
super.afterPropertiesSet();
65+
}
66+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*
2+
* Copyright 2018 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.batch.item.validator;
18+
19+
import javax.validation.constraints.NotEmpty;
20+
21+
import org.junit.Assert;
22+
import org.junit.Test;
23+
24+
/**
25+
* @author Mahmoud Ben Hassine
26+
*/
27+
public class BeanValidatingItemProcessorTest {
28+
29+
@Test
30+
public void testValidObjectValidation() throws Exception {
31+
// given
32+
BeanValidatingItemProcessor<Foo> validatingItemProcessor = new BeanValidatingItemProcessor<>();
33+
validatingItemProcessor.afterPropertiesSet();
34+
Foo foo = new Foo("foo");
35+
36+
// when
37+
Foo processed = validatingItemProcessor.process(foo);
38+
39+
// then
40+
Assert.assertNotNull(processed);
41+
}
42+
43+
@Test(expected = ValidationException.class)
44+
public void testInvalidObjectValidation() throws Exception {
45+
// given
46+
BeanValidatingItemProcessor<Foo> validatingItemProcessor = new BeanValidatingItemProcessor<>();
47+
validatingItemProcessor.afterPropertiesSet();
48+
Foo foo = new Foo("");
49+
50+
// when
51+
validatingItemProcessor.process(foo);
52+
53+
// then
54+
// expected exception
55+
}
56+
57+
private static class Foo {
58+
59+
@NotEmpty
60+
private String name;
61+
62+
public Foo(String name) {
63+
this.name = name;
64+
}
65+
66+
public String getName() {
67+
return name;
68+
}
69+
70+
public void setName(String name) {
71+
this.name = name;
72+
}
73+
74+
}
75+
76+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
* Copyright 2018 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.batch.sample.validation;
18+
19+
import java.util.Arrays;
20+
21+
import org.springframework.batch.core.Job;
22+
import org.springframework.batch.core.Step;
23+
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
24+
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
25+
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
26+
import org.springframework.batch.item.support.ListItemReader;
27+
import org.springframework.batch.item.support.ListItemWriter;
28+
import org.springframework.batch.item.validator.BeanValidatingItemProcessor;
29+
import org.springframework.batch.sample.validation.domain.Person;
30+
import org.springframework.beans.factory.annotation.Autowired;
31+
import org.springframework.context.annotation.Bean;
32+
import org.springframework.context.annotation.Configuration;
33+
34+
/**
35+
* @author Mahmoud Ben Hassine
36+
*/
37+
@Configuration
38+
@EnableBatchProcessing
39+
public class ValidationSampleConfiguration {
40+
41+
@Autowired
42+
private JobBuilderFactory jobs;
43+
44+
@Autowired
45+
private StepBuilderFactory steps;
46+
47+
@Bean
48+
public ListItemReader<Person> itemReader() {
49+
Person person1 = new Person(1, "foo");
50+
Person person2 = new Person(2, "");
51+
return new ListItemReader<>(Arrays.asList(person1, person2));
52+
}
53+
54+
@Bean
55+
public ListItemWriter<Person> itemWriter() {
56+
return new ListItemWriter<>();
57+
}
58+
59+
@Bean
60+
public BeanValidatingItemProcessor<Person> itemValidator() throws Exception {
61+
BeanValidatingItemProcessor<Person> validator = new BeanValidatingItemProcessor<>();
62+
validator.setFilter(true);
63+
validator.afterPropertiesSet();
64+
65+
return validator;
66+
}
67+
68+
@Bean
69+
public Step step() throws Exception {
70+
return this.steps.get("step")
71+
.<Person, Person>chunk(1)
72+
.reader(itemReader())
73+
.processor(itemValidator())
74+
.writer(itemWriter())
75+
.build();
76+
}
77+
78+
@Bean
79+
public Job job() throws Exception {
80+
return this.jobs.get("job")
81+
.start(step())
82+
.build();
83+
}
84+
85+
}

0 commit comments

Comments
 (0)