Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p><strong>Note:</strong> I'm the <a href="http://www.eclipse.org/eclipselink/moxy.php"><strong>EclipseLink JAXB (MOXy)</strong></a> lead and a member of the <a href="http://jcp.org/en/jsr/detail?id=222"><strong>JAXB (JSR-222)</strong></a> expert group.</p> <p>What you have done is right, the error you are seeing is due to what I believe is a bug in the <a href="http://jaxb.java.net/"><strong>JAXB reference implementation</strong></a>. The JAXB RI should be able to handle a null value being returned from an <code>XmlAdapter</code>. This use case works with EclipseLink JAXB (MOXy), I'll demonstrate below with an example.</p> <p><strong>StringAdapter</strong></p> <p>Below is an implmentation that does approximately what the one that you will get after you generate your Java model from the XML schema (see <a href="http://blog.bdoughan.com/2011/08/xml-schema-to-java-generating.html">http://blog.bdoughan.com/2011/08/xml-schema-to-java-generating.html</a>).</p> <pre><code>package forum11894193; import javax.xml.bind.annotation.adapters.XmlAdapter; public class StringAdapter extends XmlAdapter&lt;String, String&gt; { @Override public String marshal(String string) throws Exception { if("".equals(string)) { return null; } return string; } @Override public String unmarshal(String string) throws Exception { return string; } } </code></pre> <p><strong>package-info</strong></p> <p>Since you are registering a global adapter, it will be referenced from a <code>package-info</code> class like the one below (see: <a href="http://blog.bdoughan.com/2012/02/jaxb-and-package-level-xmladapters.html">http://blog.bdoughan.com/2012/02/jaxb-and-package-level-xmladapters.html</a>).</p> <pre><code>@XmlJavaTypeAdapters({ @XmlJavaTypeAdapter(value=StringAdapter.class, type=String.class) }) package forum11894193; import javax.xml.bind.annotation.adapters.*; </code></pre> <p><strong>Root</strong></p> <p>Below is a sample domain class with a few <code>String</code> fields. Since the <code>XmlAdapter</code> was registered at the package level it will apply to all mapped String fields/properties in that package.</p> <pre><code>package forum11894193; import javax.xml.bind.annotation.*; @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) public class Root { String a; String b; String c; } </code></pre> <p><strong>Demo</strong></p> <p>In the demo code below we'll create an instance of <code>Root</code> set a couple of the fields to <code>""</code> and then marshal it to XML.</p> <pre><code>package forum11894193; import javax.xml.bind.*; public class Demo { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(Root.class); Root root = new Root(); root.a = ""; root.b = "b"; root.c = ""; Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.marshal(root, System.out); } } </code></pre> <p><strong>Output Using JAXB RI</strong></p> <p>Using the JAXB RI with this example results in a NPE. The stack trace is different, but most likely to us using different marshal methods. I am also using the version of the JAXB RI included in the JDK which is repackaged to <code>com.sun.xml.internal.bind.v2</code>.</p> <pre><code>Exception in thread "main" java.lang.NullPointerException at com.sun.xml.internal.bind.v2.runtime.output.Encoded.setEscape(Encoded.java:96) at com.sun.xml.internal.bind.v2.runtime.output.UTF8XmlOutput.doText(UTF8XmlOutput.java:294) at com.sun.xml.internal.bind.v2.runtime.output.UTF8XmlOutput.text(UTF8XmlOutput.java:283) at com.sun.xml.internal.bind.v2.runtime.output.IndentingUTF8XmlOutput.text(IndentingUTF8XmlOutput.java:141) at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.leafElement(XMLSerializer.java:293) at com.sun.xml.internal.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl$1.writeLeafElement(RuntimeBuiltinLeafInfoImpl.java:179) at com.sun.xml.internal.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl$1.writeLeafElement(RuntimeBuiltinLeafInfoImpl.java:166) at com.sun.xml.internal.bind.v2.runtime.reflect.TransducedAccessor$CompositeTransducedAccessorImpl.writeLeafElement(TransducedAccessor.java:239) at com.sun.xml.internal.bind.v2.runtime.property.SingleElementLeafProperty.serializeBody(SingleElementLeafProperty.java:87) at com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:306) at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.childAsSoleContent(XMLSerializer.java:561) at com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.serializeRoot(ClassBeanInfoImpl.java:290) at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.childAsRoot(XMLSerializer.java:462) at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:314) at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:243) at javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(AbstractMarshallerImpl.java:75) at forum11894193.Demo.main(Demo.java:17) </code></pre> <p><strong>Output Using EclipseLink JAXB (MOXy)</strong></p> <p>When MOXy is used as the JAXB provider you get the desired output. For information on specifying MOXy as your JAXB provider see: <a href="http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html">http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html</a>.</p> <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;root&gt; &lt;b&gt;b&lt;/b&gt; &lt;/root&gt; </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload