Получение java.lang.ClassCastException: javax.xml.bind.JAXBElement не может быть приведен к com.[MySchema] при реализации ItemProcessor

Поэтому я создаю свою первую весеннюю пакетную работу. Я пытаюсь читать в XML, манипулировать некоторыми значениями, и записать его. Моя работа, кажется, распаковывает мой XML-документ и записывает его нормально, если я не реализую интерфейс org.springframework.batch.item.ItemProcessor. Как только я реализую интерфейс, который мне нужно сделать, чтобы манипулировать значениями, я получаю ошибку ниже. Когда я проверяю выходной файл, он выводит тег xml, тег начального корневого элемента и ничего больше. Если я закомментирую вызов моего процессора на шаге 1 моей работы, то файл будет записан в мою файловую директорию. Буду признателен за любую помощь, я искал повсюду, и мне не повезло. Мое сообщение проверяется по нескольким большим xsd, поэтому я оставил их вне кода.

2018-05-21 15: 58: 57.690 ОШИБКА 6684 --- [ main] osbatch.core.step.AbstractStep: Обнаружена ошибка при выполнении шага step1 в задании importUserJob 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();               
}
}

1 ответ

Поэтому, в конце концов, я установил точку останова в весенних рамках и обнаружил, что после того, как мой документ стал бесполезным, он на самом деле возвращал универсальный элемент JAXBElement, который содержал ожидаемый мной документ. Когда этот JAXBElement передавался моему классу BatchProcessor, который реализовывал Spring ItemProcessor, возникала ошибка, потому что мой класс не ожидал, что документ будет находиться внутри 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();               
}
    }
Другие вопросы по тегам