Trim all values in generated XML using Jaxb

In this post we will see how we can remove leading and trailing spaces from values while converting Java objects to XML using Jaxb. We will also replace empty String values with Null so that they are not exported to XML.

Implementation:

First of all, we need to create a custom adapter that will remove all leading and trailing spaces from a String value and if the resulting values is an empty String ("") then it will replace that with Null.

TrimStringToNullXmlAdapter.java

package com.blogspot.devnip.jaxb;

import javax.xml.bind.annotation.adapters.XmlAdapter;

import static java.util.Objects.isNull;

/**
 * Trim all string values while converting to XML, and replace empty Strings with Null.
 * Null values will be excluded from generated XML
 */
public class TrimStringToNullXmlAdapter extends XmlAdapter<String, String> {

    @Override
    public String unmarshal(String value) {
        return value;
    }

    @Override
    public String marshal(String value) {
        if (isNull(value)) {
            return null;
        }

        value = value.trim();

        if (value.length() == 0) {
            value = null;
        }

        return value;
    }
}

Now we need to add a `package-info.java` file in the package, which contains data objects.

package-info.java


@XmlJavaTypeAdapter(value = TrimStringToNullXmlAdapter.class, type = String.class)
package com.blogspot.devnip.jaxb;

import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

That's it, now if we use Jaxb to marshall objects in package defined above to XML, it will use the configured adapter and will trim all the String values to null.

XmlGenerator.java

package com.blogspot.devnip.jaxb;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import java.io.StringWriter;

/**
 * Handles XML conversion
 */
public class XmlGenerator {

    /**
     * Convert Java object to XML
     *
     * @param input
     * @return
     * @throws JAXBException
     */
    public static String serialize(Object input) throws JAXBException {
        JAXBContext contextObj = JAXBContext.newInstance(input.getClass());

        Marshaller marshallerObj = contextObj.createMarshaller();
        marshallerObj.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, false);

        StringWriter sw = new StringWriter();
        marshallerObj.marshal(input, sw);

        return sw.toString();
    }
}

Below is an example test.

XmlGeneratorTest.java

package com.blogspot.devnip.jaxb;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import javax.xml.bind.JAXBException;
import java.util.Collections;

class XmlGeneratorTest {

    private static final String TRIMMED_RESPONSE = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><Document><Name>James Smith</Name><Code>123123</Code><EmailAddresses><Value>james@test.com</Value><Type>OFFICE</Type></EmailAddresses></Document>";

    @Test
    void test() throws JAXBException {
        XMLDocument xmlDocument = new XMLDocument();
        xmlDocument.setName(" James Smith ");
        xmlDocument.setCode(" 123123 ");

        XMLEmail xmlEmail = new XMLEmail();
        xmlEmail.setType(" OFFICE ");
        xmlEmail.setValue("    james@test.com");
        xmlDocument.setEmails(Collections.singletonList(xmlEmail));

        String result = XmlGenerator.serialize(xmlDocument);

        Assertions.assertEquals(TRIMMED_RESPONSE, result);
    }
}

All the posts in this blog have a working example. Please visit our Github repository

0 comments:

Post a Comment