所以我正在创建我的第一个Spring批处理作业。我试图读取一个xml,操纵一些值,然后写出来。如果我没有实现org.springframework.batch.item.ItemProcessor接口,我的工作似乎解组了我的XML文档并写得很好。一旦我实现了接口,我需要做的是为了操作值,我得到下面的错误。当我检查输出文件时,它会输出xml标记,开始的根元素标记,而不是其他内容。如果我在作业的第1步中注释掉对处理器的调用,那么该文件将写入我的文件目录。任何帮助将不胜感激,我一直在寻找修复,没有任何运气。我的消息验证了多个大的xsd,所以我把它们从代码中删除了。
2018-05-21 15:58:57.690 ERROR 6684 --- [main] o.s.batch.core.step.AbstractStep:在job importUserJob中执行步骤step1时遇到错误 java.lang.ClassCastException:javax.xml.bind.JAXBElement无法强制转换为[mySchema] BatchProcessor.process(BatchProcessor.java:1)〜[classes /:na]
public class BatchProcessor implements ItemProcessor<ProdRequest, ProdRequest>{
@Override
public ProdRequest process(ProdRequest arg0) throws Exception {
//Error still thrown even when I comment out all of the code. Break points in this methoda re never reached.
return arg0;
}
}
-
@Configuration
@EnableBatchProcessing
public class XMLReaderConfiguration {
@Autowired
public JobBuilderFactory jobBuilderFactory;
@Autowired
public StepBuilderFactory stepBuilderFactory;
@Bean
public BatchProcessor processor() {
return new BatchProcessor();
}
@Bean(destroyMethod="")
public StaxEventItemReader<ProdRequest> reader(){
StaxEventItemReader<ProdRequest> reader = new StaxEventItemReader<>();
reader.setResource(new ClassPathResource("policy.xml"));
reader.setFragmentRootElementName("ProdRequest");
Jaxb2Marshaller xmlMarshaller = new Jaxb2Marshaller();
ObjectFactory objectFactory = new ObjectFactory();
xmlMarshaller.setClassesToBeBound(new Class[] {
//all of my object classes (all generated by JAXB) I have added the xmlRootElement attribute to my top level class only.
});
xmlMarshaller.setSupportJaxbElementClass(true);
reader.setUnmarshaller(xmlMarshaller);
return reader;
}
@Bean(destroyMethod="")
public StaxEventItemWriter<ProdRequest> writer(){
StaxEventItemWriter<ProdRequest> writer = new StaxEventItemWriter<ProdRequest>();
String exportFilePath = "C:/Test/springBatchTest.xml";
writer.setResource(new FileSystemResource(exportFilePath));
writer.setRootTagName("ProdRequest");
Jaxb2Marshaller xmlMarshaller = new Jaxb2Marshaller();
xmlMarshaller.setClassesToBeBound(new Class[] {
//all of my object classes (all generated by JAXB) I have added the xmlRootElement attribute to my top level class only.
});
xmlMarshaller.setSupportJaxbElementClass(true);
writer.setMarshaller(xmlMarshaller);
return writer;
}
@Bean
public Step step1(){
return stepBuilderFactory.get("step1")
.<ProdRequest, ProdRequest> chunk(10)
.reader(reader())
.processor(processor())
.writer(writer())
.build();
}
@Bean
public Job importUserJob(){
return jobBuilderFactory.get("importUserJob")
.incrementer(new RunIdIncrementer())
.flow(step1())
.end()
.build();
}
}
答案 0 :(得分:1)
所以最终我在spring框架中设置了一个断点,发现在我的文档被解组之后,实际上它返回了一个包含我期望的文档的通用JAXBElement。当JAXBElement传递给我正在实现Spring ItemProcessor的BatchProcessor类时,错误被抛出,因为我的类不希望文档在JAXBElement中。所以为了解决这个问题,我必须将BatchProcessor的参数更改为JAXBElement。我的修复如下。我删除了一些公司特定的名称和我的JAXBClasses列表。希望这可以帮助有人在路上。谢谢!
public class BatchProcessor implements ItemProcessor<JAXBElement<ProdRequest> , ProdRequest>{
@Override
public ProdRequest process(JAXBElement<ProdRequest> jaxbElement) throws Exception {
ObjectFactory objectFactory = new ObjectFactory();
JAXBElement<String> code = objectFactory.createProdRequestCode("test");
CWDocProdRequest doc = jaxbElement.getValue();
doc.setCode(code);
return doc;
}
}
@Configuration
@EnableBatchProcessing
public class XMLReaderConfiguration {
@Autowired
public JobBuilderFactory jobBuilderFactory;
@Autowired
public StepBuilderFactory stepBuilderFactory;
@Bean
public BatchCWAutoProcessor processor() {
return new BatchCWAutoProcessor();
}
@Bean(destroyMethod="")
public StaxEventItemReader <JAXBElement<ProdRequest>> reader(){
StaxEventItemReader<JAXBElement<ProdRequest>> reader = new StaxEventItemReader<JAXBElement<ProdRequest>>();
reader.setResource(new ClassPathResource("policy.xml"));
reader.setFragmentRootElementName("ProdRequest");
Jaxb2Marshaller xmlMarshaller = new Jaxb2Marshaller();
ObjectFactory objectFactory = new ObjectFactory();
xmlMarshaller.setClassesToBeBound(new Class[] {
//auto generated JAXB classes
});
xmlMarshaller.setSupportJaxbElementClass(true);
reader.setUnmarshaller(xmlMarshaller);
return reader;
}
@Bean(destroyMethod="")
public StaxEventItemWriter<ProdRequest> writer(){
StaxEventItemWriter<ProdRequest> writer = new StaxEventItemWriter<ProdRequest>();
String exportFilePath = "C:/springBatchTest.xml";
writer.setResource(new FileSystemResource(exportFilePath));
writer.setRootTagName("ProdRequest");
Jaxb2Marshaller xmlMarshaller = new Jaxb2Marshaller();
xmlMarshaller.setClassesToBeBound(new Class[] {
//list auto generated JAXB classes here
});
xmlMarshaller.setSupportJaxbElementClass(true);
writer.setMarshaller(xmlMarshaller);
return writer;
}
@Bean
public Step step1(){
return stepBuilderFactory.get("step1")
//.<ProdRequest, ProdRequest> chunk(10)//changed this to the line below
.<JAXBElement<ProdRequest>, ProdRequest> chunk(10)
.reader(reader())
.processor(processor())
.writer(writer())
.build();
}
@Bean
public Job importUserJob(){
return jobBuilderFactory.get("importUserJob")
.incrementer(new RunIdIncrementer())
.flow(step1())
.end()
.build();
}
}