我正在处理一个Spring批量需求。在我的项目中,我在一个单独的util包中编写了一个转换器类作为实用程序类。我正在读写到MySQL数据库的CSV文件。
public class Customer implements Serializable {
private Integer id_type;
private String id_number;
private String customer_name;
private String email_address;
private LocalDate birthday;
private String citizenship;
private String address;
private Long msisdn;
private LocalDateTime kyc_date;
private String kyc_level;
private String goalscore;
private String mobile_network;
}
public final class StringToLocalDateConversion {
private StringToLocalDateConversion() {
}
static ConversionService createLocalDateConversionServicve() {
DefaultConversionService stringToLocalDateconversionService = new DefaultConversionService();
DefaultConversionService.addDefaultConverters(stringToLocalDateconversionService);
stringToLocalDateconversionService.addConverter(new Converter<String, LocalDate>() {
@Override
public LocalDate convert(String text) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-mm-dd");
return LocalDate.parse(text, formatter);
}
});
return stringToLocalDateconversionService;
}
}
public final class StringToLocalDateTimeConversion {
public StringToLocalDateTimeConversion() {
}
static ConversionService stringToLocalDateTimeConversionService() {
DefaultConversionService stringToLocalDateTimeConversion = new DefaultConversionService();
DefaultConversionService.addDefaultConverters(stringToLocalDateTimeConversion);
stringToLocalDateTimeConversion.addConverter(new Converter<String, LocalDateTime>() {
@Override
public LocalDateTime convert(String source) {
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-mm-dd hh:mm:ss");
return LocalDateTime.parse(source, dateTimeFormatter);
}
});
return stringToLocalDateTimeConversion;
}
}
@Configuration
@EnableBatchProcessing
public class BatchConfiguration {
@Autowired
public JobBuilderFactory jobBuilderFactory;
@Autowired
public StepBuilderFactory stepBuilderFactory;
@Value("classPath:/data/gcash.csv")
private Resource inputResource;
@Autowired
public DataSource dataSource;
@Bean
public Job readCSVFilesJob() {
return jobBuilderFactory.get("readCSVFilesJob").incrementer(new RunIdIncrementer()).start(step1()).build();
}
@Bean
public Step step1() {
return stepBuilderFactory.get("step1").<Customer, Customer>chunk(10).reader(itemReader()).processor(processor())
.writer(writer()).build();
}
/*
* @Bean public DataSource dataSource() { final DriverManagerDataSource
* dataSource = new DriverManagerDataSource();
* dataSource.setDriverClassName("com.mysql.jdbc.Driver");
* dataSource.setUrl("jdbc:mysql://localhost:3306/springbatch");
* dataSource.setUsername("root"); dataSource.setPassword("123456");
*
* return dataSource; }
*/
@Bean
public ItemReader<Customer> itemReader() {
FlatFileItemReader<Customer> customerItemReader = new FlatFileItemReader<>();
customerItemReader.setName("CUSTOMER_READER");
customerItemReader.setLineMapper(linemapper());
customerItemReader.setLinesToSkip(1);
customerItemReader.setResource(inputResource);
return customerItemReader;
}
@Bean
public LineMapper<Customer> linemapper() {
DefaultLineMapper<Customer> linemapper = new DefaultLineMapper<>();
final DelimitedLineTokenizer tokenizer = new DelimitedLineTokenizer();
tokenizer.setDelimiter(";");
tokenizer.setStrict(false);
tokenizer.setNames(new String[] { "id_type", "id_number", "customer_name", "email_address", "birthday",
"citizenship", "address", "msisdn", "kyc_date", "kyc_level", "goalscore", "mobile_network" });
linemapper.setLineTokenizer(tokenizer);
BeanWrapperFieldSetMapper<Customer> fieldSetMapper = new BeanWrapperFieldSetMapper<>();
fieldSetMapper.setTargetType(Customer.class);
ConversionService localDateConversionService = StringToLocalDateConversion.createLocalDateConversionServicve();
ConversionService localDateTimeConversionService = StringToLocalDateTimeConversion
.stringToLocalDateTimeConversionService();
fieldSetMapper.setConversionService(localDateConversionService);
fieldSetMapper.setConversionService(localDateTimeConversionService);
linemapper.setFieldSetMapper(fieldSetMapper);
return linemapper;
}
@Bean
public CustomerItemProcessor processor() {
return new CustomerItemProcessor();
}
@Bean
public JdbcBatchItemWriter<Customer> writer() {
JdbcBatchItemWriter<Customer> writer = new JdbcBatchItemWriter<>();
writer.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<Customer>());
writer.setSql(
"INSERT INTO people (id_type, id_number,customer_name,email_address,birthday,citizenship,address,msisdn,kyc_date,kyc_level,goalscore,mobile_network) VALUES (:id_type, :id_number, :customer_name, :email_address, :birthday, :citizenship, :address, :msisdn, :kyc_date, :goalscore, :mobile_network)");
writer.setDataSource(this.dataSource);
return writer;
}
}
org.springframework.batch.item.file.FlatFileParseException: Parsing error at line: 2 in resource=[URL [classpath:/data/gcash.csv]], input=["LISONDRA, MARIA MINI, JUCOM",MJLISONDRA71@GMAIL.COM,1971-02-12,FILIPINO,2,06-1401967-8,"M L QUEZON CABANCALAN, QUEZON, MANDAUE",9052100646,2019-10-10 11:45:18,FULL KYC,525_549,Globe Prepaid]
at org.springframework.batch.item.file.FlatFileItemReader.doRead(FlatFileItemReader.java:189) ~[spring-batch-infrastructure-4.3.1.jar:4.3.1]
at org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader.read(AbstractItemCountingItemStreamItemReader.java:93) ~[spring-batch-infrastructure-4.3.1.jar:4.3.1]
at org.springframework.batch.core.step.item.SimpleChunkProvider.doRead(SimpleChunkProvider.java:99) ~[spring-batch-core-4.3.1.jar:4.3.1]
at org.springframework.batch.core.step.item.SimpleChunkProvider.read(SimpleChunkProvider.java:180) ~[spring-batch-core-4.3.1.jar:4.3.1]
at org.springframework.batch.core.step.item.SimpleChunkProvider$1.doInIteration(SimpleChunkProvider.java:126) ~[spring-batch-core-4.3.1.jar:4.3.1]
at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:375) ~[spring-batch-infrastructure-4.3.1.jar:4.3.1]
at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215) ~[spring-batch-infrastructure-4.3.1.jar:4.3.1]
at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:145) ~[spring-batch-infrastructure-4.3.1.jar:4.3.1]
at org.springframework.batch.core.step.item.SimpleChunkProvider.provide(SimpleChunkProvider.java:118) ~[spring-batch-core-4.3.1.jar:4.3.1]
at org.springframework.batch.core.step.item.ChunkOrientedTasklet.execute(ChunkOrientedTasklet.java:71) ~[spring-batch-core-4.3.1.jar:4.3.1]
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:407) ~[spring-batch-core-4.3.1.jar:4.3.1]
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:331) ~[spring-batch-core-4.3.1.jar:4.3.1]
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140) ~[spring-tx-5.3.4.jar:5.3.4]
at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:273) ~[spring-batch-core-4.3.1.jar:4.3.1]
at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:82) ~[spring-batch-core-4.3.1.jar:4.3.1]
at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:375) ~[spring-batch-infrastructure-4.3.1.jar:4.3.1]
at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215) ~[spring-batch-infrastructure-4.3.1.jar:4.3.1]
at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:145) ~[spring-batch-infrastructure-4.3.1.jar:4.3.1]
at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:258) ~[spring-batch-core-4.3.1.jar:4.3.1]
at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:208) ~[spring-batch-core-4.3.1.jar:4.3.1]
at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:148) [spring-batch-core-4.3.1.jar:4.3.1]
at org.springframework.batch.core.job.AbstractJob.handleStep(AbstractJob.java:411) [spring-batch-core-4.3.1.jar:4.3.1]
at org.springframework.batch.core.job.SimpleJob.doExecute(SimpleJob.java:136) [spring-batch-core-4.3.1.jar:4.3.1]
at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:320) [spring-batch-core-4.3.1.jar:4.3.1]
at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:147) [spring-batch-core-4.3.1.jar:4.3.1]
at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50) [spring-core-5.3.4.jar:5.3.4]
at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:140) [spring-batch-core-4.3.1.jar:4.3.1]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_271]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_271]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_271]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_271]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) [spring-aop-5.3.4.jar:5.3.4]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198) [spring-aop-5.3.4.jar:5.3.4]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) [spring-aop-5.3.4.jar:5.3.4]
at org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration$PassthruAdvice.invoke(SimpleBatchConfiguration.java:128) [spring-batch-core-4.3.1.jar:4.3.1]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) [spring-aop-5.3.4.jar:5.3.4]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215) [spring-aop-5.3.4.jar:5.3.4]
at com.sun.proxy.$Proxy104.run(Unknown Source) [na:na]
at org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner.execute(JobLauncherApplicationRunner.java:199) [spring-boot-autoconfigure-2.4.3.jar:2.4.3]
at org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner.executeLocalJobs(JobLauncherApplicationRunner.java:173) [spring-boot-autoconfigure-2.4.3.jar:2.4.3]
at org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner.launchJobFromProperties(JobLauncherApplicationRunner.java:160) [spring-boot-autoconfigure-2.4.3.jar:2.4.3]
at org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner.run(JobLauncherApplicationRunner.java:155) [spring-boot-autoconfigure-2.4.3.jar:2.4.3]
at org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner.run(JobLauncherApplicationRunner.java:150) [spring-boot-autoconfigure-2.4.3.jar:2.4.3]
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:795) [spring-boot-2.4.3.jar:2.4.3]
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:785) [spring-boot-2.4.3.jar:2.4.3]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:333) [spring-boot-2.4.3.jar:2.4.3]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1311) [spring-boot-2.4.3.jar:2.4.3]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1300) [spring-boot-2.4.3.jar:2.4.3]
at com.gcash.milo.GCashMiloApplication.main(GCashMiloApplication.java:10) [classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_271]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_271]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_271]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_271]
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) [spring-boot-devtools-2.4.3.jar:2.4.3]
Caused by: org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 3 errors
Field error in object 'target' on field 'id_type': rejected value ["LISONDRA, MARIA MINI, JUCOM",MJLISONDRA71@GMAIL.COM,1971-02-12,FILIPINO,2,06-1401967-8,"M L QUEZON CABANCALAN, QUEZON, MANDAUE",9052100646,2019-10-10 11:45:18,FULL KYC,525_549,Globe Prepaid]; codes [typeMismatch.target.id_type,typeMismatch.id_type,typeMismatch.java.lang.Integer,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [target.id_type,id_type]; arguments []; default message [id_type]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.lang.Integer' for property 'id_type'; nested exception is java.lang.NumberFormatException: For input string: ""LISONDRA,MARIAMINI,JUCOM",MJLISONDRA71@GMAIL.COM,1971-02-12,FILIPINO,2,06-1401967-8,"MLQUEZONCABANCALAN,QUEZON,MANDAUE",9052100646,2019-10-1011:45:18,FULLKYC,525_549,GlobePrepaid"]
Field error in object 'target' on field 'kyc_date': rejected value []; codes [typeMismatch.target.kyc_date,typeMismatch.kyc_date,typeMismatch.java.time.LocalDateTime,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [target.kyc_date,kyc_date]; arguments []; default message [kyc_date]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.time.LocalDateTime' for property 'kyc_date'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.time.LocalDateTime] for value ''; nested exception is java.time.format.DateTimeParseException: Text '' could not be parsed at index 0]
Field error in object 'target' on field 'birthday': rejected value []; codes [typeMismatch.target.birthday,typeMismatch.birthday,typeMismatch.java.time.LocalDate,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [target.birthday,birthday]; arguments []; default message [birthday]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.time.LocalDate' for property 'birthday'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'java.time.LocalDate' for property 'birthday': no matching editors or conversion strategy found]
at org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper.mapFieldSet(BeanWrapperFieldSetMapper.java:201) ~[spring-batch-infrastructure-4.3.1.jar:4.3.1]
at org.springframework.batch.item.file.mapping.DefaultLineMapper.mapLine(DefaultLineMapper.java:43) ~[spring-batch-infrastructure-4.3.1.jar:4.3.1]
at org.springframework.batch.item.file.FlatFileItemReader.doRead(FlatFileItemReader.java:185) ~[spring-batch-infrastructure-4.3.1.jar:4.3.1]
... 53 common frames omitted
[2m2021-04-27 22:45:46.085[0;39m [32m INFO[0;39m [35m7456[0;39m [2m---[0;39m [2m[ restartedMain][0;39m [36mo.s.batch.core.step.AbstractStep [0;39m [2m:[0;39m Step: [step1] executed in 25ms
[2m2021-04-27 22:45:46.097[0;39m [32m INFO[0;39m [35m7456[0;39m [2m---[0;39m [2m[ restartedMain][0;39m [36mo.s.b.c.l.support.SimpleJobLauncher [0;39m [2m:[0;39m Job: [SimpleJob: [name=readCSVFilesJob]] completed with the following parameters: [{run.id=17}] and the following status: [FAILED] in 49ms
[2m2021-04-27 22:45:46.097[0;39m [32m INFO[0;39m [35m7456[0;39m [2m---[0;39m [2m[ restartedMain][0;39m [36m.ConditionEvaluationDeltaLoggingListener[0;39m [2m:[0;39m Condition evaluation unchanged
Caused by: org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 3 errors
Field error in object 'target' on field 'id_type': rejected value ["LISONDRA, MARIA MINI, JUCOM",MJLISONDRA71@GMAIL.COM,1971-02-12,FILIPINO,2,06-1401967-8,"M L QUEZON CABANCALAN, QUEZON, MANDAUE",9052100646,2019-10-10 11:45:18,FULL KYC,525_549,Globe Prepaid]; codes [typeMismatch.target.id_type,typeMismatch.id_type,typeMismatch.java.lang.Integer,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [target.id_type,id_type]; arguments []; default message [id_type]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.lang.Integer' for property 'id_type'; nested exception is java.lang.NumberFormatException: For input string: ""LISONDRA,MARIAMINI,JUCOM",MJLISONDRA71@GMAIL.COM,1971-02-12,FILIPINO,2,06-1401967-8,"MLQUEZONCABANCALAN,QUEZON,MANDAUE",9052100646,2019-10-1011:45:18,FULLKYC,525_549,GlobePrepaid"]
Field error in object 'target' on field 'kyc_date': rejected value []; codes [typeMismatch.target.kyc_date,typeMismatch.kyc_date,typeMismatch.java.time.LocalDateTime,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [target.kyc_date,kyc_date]; arguments []; default message [kyc_date]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.time.LocalDateTime' for property 'kyc_date'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.time.LocalDateTime] for value ''; nested exception is java.time.format.DateTimeParseException: Text '' could not be parsed at index 0]
Field error in object 'target' on field 'birthday': rejected value []; codes [typeMismatch.target.birthday,typeMismatch.birthday,typeMismatch.java.time.LocalDate,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [target.birthday,birthday]; arguments []; default message [birthday]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.time.LocalDate' for property 'birthday'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'java.time.LocalDate' for property 'birthday': no matching editors or conversion strategy found]
[未能将类型“java.lang.String”的属性值转换为属性“id_type”所需的类型“java.lang.Integer”
在我的模型类中,id_type是Integer类型,那么为什么它说“未能将属性值字符串转换为Integer?”
这是因为有行,其中一些字段在引号字段中包含分隔符(,
):
"LISONDRA, MARIA MINI, JUCOM",MJLISONDRA71@GMAIL.COM,1971-02-12,FILIPINO,2,06-1401967-8,"M L QUEZON CABANCALAN, QUEZON, MANDAUE",9052100646,2019-10-10 11:45:18,FULL KYC,525_549,Globe Prepaid
由于您使用的是DelimitedLineTokenizer
,其中默认引号字符为“
”,因此“Lisondra,MARIA MINI,Jucom”
和“M L QUEZON CABANCALAN,QUEZON,Mandaue”
字段不被视为单个值。因此,试图将整行字符串转换为type_id
类型为integer的第一个字段。这里有一个开放的问题:https://github.com/spring-batch/issues/1822。
您需要使用不同的引号字符或创建能够处理这种情况的自定义FieldSetMapper
。
编辑:添加转换服务示例
conversionService.addConverter(new Converter<String, LocalDate>() { .. });
conversionService.addConverter(new Converter<String, LocalDatTime>() { .. });
fieldSetMapper.setConversionService(conversionService);
我想在json中以的形式发布上面的字符串日期,但我收到了400个错误请求。有人能帮忙吗。我使用过,但它也没有帮助我。
我不确定我是否错过了一些真正基本的东西,但这是我想做的。 我想对这个地址进行rest API调用: https://localhost:8080/fetchlocation?lat=-26.2041028和lng=28.0473051和radius=500 我想这是因为当我进行GET调用时,rest API接收的坐标是字符串而不是long。我如何确保rest API在调用时得到的是长值而不是字符串
我有两个实体,它们使用一个主键互相引用,主键是一个实体的整数。我不确定我做这件事的方式是否正确。 下面是引用主键id为int的实体 下面是我们从上面的实体中将外键设置为Kmichango kandaMchango的实体。 这里是表单的一部分,我在这里提交了用户在jumuiya_michango_form.html中提供的数据 下面是我的控制器中用于链接到表单和发布数据的两个方法 在我提交表单后,我
org.springframework.beans.ConversionNotSupportedException:未能将类型“java.lang.long”的属性值转换为属性“card”所需的类型“card”;嵌套异常是java.lang.IllegalStateException:无法将类型“java.lang.Long”的值转换为属性“Card”所需的类型“Card”:找不到匹配的编辑器或转
我是SpringMVC的新手。我开发了一个执行选择,插入,更新和删除的示例应用程序。 下面是我的Bean类 下面是我的控制器类 下面是我的JSP页面 现在我面临两个问题。输入值并单击“添加学生”按钮后,收到以下错误。
我正在关注Spring in Action 5,在按下提交按钮后创建Taco模型时遇到问题。这是我的设计Taco控制器类: 以及我捕获的错误消息: 炸玉米饼实体如下所示: 以及我的配料实体: 这是一个html页面,必须使用所选成分创建新的Taco对象: 我该怎么修理它?谢谢你的预付款。