3

I am trying to make JAXB do not marshal empty tags when string is empty. I can make it by creating XmlAdapter where insted empty string null would be returned. But in that way, I will have to annotate each attribute with this adapter.

Is there any way to make it more global?

1 Answer 1

1

EclipseLink JAXB (MOXy) will let you specify the XmlAdapter for java.lang.String at the package level (I'm the MOXy tech lead):

package-info

@XmlJavaTypeAdapter(value=StringAdapter.class, type=String.class)
package example;

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

StringAdapter

package example;

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

public class StringAdapter extends XmlAdapter<String, String> {

    @Override
    public String unmarshal(String v) throws Exception {
        return v;
    }

    @Override
    public String marshal(String v) throws Exception {
        if("".equals(v)) {
            return null;
        }
        return v;
    }

}

Root

package example;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Root {

    private String foo;
    private String bar;

    public String getFoo() {
        return foo;
    }

    public void setFoo(String foo) {
        this.foo = foo;
    }

    public String getBar() {
        return bar;
    }

    public void setBar(String bar) {
        this.bar = bar;
    }

}

jaxb.properties

To use MOXy as your JAXB provider you need to include a file named jaxb.properties in the same package as your model classes with the following entry:

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

Demo

package example;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Root.class);
        System.out.println(jc);

        Root root = new Root();
        root.setFoo("");
        root.setBar("");

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(root, System.out);
    }

}

Note

Due to what I feel is a bug in the JAXB reference implementation, the following exception is thrown if you use the version of JAXB included in Java SE 6:

Exception in thread "main" java.lang.NullPointerException
    at com.sun.xml.bind.v2.runtime.output.Encoded.setEscape(Encoded.java:107)
    at com.sun.xml.bind.v2.runtime.output.UTF8XmlOutput.doText(UTF8XmlOutput.java:315)
    at com.sun.xml.bind.v2.runtime.output.UTF8XmlOutput.text(UTF8XmlOutput.java:299)
    at com.sun.xml.bind.v2.runtime.output.IndentingUTF8XmlOutput.text(IndentingUTF8XmlOutput.java:153)
    at com.sun.xml.bind.v2.runtime.XMLSerializer.leafElement(XMLSerializer.java:325)
    at com.sun.xml.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl$1.writeLeafElement(RuntimeBuiltinLeafInfoImpl.java:210)
    at com.sun.xml.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl$1.writeLeafElement(RuntimeBuiltinLeafInfoImpl.java:209)
    at com.sun.xml.bind.v2.runtime.reflect.TransducedAccessor$CompositeTransducedAccessorImpl.writeLeafElement(TransducedAccessor.java:250)
    at com.sun.xml.bind.v2.runtime.property.SingleElementLeafProperty.serializeBody(SingleElementLeafProperty.java:98)
    at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:340)
    at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsSoleContent(XMLSerializer.java:593)
    at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeRoot(ClassBeanInfoImpl.java:324)
    at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsRoot(XMLSerializer.java:494)
    at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:315)
    at com.sun.xml.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:244)
    at javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(AbstractMarshallerImpl.java:75)
    at example.Demo.main(Demo.java:18)
Sign up to request clarification or add additional context in comments.

3 Comments

Hi Blaise, your solution might work, but I got just following exception you mentioned :D.. How to overcome it?
@meduoliai - You will need to use an alternate JAXB implementation such as MOXy (I'm the tech lead). MOXy can be obtained from here: eclipse.org/eclipselink/moxy.php, for instructions on specifying MOXy as the JAXB provider see: bdoughan.blogspot.com/2011/05/…
Very strange, it generates empty tag even if XmlAdapter returns null value

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.