我正在尝试通过使用spring batch和XStreamMarshaller在spring boot项目中将XML文件解析为JavaBean。我花了很多时间编写类DateConverter来转换XStreamMarshaller对象的正确日期。但这导致我死胡同。我尝试将Date替换为String,但再次显示相同的异常。请帮助我修复这些代码。
这是XML文件:
<RECORDS>
<RECORD>
<emp_no>10001</emp_no>
<birth_date>1953-09-02</birth_date>
<first_name>Georgi</first_name>
<last_name>Facello</last_name>
<gender>M</gender>
<hire_date>1986-06-26</hire_date>
</RECORD>
<RECORD>
<emp_no>10002</emp_no>
<birth_date>1964-06-02</birth_date>
<first_name>Bezalel</first_name>
<last_name>Simmel</last_name>
<gender>F</gender>
<hire_date>1985-11-21</hire_date>
</RECORD>
</RECORDS>
XmlFileDemoApp.java:
@SpringBootApplication
@EnableBatchProcessing
public class XmlFileDemoApp {
public static void main(String[] args) {
SpringApplication.run(XmlFileDemoApp.class, args);
}
}
XmlFileDemoJobConfiguration.java
@Configuration
public class XmlFileDemoJobConfiguration {
@Autowired
private JobBuilderFactory jobBuilderFactory;
@Autowired
private StepBuilderFactory stepBuilderFactory;
@Autowired
@Qualifier("xmlFileDemoWriter")
private ItemWriter<? super NewEmployees> xmlFileDemoWriter;
@Bean
public Job xmlFileDemoJob() throws ClassNotFoundException {
return jobBuilderFactory.get("xmlFileDemoJob")
.start(xmlFileDemoStep())
.build();
}
@Bean
public Step xmlFileDemoStep() throws ClassNotFoundException {
return stepBuilderFactory.get("xmlFileDemoStep")
.<NewEmployees, NewEmployees>chunk(1000)
.reader(xmlFileDemoReader())
.writer(xmlFileDemoWriter)
.build();
}
@Bean
public StaxEventItemReader<NewEmployees> xmlFileDemoReader() throws ClassNotFoundException {
StaxEventItemReader<NewEmployees> reader = new StaxEventItemReader<>();
reader.setResource(new ClassPathResource("employees.xml"));
reader.setFragmentRootElementName("RECORD");
XStreamMarshaller unMarshaller = new XStreamMarshaller();
ConverterMatcher[] converterMatchers = {new DateConverter()};
unMarshaller.setConverters(converterMatchers);
Map<String, Class> map = new HashMap<>(1);
map.put("RECORD", NewEmployees.class);
unMarshaller.setAliases(map);
reader.setUnmarshaller(unMarshaller);
return reader;
}
}
XmlFileDemoWriter.java
@Component("xmlFileDemoWriter")
public class XmlFileDemoWriter implements ItemWriter<NewEmployees> {
@Override
public void write(List<? extends NewEmployees> list) throws Exception {
for (NewEmployees employee : list) {
System.out.println(employee);
}
}
}
DateConverter.java
public class DateConverter implements Converter {
@Override
public boolean canConvert(Class arg0) {
return Date.class == arg0;
}
@Override
public void marshal(Object arg0, HierarchicalStreamWriter arg1, MarshallingContext arg2) {
}
@Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext arg1) {
GregorianCalendar calendar = new GregorianCalendar();
SimpleDateFormat dateFm = new SimpleDateFormat("yyyy-MM-dd");
try {
calendar.setTime(dateFm.parse(reader.getValue()));
} catch (ParseException e) {
throw new ConversionException(e.getMessage(), e);
}
return calendar.getTime();
}
}
NewEmployees.java
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class NewEmployees {
private int emp_no;
private Date birth_date;
private String first_name;
private String last_name;
private String gender;
private Date hire_date;
}
显然,yyyy-MM-dd是不正确的。 错误日志为:
org.springframework.oxm.UnmarshallingFailureException: XStream unmarshalling exception; nested exception is com.thoughtworks.xstream.converters.ConversionException: Cannot parse date
---- Debugging information ----
message : Cannot parse date
date : 1953-09-02
class : java.util.Date
required-type : java.util.Date
converter-type : com.thoughtworks.xstream.converters.SingleValueConverterWrapper
wrapped-converter : com.thoughtworks.xstream.converters.basic.DateConverter
Default date pattern: yyyy-MM-dd HH:mm:ss.S z
Default era date pattern: yyyy-MM-dd G HH:mm:ss.S z
Alternative date pattern: yyyy-MM-dd HH:mm:ss.S z
Alternative date pattern[1]: yyyy-MM-dd HH:mm:ss.S a
Alternative date pattern[2]: yyyy-MM-dd HH:mm:ssz
Alternative date pattern[3]: yyyy-MM-dd HH:mm:ss z
Alternative date pattern[4]: yyyy-MM-dd'T'HH:mm:ss.SX
Alternative date pattern[5]: yyyy-MM-dd'T'HH:mm:ssX
Alternative date pattern[6]: yyyy-MM-dd'T'HH:mmX
Alternative date pattern[7]: yyyy-MM-dd HH:mm:ssa
path : /RECORD/birth_date
line number : 5
class[1] : com.batch.testspringbatch.input.xmlFile.NewEmployees
converter-type[1] : com.thoughtworks.xstream.converters.reflection.ReflectionConverter
version : 1.4.10
然后我写了一个DateConverter来处理时间,然后错误变为:
java.lang.ClassCastException: com.batch.testspringbatch.input.xmlFile.NewEmployees cannot be cast to com.batch.testspringbatch.input.xmlFile.NewEmployees
at com.batch.testspringbatch.input.xmlFile.XmlFileDemoWriter.write(XmlFileDemoWriter.java:12) ~[classes/:na]