The XML output from the Spring Batch Jaxb2Marshaller - Marshaller.JAXB_FORMATTED_OUTPUT is not working, why?

不想你离开。 提交于 2019-12-13 06:37:24

问题


I am working on Spring Batch MongoDB to XML. I've the following two code snippet.

First:

<bean id="reportMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
    <property name="classesToBeBound">
        <value>com.mkyong.model.Report</value>
    </property>
    <property name="marshallerProperties">
        <map>
            <entry>
                <key>
                    <util:constant static-field="javax.xml.bind.Marshaller.JAXB_FORMATTED_OUTPUT"/>
                </key>
                <value type="boolean">true</value>
            </entry>
        </map>
    </property>
</bean>

Second

<bean id="reportMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
    <property name="classesToBeBound">
        <value>com.mkyong.model.Report</value>
    </property>
</bean>

Both configuration is not formatting the output file. The Result is printed in a only single line of XML file. I was expecting the First configuration will format the result, but its not.

JAXB_FORMATTED_OUTPUT The name of the property used to specify whether or not the marshalled XML data is formatted with linefeeds and indentation. But unfortunately this is not happening.

The ouput which I see in single line of xml file:

pom.xml

<properties>
    <!-- Generic properties -->
    <java.version>1.7</java.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

    <spring.version>4.3.5.RELEASE</spring.version>
    <spring.batch.version>3.0.7.RELEASE</spring.batch.version>
    <spring.data.version>1.8.4.RELEASE</spring.data.version>
    <mongodb.driver.version>3.1.1</mongodb.driver.version>

    <!-- Logging -->
    <logback.version>1.0.13</logback.version>
    <slf4j.version>1.7.5</slf4j.version>
    <jcl.slf4j.version>1.7.12</jcl.slf4j.version>

    <!-- Test -->
    <junit.version>4.12</junit.version>

</properties>

<dependencies>
    <!-- Spring Core -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <!-- Spring XML to/back object -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-oxm</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <!-- Spring Batch dependencies -->
    <dependency>
        <groupId>org.springframework.batch</groupId>
        <artifactId>spring-batch-core</artifactId>
        <version>${spring.batch.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.batch</groupId>
        <artifactId>spring-batch-infrastructure</artifactId>
        <version>${spring.batch.version}</version>
    </dependency>

    <!-- Spring Batch unit test -->
    <dependency>
        <groupId>org.springframework.batch</groupId>
        <artifactId>spring-batch-test</artifactId>
        <version>${spring.batch.version}</version>
    </dependency>

    <!-- MongoDB database driver -->
    <dependency>
        <groupId>org.mongodb</groupId>
        <artifactId>mongo-java-driver</artifactId>
        <version>${mongodb.driver.version}</version>
    </dependency>

    <!-- Logging with SLF4J & LogBack -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>${slf4j.version}</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>${logback.version}</version>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>jcl-over-slf4j</artifactId>
        <version>${jcl.slf4j.version}</version>
    </dependency>

    <!-- Spring data mongodb -->
    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-mongodb</artifactId>
        <version>${spring.data.version}</version>
    </dependency>

    <dependency>
        <groupId>javax.xml.bind</groupId>
        <artifactId>jaxb-api</artifactId>
        <version>2.2.12</version>
    </dependency>


    <!-- Junit -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>${junit.version}</version>
        <scope>test</scope>
    </dependency>

    <!-- Testng -->
    <dependency>
        <groupId>org.testng</groupId>
        <artifactId>testng</artifactId>
        <version>6.8.5</version>
        <scope>test</scope>
    </dependency>
</dependencies>

I am using following:

<bean id="xmlItemWriter" class="org.springframework.batch.item.xml.StaxEventItemWriter">
    <property name="resource" value="file:outputs/report.xml" />
    <property name="encoding" value="ISO-8859-1" />
    <property name="version" value="1.0" />
    <property name="marshaller" ref="reportMarshaller" />
    <property name="rootTagName" value="record" />
    <!-- TRUE means, that output file will be overwritten if exists - default is TRUE -->
    <property name="overwriteOutput" value="true" />
</bean>

As per inputs from Karthik:

<?xml version="1.0" encoding="ISO-8859-1"?>
<record><record id="1">
    <date>01-06-2013</date>
    <impression>139237</impression>
    <clicks>40</clicks>
    <earning>220.90</earning>
  </record><record id="2">
    <date>02-06-2013</date>
    <impression>339100</impression>
    <clicks>60</clicks>
    <earning>320.88</earning>
  </record><record id="3">
    <date>03-06-2013</date>
    <impression>431436</impression>
    <clicks>76</clicks>
    <earning>270.80</earning>
  </record><record id="4">
    <date>12-03-2016</date>
    <impression>534987</impression>
    <clicks>43</clicks>
    <earning>454.80</earning>
  </record></record>

回答1:


Look at this JIRA Ticket, the issue is not fixed yet in spring batch. However there is work around for this.

Add maven dependency.

<dependency>
    <groupId>net.java.dev.stax-utils</groupId>
    <artifactId>stax-utils</artifactId>
    <version>20070216</version>
</dependency>

Create a custom class.

public class IndentingStaxEventItemWriter <T> extends StaxEventItemWriter<T> {

      private boolean indenting = true;

      @Override
      protected XMLEventWriter createXmlEventWriter( XMLOutputFactory outputFactory, Writer writer) throws XMLStreamException {
        if (indenting) {
          return new IndentingXMLEventWriter( super.createXmlEventWriter( outputFactory, writer ) );
        }
        else {
          return super.createXmlEventWriter( outputFactory, writer );
        }
      }

    public boolean isIndenting() {
        return indenting;
    }

    public void setIndenting(boolean indenting) {
        this.indenting = indenting;
    }

}

Modify your EventWriter

<bean id="xmlItemWriter" class="com.kp.IndentingStaxEventItemWriter">
    <property name="resource" value="file:outputs/report.xml" />
    <property name="encoding" value="ISO-8859-1" />
    <property name="version" value="1.0" />
    <property name="marshaller" ref="reportMarshaller" />
    <property name="rootTagName" value="record" />
    <!-- TRUE means, that output file will be overwritten if exists - default is TRUE -->
    <property name="overwriteOutput" value="true" />
</bean>


来源:https://stackoverflow.com/questions/41566545/the-xml-output-from-the-spring-batch-jaxb2marshaller-marshaller-jaxb-formatted

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!