spring-projects / spring-batch

Spring Batch is a framework for writing batch applications using Java and Spring
http://projects.spring.io/spring-batch/
Apache License 2.0
2.7k stars 2.33k forks source link

StaxEventItemWriter fails to create formatted output [BATCH-1835] #1754

Open spring-projects-issues opened 12 years ago

spring-projects-issues commented 12 years ago

Oliver Theissen opened BATCH-1835 and commented

A Jaxb2Marshaller used in a StaxEventItemWriter fails to create formatted XML output (one element per line, ident lines) even if the Jaxb2Marshaller has been configured to do so. See the sample application (STS project, maven build) to reproduce: this application reads some sample data from a csv file in data/in and creates two XML files in the directory data/out: one XML file created by a StaxEventItemWriter and the other created by a "home made" XmlItemWriter. Both ItemWriters use the same Jaxb2Marshaller bean for marshalliung but produce different output: the output of the StaxEventItemWriter fails to be formatted.


Affects: 2.1.8

Reference URL: http://forum.springsource.org/archive/index.php/t-69570.html

Attachments:

4 votes, 10 watchers

spring-projects-issues commented 11 years ago

David J. M. Karlsen commented

Any chance of getting this fixed?

spring-projects-issues commented 11 years ago

Jimmy Praet commented

There is no standard support for XML formatting in stax. But a third-party library called stax-utils (https://java.net/projects/stax-utils/) does provide this functionality (with javanet.staxutils.IndentingXMLEventWriter).

If you really need this you could extend StaxEventItemWriter and override the createXmlEventWriter method to return an IndentingXMLEventWriter.

spring-projects-issues commented 11 years ago

David J. M. Karlsen commented

Yes, this is what I ended up with if the project wants it:

+import java.io.Writer;
+
+import javanet.staxutils.IndentingXMLEventWriter;
+
+import javax.xml.stream.XMLEventWriter;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
+
+import org.springframework.batch.item.xml.StaxEventItemWriter;
+
+
+public class ExtendedStaxEventItemWriter<T>
+    extends StaxEventItemWriter<T>
+{
+    
+    public void setIndenting( boolean indenting )
+    {
+        this.indenting = indenting;
+    }
+    
+    public boolean isIndenting()
+    {
+        return indenting;
+    }
+    
+    @Override
+    protected XMLEventWriter createXmlEventWriter( XMLOutputFactory outputFactory, Writer writer )
+        throws XMLStreamException
+    {
+        if ( isIndenting() ) {
+            return new IndentingXMLEventWriter( super.createXmlEventWriter( outputFactory, writer ) );
+        }
+        else {
+            return super.createXmlEventWriter( outputFactory, writer );
+        }
+    }
+
+}
spring-projects-issues commented 11 years ago

Sebastien Lorber commented

Check also this issue: https://jira.springsource.org/browse/BATCH-2113

spring-projects-issues commented 9 years ago

Smail Louahchi commented

Please check, if its possible to add prettyPrint Feature to StaxEventItemWriter with IndentingXMLEventWriter.

In my CustomStaxEventItemWriter the user has the choice with an boolean flag for pretty print. The close method only requires an CR/LF for the end tag in mode 'prettyPrint'.

<dependency>
    <groupId>net.java.dev.stax-utils</groupId>
    <artifactId>stax-utils</artifactId>
    <version>20040917</version>
</dependency>
private boolean prettyPrint = false;
...
public void setPrettyPrint(boolean prettyPrint)
{
    this.prettyPrint = prettyPrint;
}
...
protected XMLEventWriter createXmlEventWriter(XMLOutputFactory outputFactory, Writer writer) throws XMLStreamException
{
    XMLEventWriter result = outputFactory.createXMLEventWriter(writer);
    if (prettyPrint)
    {
        return new IndentingXMLEventWriter(result);
    }
    return result;
}
...
public void close() {
    super.close();

    XMLEventFactory factory = createXmlEventFactory();
    try {
        delegateEventWriter.add(factory.createCharacters(prettyPrint ? "\n" : ""));
    }
...
<bean id="staxItemWriter" class="org.springframework.batch.item.xml.StaxEventItemWriter">
    ...
    <property name="prettyPrint" value="true" />
</bean>
spring-projects-issues commented 7 years ago

Ketan Prajapati commented

@Smail, thanks for possible solution. It is helping to generate pretty printed XML but it has a side effect as mentioned in https://jira.springsource.org/browse/BATCH-2113. because StaxEventItemWriter is not working fine when using IndentingXMLEventWriter.

When I am trying hacks mentioned in https://jira.springsource.org/browse/BATCH-2113 along with your solution, it is working fine for me but had to leave restart ability on risk which is not ideal solution.

spring-projects-issues commented 6 years ago

Vishal Pawar commented

Thanks all for the info on this issue. Do we have a better solution for this since last discussed

GregBragg commented 1 year ago

Vishal Pawar commented

Thanks all for the info on this issue. Do we have a better solution for this since last discussed

I'm wondering the same thing as I recently ran into this exact same issue.

GregBragg commented 1 year ago

Smail Louahchi commented

Please check, if its possible to add prettyPrint Feature to StaxEventItemWriter with IndentingXMLEventWriter.

In my CustomStaxEventItemWriter the user has the choice with an boolean flag for pretty print. The close method only requires an CR/LF for the end tag in mode 'prettyPrint'.

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

The dependency to the Bea jar is no longer in the Maven repo, however it is not needed with the latest JDKs as the dependent APIs are already included. This works for me for the code that Sebastien Lorber provided in https://github.com/spring-projects/spring-batch/issues/1484.

        <dependency>
            <groupId>net.java.dev.stax-utils</groupId>
            <artifactId>stax-utils</artifactId>
            <version>20070216</version>
            <exclusions>
                <exclusion>
                    <groupId>com.bea.xml</groupId>
                    <artifactId>jsr173-ri</artifactId>
                </exclusion>
            </exclusions>
        </dependency>