将 Java 对象转换为 XML 字符串
Posted
技术标签:
【中文标题】将 Java 对象转换为 XML 字符串【英文标题】:Convert Java object to XML string 【发布时间】:2015-01-13 13:50:57 【问题描述】:是的,是的,我知道有人就这个话题提出了很多问题。但我仍然找不到解决问题的方法。我有一个属性注释的 Java 对象。例如客户,like in this example。我想要它的字符串表示。 Google 建议将 JAXB 用于此类目的。但在所有示例中,创建的 XML 文件都会打印到文件或控制台,如下所示:
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);
但我必须使用这个对象并以 XML 格式通过网络发送。所以我想得到一个代表 XML 的字符串。
String xmlString = ...
sendOverNetwork(xmlString);
我该怎么做?
【问题讨论】:
【参考方案1】:您可以使用以Writer 作为参数的编组器方法进行编组:
marshal(Object,Writer)
并传递一个可以构建字符串对象的实现
直接已知的子类: BufferedWriter, CharArrayWriter, FilterWriter, OutputStreamWriter, PipedWriter, PrintWriter, StringWriter
调用它的toString方法来获取实际的String值。
这样做:
StringWriter sw = new StringWriter();
jaxbMarshaller.marshal(customer, sw);
String xmlString = sw.toString();
【讨论】:
StringWriter
已经很老了。在幕后,它使用StringBuffer
,其中更快的方法是使用StringBuilder
,但在第一次制作StringWriter时并不存在。因此,每次调用sw.toString()
都意味着同步。如果您正在寻找性能,那就太糟糕了。
@peterh 这里的所有答案都使用 StringWriter。你会建议什么?
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);使用它来获取 XML 的确切结构。
对于 org.springframework.oxm.jaxb.Jaxb2Marshaller,您可以使用:final StringResult result = new StringResult(); jaxb2Marshaller.marshal(customer, result); String xmlString = result.toString();
【参考方案2】:
一个方便的选择是使用javax.xml.bind.JAXB:
StringWriter sw = new StringWriter();
JAXB.marshal(customer, sw);
String xmlString = sw.toString();
[reverse] 过程(解组)将是:
Customer customer = JAXB.unmarshal(new StringReader(xmlString), Customer.class);
在这种方法中不需要处理已检查的异常。
【讨论】:
这不会复制只有 getter 的字段【参考方案3】:正如 A4L 提到的,你可以使用 StringWriter。此处提供示例代码:
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;
【讨论】:
StringWriter 中不需要 m.marshal(customer, System.out);【参考方案4】:您可以将其编组为 StringWriter
并抓住其字符串。来自toString()
。
【讨论】:
@KickButtowski:答案的基本部分就是使用StringWriter
。该链接只是文档。
请添加一些解释,很高兴我删除了我的反对票。 :) 你可以把它作为评论放在旁边
你能提供一个例子吗?
@Bob:创建一个StringWriter
,将其传递给marshal()
,调用toString()
。
@Bob 这个答案实际上就足够了。请学习如何研究 API,在这个例子中 Marshaller
有几个 marshal 重载方法,只要看看它们的参数和它们的作用,你就会找到答案。【参考方案5】:
测试和工作 Java 代码将 java 对象转换为 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);
【讨论】:
一般添加只包含代码而没有解释的答案是不被接受的【参考方案6】:在 Java 中将 Object 转换为 XML
客户.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);
试试这个例子..
【讨论】:
【参考方案7】:使用 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();
【讨论】:
【参考方案8】:我采用了 JAXB.marshal 实现并添加了 jaxb.fragment=true 以删除 XML 序言。即使没有 XmlRootElement 批注,此方法也可以处理对象。这也会引发未经检查的 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);
如果编译器警告困扰您,这里是模板化的两个参数版本。
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);
【讨论】:
【参考方案9】:这是一个用于编组和解组对象的实用程序类。在我的例子中,它是一个嵌套类,所以我将它设为静态 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();
【讨论】:
【参考方案10】:下面是Java类的一个例子,不同的注释集生成xml,CDATA和JaxB代码生成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;
适配器类
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;
生成 XML 的 JAXB 代码
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,sw);
return sw.toString();
Above Code 将生成如下所示的 xml
<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>
【讨论】:
【参考方案11】:创建 XML Stirng 的一些通用代码
object --> 是将其转换为 XML 的 Java 类name --> 只是名称空间之类的东西 - 用于区分
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;
【讨论】:
【参考方案12】:Underscore-java 可以在构建器的帮助下构造 XML 字符串。
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>
【讨论】:
【参考方案13】: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();
【讨论】:
【参考方案14】:使用此函数将 Object 转换为 xml 字符串 (应该叫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;
使用此函数将xml字符串转换回Object -->
(应该叫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;
【讨论】:
以上是关于将 Java 对象转换为 XML 字符串的主要内容,如果未能解决你的问题,请参考以下文章