115

Yes, yes I know that lots of questions were asked about this topic. But I still cannot find the solution to my problem. I have a property annotated Java object. For example Customer, like in this example. And I want a String representation of it. Google reccomends using JAXB for such purposes. But in all examples created XML file is printed to file or console, like this:

File file = new File("C:\\file.xml");
JAXBContext jaxbContext = JAXBContext.newInstance(Customer.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();

// output pretty printed
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

jaxbMarshaller.marshal(customer, file);
jaxbMarshaller.marshal(customer, System.out);

But I have to use this object and send over network in XML format. So I want to get a String which represents XML.

String xmlString = ...
sendOverNetwork(xmlString);

How can I do this?

15 Answers 15

143

You can use the Marshaler's method for marshaling which takes a Writer as parameter:

marshal(Object,Writer)

and pass it an Implementation which can build a String object

Direct Known Subclasses: BufferedWriter, CharArrayWriter, FilterWriter, OutputStreamWriter, PipedWriter, PrintWriter, StringWriter

Call its toString method to get the actual String value.

So doing:

StringWriter sw = new StringWriter();
jaxbMarshaller.marshal(customer, sw);
String xmlString = sw.toString();
Sign up to request clarification or add additional context in comments.

4 Comments

StringWriter is very old. Under the covers it uses StringBuffer where a much faster approach would have been to use StringBuilder but that didn't exist when StringWriter was first made. Because of this every call to sw.toString() implies synchronization. Bad if you're looking for performance.
@peterh All answers here use a StringWriter. What would you suggest instead?
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); Use this to get the exact structure of XML.
For org.springframework.oxm.jaxb.Jaxb2Marshaller you can use: final StringResult result = new StringResult(); jaxb2Marshaller.marshal(customer, result); String xmlString = result.toString();
58

A convenient option is to use javax.xml.bind.JAXB:

StringWriter sw = new StringWriter();
JAXB.marshal(customer, sw);
String xmlString = sw.toString();

The [reverse] process (unmarshal) would be:

Customer customer = JAXB.unmarshal(new StringReader(xmlString), Customer.class);

No need to deal with checked exceptions in this approach.

2 Comments

This won't copy fields that have only getters
JAXB.marshal() is really convenient. I tried around to set up a marshaller object. But it only accepts objects with @XmlRootElement annotation and causes a bunch of other problems...
36

As A4L mentioning, you can use StringWriter. Providing here example code:

private static String jaxbObjectToXML(Customer customer) {
    String xmlString = "";
    try {
        JAXBContext context = JAXBContext.newInstance(Customer.class);
        Marshaller m = context.createMarshaller();

        m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); // To format XML

        StringWriter sw = new StringWriter();
        m.marshal(customer, sw);
        xmlString = sw.toString();

    } catch (JAXBException e) {
        e.printStackTrace();
    }

    return xmlString;
}

1 Comment

no need in StringWriter m.marshal(customer, System.out);
6

You can marshal it to a StringWriter and grab its string. from toString().

5 Comments

@KickButtowski: The essential part of the answer is just to use a StringWriter. The link is just documentation.
please add some explanation and gladly I remove my down vote. :) beside you can put this as a comment
Can you provide an example usage of it?
@Bob: Create a StringWriter, pass it to marshal(), call toString().
@Bob this answer is actually sufficient. Please learn how to research the APIs, in this example Marshaller has several marshal overloaded methods, just take a look at their parameters and what they are for and you'll find out the answer.
6

To convert an Object to XML in Java

Customer.java

package com;

import java.util.ArrayList;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

/**
*
* @author ABsiddik
*/

@XmlRootElement
public class Customer {

int id;
String name;
int age;

String address;
ArrayList<String> mobileNo;


 public int getId() {
    return id;
}

@XmlAttribute
public void setId(int id) {
    this.id = id;
}

public String getName() {
    return name;
}

@XmlElement
public void setName(String name) {
    this.name = name;
}

public int getAge() {
    return age;
}

@XmlElement
public void setAge(int age) {
    this.age = age;
}

public String getAddress() {
    return address;
}

@XmlElement
public void setAddress(String address) {
    this.address = address;
}

public ArrayList<String> getMobileNo() {
    return mobileNo;
}

@XmlElement
public void setMobileNo(ArrayList<String> mobileNo) {
    this.mobileNo = mobileNo;
}


}

ConvertObjToXML.java

package com;

import java.io.File;
import java.io.StringWriter;
import java.util.ArrayList;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;

/**
*
* @author ABsiddik
*/
public class ConvertObjToXML {

public static void main(String args[]) throws Exception
{
    ArrayList<String> numberList = new ArrayList<>();
    numberList.add("01942652579");
    numberList.add("01762752801");
    numberList.add("8800545");

    Customer c = new Customer();

    c.setId(23);
    c.setName("Abu Bakar Siddik");
    c.setAge(45);
    c.setAddress("Dhaka, Bangladesh");
    c.setMobileNo(numberList);

    File file = new File("C:\\Users\\NETIZEN-ONE\\Desktop \\customer.xml");
    JAXBContext jaxbContext = JAXBContext.newInstance(Customer.class);
    Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
    jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

    jaxbMarshaller.marshal(c, file);// this line create customer.xml file in specified path.

    StringWriter sw = new StringWriter();
    jaxbMarshaller.marshal(c, sw);
    String xmlString = sw.toString();

    System.out.println(xmlString);
}

}

Try with this example..

1 Comment

Best answer normal object with @xml annotations pretty well working solution thanks
3

Testing And working Java code to convert java object to XML:

Customer.java

import java.util.ArrayList;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;


@XmlRootElement
public class Customer {

    String name;
    int age;
    int id;
    String desc;
    ArrayList<String> list;

    public ArrayList<String> getList()
    {
        return list;
    }

    @XmlElement
    public void setList(ArrayList<String> list)
    {
        this.list = list;
    }

    public String getDesc()
    {
        return desc;
    }

    @XmlElement
    public void setDesc(String desc)
    {
        this.desc = desc;
    }

    public String getName() {
        return name;
    }

    @XmlElement
    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    @XmlElement
    public void setAge(int age) {
        this.age = age;
    }

    public int getId() {
        return id;
    }

    @XmlAttribute
    public void setId(int id) {
        this.id = id;
    }
}

createXML.java

import java.io.StringWriter;
import java.util.ArrayList;

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


public class createXML {

    public static void main(String args[]) throws Exception
    {
        ArrayList<String> list = new ArrayList<String>();
        list.add("1");
        list.add("2");
        list.add("3");
        list.add("4");
        Customer c = new Customer();
        c.setAge(45);
        c.setDesc("some desc ");
        c.setId(23);
        c.setList(list);
        c.setName("name");
        JAXBContext jaxbContext = JAXBContext.newInstance(Customer.class);
        Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
        jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        StringWriter sw = new StringWriter();
        jaxbMarshaller.marshal(c, sw);
        String xmlString = sw.toString();
        System.out.println(xmlString);
    }

}

1 Comment

Generally adding answers that just include code and no explanation are frowned upon
2

Here is a util class for marshaling and unmarshaling objects. In my case it was a nested class, so I made it static JAXBUtils.

import javax.xml.bind.JAXB;
import java.io.StringReader;
import java.io.StringWriter;

public class JAXBUtils
{
    /**
     * Unmarshal an XML string
     * @param xml     The XML string
     * @param type    The JAXB class type.
     * @return The unmarshalled object.
     */
    public <T> T unmarshal(String xml, Class<T> type)
    {
        StringReader reader = new StringReader(xml);
        return javax.xml.bind.JAXB.unmarshal(reader, type);
    }

    /**
     * Marshal an Object to XML.
     * @param object    The object to marshal.
     * @return The XML string representation of the object.
     */
    public String marshal(Object object)
    {
        StringWriter stringWriter = new StringWriter();
        JAXB.marshal(object, stringWriter);
        return stringWriter.toString();
    }
}

Comments

1

Using ByteArrayOutputStream

public static String printObjectToXML(final Object object) throws TransformerFactoryConfigurationError,
        TransformerConfigurationException, SOAPException, TransformerException
{
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    XMLEncoder xmlEncoder = new XMLEncoder(baos);
    xmlEncoder.writeObject(object);
    xmlEncoder.close();

    String xml = baos.toString();
    System.out.println(xml);

    return xml.toString();
}

Comments

1

Some Generic code to create XML Stirng

object --> is Java class to convert it to XML
name --> is just name space like thing - for differentiate

public static String convertObjectToXML(Object object,String name) {
          try {
              StringWriter stringWriter = new StringWriter();
              JAXBContext jaxbContext = JAXBContext.newInstance(object.getClass());
              Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
              jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
              QName qName = new QName(object.getClass().toString(), name);
              Object root = new JAXBElement<Object>(qName,java.lang.Object.class, object);
              jaxbMarshaller.marshal(root, stringWriter);
              String result = stringWriter.toString();
              System.out.println(result);
              return result;
        }catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

Comments

1

I took the JAXB.marshal implementation and added jaxb.fragment=true to remove the XML prolog. This method can handle objects even without the XmlRootElement annotation. This also throws the unchecked DataBindingException.

public static String toXmlString(Object o) {
    try {
        Class<?> clazz = o.getClass();
        JAXBContext context = JAXBContext.newInstance(clazz);
        Marshaller marshaller = context.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true); // remove xml prolog
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); // formatted output

        final QName name = new QName(Introspector.decapitalize(clazz.getSimpleName()));
        JAXBElement jaxbElement = new JAXBElement(name, clazz, o);

        StringWriter sw = new StringWriter();
        marshaller.marshal(jaxbElement, sw);
        return sw.toString();

    } catch (JAXBException e) {
        throw new DataBindingException(e);
    }
}

If the compiler warning bothers you, here's the templated, two parameter version.

public static <T> String toXmlString(T o, Class<T> clazz) {
    try {
        JAXBContext context = JAXBContext.newInstance(clazz);
        Marshaller marshaller = context.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true); // remove xml prolog
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); // formatted output

        QName name = new QName(Introspector.decapitalize(clazz.getSimpleName()));
        JAXBElement jaxbElement = new JAXBElement<>(name, clazz, o);

        StringWriter sw = new StringWriter();
        marshaller.marshal(jaxbElement, sw);
        return sw.toString();

    } catch (JAXBException e) {
        throw new DataBindingException(e);
    }
}

Comments

1

Below is one example of Java Class, different set of annotations to generate xml, CDATA and JaxB code to generate XML.

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name="customer")
public class Customer {
   
   @XmlElement(name = "first-name")
   String firstName;
   @XmlElement(name = "last-name")
   String lastName;
   
   @XmlElement(name= "customer-address")
   private Address address;
   
   @XmlElement(name= "bio")
   @XmlJavaTypeAdapter(AdapterCDATA.class)
   private Biography bio;
}


@XmlAccessorType(XmlAccessType.FIELD)
public class Address {
   
   @XmlElement(name = "house-number")
   String houseNumber;
   @XmlElement(name = "address-line-1")
   String addLine1;
   
   @XmlElement(name = "address-line-2")
   String addLine2;
   
  }

 

Adaptor Class

    public class AdaptorCDATA extends XmlAdapter<String, String> {

    @Override
    public String marshal(String arg0) throws Exception {
        return "<![CDATA[" + arg0 + "]]>";
    }
    @Override
    public String unmarshal(String arg0) throws Exception {
        return arg0;
    }
}

JAXB code to generat XML

  public String xmlStringForCustomer(Customer customer) {
 
   JAXBContext jaxbContext = JAXBContext.newInstance(Customer.class);
    Marshaller marshaller = jaxbContext.createMarshaller();
    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
    
    StringWriter writer = new StringWriter();
    marshaller.marshal(customer,writer);
    return writer.toString();
}

Above Code will generate an xml like below

<customer>
 <first-name></first-name>
 <last-name></last-name>
 <customer-address> 
     <house-number></house-number>
     <address-line-1></address-line-1>
     <address-line-2></address-line-2>
 </customer-address>
 <bio>
   <![CDATA[ **bio data will come here**]]>
 </bio>
< /customer>

2 Comments

What is sw? marshaller.marshal(customer,sw)??
Corrected the code snippet, sw meant to be the variable name for StringWriter, which was called writer in one line and sw in other 2 lines.
1

If you use the Spring Webservices framework you can use org.springframework.oxm.jaxb.Jaxb2Marshaller:

final StringResult result = new StringResult();
jaxb2Marshaller.marshal(customer, result);
String xmlString = result.toString();

Comments

0

Underscore-java can construct XML string with help of a builder.

    class Customer {
        String name;
        int age;
        int id;
    }
    Customer customer = new Customer();
    customer.name = "John";
    customer.age = 30;
    customer.id = 12345;

    String xml = U.objectBuilder().add("customer", U.objectBuilder()
        .add("name", customer.name)
        .add("age", customer.age)
        .add("id", customer.id)).toXml();

    // <?xml version="1.0" encoding="UTF-8"?>
    //    <customer>
    //      <name>John</name>
    //      <age number="true">30</age>
    //      <id number="true">12345</id>
    //    </customer>

Comments

-1
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;

private String generateXml(Object obj, Class objClass) throws JAXBException {
        JAXBContext jaxbContext = JAXBContext.newInstance(objClass);
        Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
        jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        StringWriter sw = new StringWriter();
        jaxbMarshaller.marshal(obj, sw);
        return sw.toString();
    }

Comments

-1

Use this function to convert Object to xml string (should be called as convertToXml(sourceObject, Object.class); )-->

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.namespace.QName;

public static <T> String convertToXml(T source, Class<T> clazz) throws JAXBException {
    String result;
    StringWriter sw = new StringWriter();
    JAXBContext jaxbContext = JAXBContext.newInstance(clazz);
    Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
    jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
    QName qName = new QName(StringUtils.uncapitalize(clazz.getSimpleName()));
    JAXBElement<T> root = new JAXBElement<T>(qName, clazz, source);
    jaxbMarshaller.marshal(root, sw);
    result = sw.toString();
    return result;
}

Use this function to convert xml string to Object back --> (should be called as createObjectFromXmlString(xmlString, Object.class))

public static <T> T createObjectFromXmlString(String xml, Class<T> clazz) throws JAXBException, IOException{

    T value = null;
    StringReader reader = new StringReader(xml); 
    JAXBContext jaxbContext = JAXBContext.newInstance(clazz);
    Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
    JAXBElement<T> rootElement=jaxbUnmarshaller.unmarshal(new StreamSource(reader),clazz);
    value = rootElement.getValue();
    return value;
}

Comments

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.