Descripción del Problema
Cómo leer registros de múltiples ficheros (en este caso usaremos ficheros CSV), y escribir los diferentes registros en un sólo fichero csv.
Ficheros
Para ilustrar el caso, os proporciono 3 ficheros: domain-1-3-2013.csv, domain-2-3-2013.csv, domain-3-3-2013.csv
csv/inputs/domain-1-3-2013.csv
1 2 3 4 5 | 1,facebook.com 2,yahoo.com 3,google.com |
csv/inputs/domain-2-3-2013.csv
1 2 3 4 5 | 200,wherever.com 300,stackoverflow.com 400,oracle.com |
csv/inputs/domain-3-3-2013.csv
1 2 3 | 999,eclipse.org 888,baidu.com |
CLASE
Se requiere una clase que servirá para almacenar temporalmente los dos campos de cada linea del fichero.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | package com.ejemplo; public class Domain { int id; String domain; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getDomain() { return domain; } public void setDomain(String domain) { this.domain = domain; } } |
Configuración del Job de Spring
Solo se necesita la siguiente configuración en spring-batchjob-merge-files.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | < beans xmlns:batch = "http://www.springframework.org/schema/batch" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns = "http://www.springframework.org/schema/beans" xsi:schemalocation="http://www.springframework.org/schema/batch "> < import resource = "../config/context.xml" > < bean class = "com.ejemplo.Domain" id = "domain" > < step id = "step1" > < tasklet > < chunk commit-interval = "1" reader = "multiResourceReader" writer = "flatFileItemWriter" > </ chunk ></ tasklet > </ step > </ job > < bean class = " org.springframework.batch.item.file.MultiResourceItemReader" id = "multiResourceReader" > < property name = "resources" value = "file:csv/inputs/domain-*.csv" > < property name = "delegate" ref = "flatFileItemReader" > </ property ></ property ></ bean > < bean class = "org.springframework.batch.item.file.FlatFileItemReader" id = "flatFileItemReader" > < property name = "lineMapper" > < bean class = "org.springframework.batch.item.file.mapping.DefaultLineMapper" > < property name = "lineTokenizer" > < bean class = "org.springframework.batch.item.file.transform.DelimitedLineTokenizer" > < property name = "names" value = "id, domain" > </ property ></ bean > </ property > < property name = "fieldSetMapper" > < bean class = "org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper" > < property name = "prototypeBeanName" value = "domain" > </ property ></ bean > </ property > </ bean > </ property > </ bean > < bean class = "org.springframework.batch.item.file.FlatFileItemWriter" id = "flatFileItemWriter" > < property name = "resource" value = "file:csv/outputs/domain.all.csv" > < property name = "appendAllowed" value = "true" > < property name = "lineAggregator" > < bean class = "org.springframework.batch.item.file.transform.DelimitedLineAggregator" > < property name = "delimiter" value = "," > < property name = "fieldExtractor" > < bean class = "org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor" > < property name = "names" value = "id, domain" > </ property ></ bean > </ property > </ property ></ bean > </ property > </ property ></ property ></ bean > </ bean ></ import ></ beans > |
Configuración del Contexto de Spring-Batch
Este fichero suele cambiar según la configuración que quieras hacer con spring-batch, les facilito la parte más básica.
context.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | < beans xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns = "http://www.springframework.org/schema/beans" xsi:schemalocation=" <!-- stored job-meta in memory --> < bean class = "org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean" id = "jobRepository" > < property name = "transactionManager" ref = "transactionManager" > </ property ></ bean > < bean class = "org.springframework.batch.support.transaction.ResourcelessTransactionManager" id = "transactionManager" > < bean class = "org.springframework.batch.core.launch.support.SimpleJobLauncher" id = "jobLauncher" > < property name = "jobRepository" ref = "jobRepository" > </ property ></ bean > </ bean ></ beans > |
Clase para ejecutar el job
Se requiere una clase que servirá para ejecutar el job.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | package com.ejemplo; import org.springframework.batch.core.Job; import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.JobParameters; import org.springframework.batch.core.launch.JobLauncher; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class App { public static void main(String[] args) { App obj = new App(); obj.run(); } private void run() { String[] springConfig = { "spring/batch/jobs/job-merge-files.xml" }; ApplicationContext context = new ClassPathXmlApplicationContext(springConfig); JobLauncher jobLauncher = (JobLauncher) context.getBean("jobLauncher"); Job job = (Job) context.getBean("readMultiFileJob"); try { JobExecution execution = jobLauncher.run(job, new JobParameters()); System.out.println("Exit Status : " + execution.getStatus()); } catch (Exception e) { e.printStackTrace(); } System.out.println("Done"); } } |
RESULTADO
Al ejecutar el batch, la salida esperada será un fichero llamado domain.all.csv con la combinación de los registros de los tres ficheros csv de entrada.csv/outputs/domain.all.csv
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 1,facebook.com 2,yahoo.com 3,google.coms 200,mkyong.com 300,stackoverflow.com 400,oracle.com 999,eclipse.org 888,baidu.com |
No hay comentarios:
Publicar un comentario