Jax-WS - To Remove Empty Tags from Request XML

jax-ws, jaxb, moxy, web-services, xml

Solution

Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB (JSR-222) expert group.

By default MOXy like other JAXB implementations will not marshal an element for null values:

- http://blog.bdoughan.com/2012/04/binding-to-json-xml-handling-null.html

POSSIBLE PROBLEM

I believe the `strIpAddress` property is not null, but contains a value of empty String (""). This would cause the empty element to be written out.

Root

package forum11215485;

import javax.xml.bind.annotation.*;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Root {

    String nullValue;
    String emptyStringValue;
    String stringValue;

}

Demo

package forum11215485;

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.nullValue = null;
        root.emptyStringValue = "";
        root.stringValue = "Hello World";

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

}

Output

Note how there is no element marshalled out for the `nullValue` field, and the `emptyStringValue` field is marshalled as an empty element.

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <emptyStringValue></emptyStringValue>
   <stringValue>Hello World</stringValue>
</root>

SOLUTION #1 - Ensure the property is set to null and not ""

SOLUTION #2 - Write an XmlAdapter that converts "" to null

An `XmlAdapter` is a JAXB mechanism that allows an object to be marshalled as another object.

StringAdapter

The following `XmlAdapter` will marshal empty strings as null. This will cause them not to appear in the XML representation.

package forum11215485;

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(null == v || v.length() == 0) {
            return null;
        }
        return v;
    }

}

package-info

The `XmlAdapter` is hooked in using the `@XmlJavaTypeAdapter` annotation. Below is an example of hooking it in at the package level so that it applies to a fields/properties of type String within the package. For more information see: http://blog.bdoughan.com/2012/02/jaxb-and-package-level-xmladapters.html

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

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

Output

Now the output from running the demo code is the following:

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <stringValue>Hello World</stringValue>
</root>

Problem

I'm trying to consume a web service exposed by a provider. The Provider has a strict checking at his end that the request xml should not contain tags which don't have values. I'm using Jax-WS. If i don't set value in a particular object, it is being sent as empty tag and the tag is present. PFB the example illustrating my issue. Client XML : ``` <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:host="http://host.testing.webservice.com/"> <soapenv:Header/> <soapenv:Body> <host:testingMathod> <arg0> <PInfo> <IAge>45</IAge> <strName>Danny</strName> </PInfo> <strCorrId>NAGSEK</strCorrId> <strIpAddress></strIpAddress> </arg0> </host:testingMathod> </soapenv:Body> </soapenv:Envelope> ``` In this, the value for IpAddress is not been given and hence the empty tag is been sent. Hence kindly let us me know what needs to be done to remove the empty tags in request xml. Is Handlerchain is the only solution for the same? Thanks, Naveen.

Original source

Related problems