What is the best way to convert a java object to xml with open source apis
JAXB is definitely the solution.
Why? Well, it's inside the JDK 6, so you'll never find it unmaintained.
It uses Java annotations to declare XML-related properties for classes, methods and fields.
Tutorial 1
Tutorial 2
Note: JAXB also enables you to easily 'unmarshal' XML data
(which was previously marshalled from Java object instances) back
to object instances.
One more great thing about JAXB is: It is supported by other Java-related
technologies, such as JAX-RS (a Java RESTful API, which is availible
as part of Java EE 6). JAX-RS can serve and receive JAXB
objects on the fly, without the need of marshalling/unmarshalling them.
You might want to check out Netbeans, which contains
out-of-the-box support for JAX-RS. Read this tutorial for getting started.
edit:
To marshall/unmarshall 'random' (or foreign) Java objects, JAXB
offers fairly simple possibility: One can declare an XmlAdapter
and 'wrap' existing Java classes to be JAXB-compatible.
Usage of such XmlAdapter is done by using the @XmlJavaTypeAdapter-annotation.
Simplest way to convert java objects to xml
I'd go with XStream, as your question 2 suggests.
It needs no annotations, just configuration, and can serialize simple objects out of the box.
To make the objects fit a given schema, you'd convert them to objects that closely resemble the schema first and serialize those to XML.
The XStream page also holds the tutorials you request.
Convert java object to XML REST response
- Add produces = "application/xml" inside the @RequestMapping.
@RequestMapping(value="/api", method=RequestMethod.GET, produces=application/xml")
- You need to add number of JAXB annotations to your bean class (VisaResponseHeader) to allow it to be marshalled into XML.
@XmlRootElement: This annotation is used at the top level class to indicate the root element in the XML document. The name attribute in the annotation is optional. If not specified, the class name is used as the root XML element in the document.
@XmlAttribute: This annotation is used to indicate the attribute of the root element.
@XmlElement: This annotation is used on the properties of the class which will be the sub-elements of the root element.
HelloWorldRestController .java
@RestController
public class HelloWorldRestController {
@Autowired
ApiService apiService;
@RequestMapping(value = "/api", method = RequestMethod.GET)
public ResponseEntity<String> listAllUsers() {
// get data from database
VisaResponse visaResponse = apiService.visaresponse();
// convert bean to XML
String xmlResponse = jaxbObjectToXML(visaResponse);
return new ResponseEntity<>(xmlResponse, HttpStatus.OK);
}
private static String jaxbObjectToXML(VisaResponse customer) {
String xmlString = "";
try {
JAXBContext context = JAXBContext.newInstance(VisaResponse.class);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
StringWriter sw = new StringWriter();
m.marshal(customer, sw);
xmlString = sw.toString();
} catch (JAXBException e) {
e.printStackTrace();
}
return xmlString;
}
}
VisaResponse.java
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class VisaResponse {
@XmlElement
private int id;
// for testing purpose. Remove once database integration is done and data is received via service and repository.
public VisaResponse() {
id = 3;
}
}
No need of VisaResponseHeader.java class.
Expected output(Tested using Postman)
Convert Java object to XML
Background Info (From Related Question)
From the comment you made on my answer to your previous question the domain model is already being used with JAXB. The easiest way to have your client and server communicate via XML is to leverage the already annotated model on both ends.
I just have checked the source code of
my client. In the process, we need to
convert back a xml file which is
generated from java objects to xml
file using: javax.xml.bind.JAXBContext
& javax.xml.bind.Marshaller. so my
question is it possible to read back
the xml file to the same java objects?
then we can use the java objects for a
further step. Thanks in advance!
UPDATE
It appears as though your issue is due to having a domain model that is defined through interfaces with backing implementation classes. Below I'll demonstrate how you can handle this using a JAXB implementation (Metro, MOXy, JaxMe, etc).
Demo Code
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(CustomerImpl.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("input.xml");
Customer customer = (Customer) unmarshaller.unmarshal(xml);
Address address = customer.getAddress();
System.out.println(address.getStreet());
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(customer, System.out);
}
}
Interface Model
The following interfaces represent our domain model. These interfaces when not be leveraged to bootstrap the JAXBContext.
Customer
public interface Customer {
public Address getAddress();
public void setAddress(Address address);
}
Address
public interface Address {
public String getStreet();
public void setStreet(String street);
}
Implementation Classes
The implementation classes are what will be mapped to XML using JAXB.
CustomerImpl
Note in the CustomerImpl
class we use the @XmlElement
annotation on the address
property to specify the type is AddressImpl
.
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name="customer")
public class CustomerImpl implements Customer {
private Address address;
@XmlElement(type=AddressImpl.class)
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
}
AddressImpl
public class AddressImpl implements Address {
private String street;
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
}
input.xml
<?xml version="1.0" encoding="UTF-8"?>
<customer>
<address>
<street>1 Any Street</street>
</address>
</customer>
Converting java object to xml
I'm not familiar with @TypeConverter
, but looks that that is an EclipseLink feature for JPA. In the end it has this JavaDoc on the @Convert
:
/**
* Constant name for the reserved XML converter.
* This will use JAXB to convert the object to and from XML.
*/
public static final String XML = "xml";
So, it still would require from you a JaxB Marshaller
to be configured.
Not sure from here why do you ask about Spring Integration if your end goal is JPA...
Anyway: the best way to convert object to XML in Spring Integration is indeed use a MarshallingTransformer
which could be configured with any org.springframework.oxm.Marshaller
impl, not only JaxB.
If you are looking for some conversion way in between, you may also look into MappingJackson2MessageConverter
when you inject an XmlMapper
from Jackson lib.
For better assisting you, we definitely need to know more about your use-case and what and how you'd like to marshal into an XML.
Suggesstion needed for persisting java objects to xml
Take a look at this question which discusses libraries (such as JAXB and XStream) you can use to convert Java objects to XML.
What is the best way to convert a java object to xml with open source apis
Converting JSON to XML in Java
Use the (excellent) JSON-Java library from json.org then
JSONObject json = new JSONObject(str);
String xml = XML.toString(json);
toString
can take a second argument to provide the name of the XML root node.
This library is also able to convert XML to JSON using XML.toJSONObject(java.lang.String string)
Check the Javadoc
Link to the the github repository
POM
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20160212</version>
</dependency>
original post updated with new links
Generate XML from a class with JAVA
XStream will allow you to represent any class as an XML. You can check here for an example.
How to convert List of Object to XML doc using XStream
You don't necessarily need a CustomConverter.
You need a class to hold your list:
public class PersonList {
private List<Person> list;
public PersonList(){
list = new ArrayList<Person>();
}
public void add(Person p){
list.add(p);
}
}
To serialise the list to XML:
XStream xstream = new XStream();
xstream.alias("person", Person.class);
xstream.alias("persons", PersonList.class);
xstream.addImplicitCollection(PersonList.class, "list");
PersonList list = new PersonList();
list.add(new Person("ABC",12,"address"));
list.add(new Person("XYZ",20,"address2"));
String xml = xstream.toXML(list);
To deserialise xml to a list of person objects:
String xml = "<persons><person>...</person></persons>";
PersonList pList = (PersonList)xstream.fromXML(xml);
Related Topics
Java: Infinite Loop Using Scanner In.Hasnextint()
Problems Resteasy 3.09 Corsfilter
Can Someone Please Explain Me @Mapsid in Hibernate
How to Mix --Class-Path and --Module-Path in Javac (Jdk 9)
How to Specify the Default Jvm Arguments for Programs I Run from Eclipse
Java: Why am I Required to Initialize a Primitive Local Variable
Efficient Way to Divide a List into Lists of N Size
Accessing Kotlin Extension Functions from Java
Parsing Dates of the Format "January 10Th, 2010" in Java? (With Ordinal Indicators, St|Nd|Rd|Th)
If Parenthesis Has a Higher Precedence Then Why Is Increment Operator Solved First
Using Ntlm Authentication in Java Applications
How Does System.Out.Print() Work
How Does the Enhanced for Statement Work for Arrays, and How to Get an Iterator for an Array
Java.Sql.Sqlexception: No Suitable Driver Found for Jdbc:Mysql://Localhost:3306/Dbname