Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 4 years ago.
Improve this question
What is the Java analogue of .NET's XML serialization?
2008 Answer
The "Official" Java API for this is now JAXB - Java API for XML Binding. See Tutorial by Oracle. The reference implementation lives at http://jaxb.java.net/
2018 Update
Note that the Java EE and CORBA Modules are deprecated in SE in JDK9 and to be removed from SE in JDK11. Therefore, to use JAXB it will either need to be in your existing enterprise class environment bundled by your e.g. app server, or you will need to bring it in manually.
XStream is pretty good at serializing object to XML without much configuration and money! (it's under BSD license).
We used it in one of our project to replace the plain old java-serialization and it worked almost out of the box.
"Simple XML Serialization" Project
You may want to look at the Simple XML Serialization project. It is the closest thing I've found to the System.Xml.Serialization in .Net.
JAXB is part of JDK standard edition version 1.6+. So it is FREE and no extra libraries to download and manage.
A simple example can be found here
XStream seems to be dead. Last update was on Dec 6 2008.
Simple seems as easy and simpler as JAXB but I could not find any licensing information to evaluate it for enterprise use.
Worth mentioning that since version 1.4, Java had the classes java.beans.XMLEncoder and java.beans.XMLDecoder. These classes perform XML encoding which is at least very comparable to XML Serialization and in some circumstances might do the trick for you.
If your class sticks to the JavaBeans specification for its getters and setters, this method is straightforward to use and you don't need a schema. With the following caveats:
As with normal Java serialization
coding and decoding run over a InputStream and OutputStream
the process uses the familar writeObject and readObject methods
In contrast to normal Java serialization
the encoding but also decoding causes constructors and initializers to be invoked
encoding and decoding work regardless if your class implements Serializable or not
transient modifiers are not taken into account
works only for public classes, that have public constructors
For example, take the following declaration:
public class NPair {
public NPair() { }
int number1 = 0;
int number2 = 0;
public void setNumber1(int value) { number1 = value;}
public int getNumber1() { return number1; }
public void setNumber2(int value) { number2 = value; }
public int getNumber2() {return number2;}
}
Executing this code:
NPair fe = new NPair();
fe.setNumber1(12);
fe.setNumber2(13);
FileOutputStream fos1 = new FileOutputStream("d:\\ser.xml");
java.beans.XMLEncoder xe1 = new java.beans.XMLEncoder(fos1);
xe1.writeObject(fe);
xe1.close();
Would result in the following file:
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.7.0_02" class="java.beans.XMLDecoder">
<object class="NPair">
<void property="number1">
<int>12</int>
</void>
<void property="number2">
<int>13</int>
</void>
</object>
</java>
XMLBeans works great if you have a schema for your XML. It creates Java objects for the schema and creates easy to use parse methods.
If you're talking about automatic XML serialization of objects, check out Castor:
Castor is an Open Source data binding framework for Java[tm]. It's the shortest path between Java objects, XML documents and relational tables. Castor provides Java-to-XML binding, Java-to-SQL persistence, and more.
Usually I use jaxb or XMLBeans if I need to create objects serializable to XML. Now, I can see that XStream might be very useful as it's nonintrusive and has really simple api. I'll play with it soon and probably use it. The only drawback I noticed is that I can't create object's id on my own for cross referencing.
#Barak Schiller
Thanks for posting link to XStream!
Don't forget JiBX.
if you want a structured solution (like ORM) then JAXB2 is a good solution.
If you want a serialization like DOT NET then you could use Long Term Persistence of JavaBeans Components
The choice depends on use of serialization.
public static String genXmlTag(String tagName, String innerXml, String properties )
{
return String.format("<%s %s>%s</%s>", tagName, properties, innerXml, tagName);
}
public static String genXmlTag(String tagName, String innerXml )
{
return genXmlTag(tagName, innerXml, "");
}
public static <T> String serializeXML(List<T> list)
{
String result = "";
if (list.size() > 0)
{
T tmp = list.get(0);
String clsName = tmp.getClass().getName();
String[] splitCls = clsName.split("\\.");
clsName = splitCls[splitCls.length - 1];
Field[] fields = tmp.getClass().getFields();
for (T t : list)
{
String row = "";
try {
for (Field f : fields)
{
Object value = f.get(t);
row += genXmlTag(f.getName(), value == null ? "" : value.toString());
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
row = genXmlTag(clsName, row);
result += row;
}
}
result = genXmlTag("root", result);
return result;
}
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I have been working on a small app, where I need to respond with XML messages like
<response>
<message>blah</message>
</response>
I find marshalling very confusing, is there a better way or alternative to this approach?
EDIT: My question was to gain a little insight into what is better? Using marshaling/unmarshaling or some easier alternatives to that approach.
As an alternative, you can hardcode the xml tags in your output message, and add your messagge (blah) between those tags. It wouldn't be too complicated for a small message like this. Like
System.out.println("<response><message>" +
yourMessageHere + "</message></response>");
But, in case of a longer complicated message, you could very easily complicate the ordering of tags or forget to type something and it could get even frustrating.
I'd suggest trying marshalling/unmarshalling. I did it for one of my assignments, I agree it looks complicated when you start but once you get hang of it, you don't have to worry about well-formedness of your XML.
For really simple documents you can use the StAX APIs instead of building an XML String. This makes it much more difficult to introduce errors.
Demo Code
Below are the StAX calls necessary to produce the XML from your question. Just to make things interesting the message contains a character that is not valid in the XML document.
import javax.xml.stream.*;
public class StAXDemo {
public static void main(String[] args) throws Exception {
XMLOutputFactory xof = XMLOutputFactory.newFactory();
XMLStreamWriter xsw = xof.createXMLStreamWriter(System.out);
xsw.writeStartDocument();
xsw.writeStartElement("response");
xsw.writeStartElement("message");
xsw.writeCharacters("1 < 2");
xsw.writeEndDocument();
xsw.close();
}
}
Output
We see in the output that the < character is properly escaped as <.
<?xml version="1.0" ?><response><message>1 < 2</message></response>
Look at the definition of marshalling - whatever you do to produce that XML, you are marshalling the data it describes!
The real question is how to go about implementing that marshalling.
In this very simple case, you could hand roll your own Marshaller for that specific data - it could be as simple as hard coding the tags and just filling in the message, as already suggested by #BeginnerJava
public class XmlMarshaller {
public String marshal(String message) {
return "<response><message>" + message + "</message></response>";
}
}
Then, as suggested by #yshavit, you might want to make sure the message contains no extra xml tags which could break the output.
Then you might want additional features x, y and z, and for the marshaller to simultaneously juggle elephants and bowling balls for a while before returning your xml.
Here's an anthropomorphic visualisation of your marshaller at this point
Doesn't look easy, does it?
The point is, for anything but the most simple, narrow marshalling functionality, the short term pain of ramping up on a 3rd party framework like JAXB is going to be astoundingly less than the long term pain of writing, enhancing and maintaining your own implementation.
So, when you move beyond school assignments and start building more complex apps, seriously consider investing the time to learn existing frameworks and libraries for common tasks - such as JAXB for marshalling. This approach will make both your code and your productivity far better in the long run :-)
JAXB (JSR-222) is pretty easy to use. I will demonstrate below with an example.
Domain Model
JAXB doesn't require any annotations (see: http://blog.bdoughan.com/2012/07/jaxb-no-annotations-required.html), but including a root element makes things a bit easier.
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement
public class Response {
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
Demo Code
Demo
Below is all you need to do to produce the XML message. Just for fun I'm going to use a message that would break the code given by BeginnerJava.
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Response.class);
Response response = new Response();
response.setMessage("1 < 2");
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(response, System.out);
}
}
Output
In the output we see that the < character has been properly escaped as <. What's harder to see is that the XML output has been marshalled to the correct encoding.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<response>
<message>1 < 2</message>
</response>
I have done the marshalling of a JaxB java object to Json using JETTISON. But I can not marshall a simple java object (which has no annotations in it) to Json using JETTISON. I know it is possible to do it by using GSON or MOXy or some other providers.
But I like to get clear "Can we do it using JETTISON?"., If we can, How to do it?
Thanks in Advance.
Don't waste your time, this is simply not what Jettison was designed to do. Conceivably, it would have been possible to instantiate a JSONObject with your POJO and serialize it that way, but there are some issues with its code that make this next to impossible:
It requires passing in the names of the fields that will be included in the JSON.
It can only process public properties of the supplied object.
Not to mention it cannot handle nesting of any kind. Take a look at this lovely code:
Class c = object.getClass();
for (int i = 0; i < names.length; i += 1) {
try {
String name = names[i];
Field field = c.getField(name);
Object value = field.get(object);
this.put(name, value);
} catch (Exception e) {
/* forget about it */
}
}
Yep, thats the code in the constructor JSONObject(Object, String[]). I'm sure you will see the problems with it (raw access to generic objects, can only access public fields, sloppy exception handling). All in all - very bad 'serialization' code.
I know its probably not what you want to hear, but if you want to convert regular Java objects to JSON then you might want to stick with one of the more general-purpose libraries.
JAXB (JSR-222) is configuration by exception and only requires annotations where you need to override the default XML representation (Jettison converts XML StAX events to/from JSON). Instead of #XmlRootElement you can wrap your object in an instance of JAXBElement.
http://blog.bdoughan.com/2012/07/jaxb-no-annotations-required.html
The XML Schema spec defines a lot of built in data types http://www.w3.org/TR/xmlschema-2/#built-in-datatypes is there Java library which can answer questions about weather a value is a a specific data type. Something along the lines.
if(XSDValidator.isXSDDate("2012-06-12") == false) {
// return error
}
Update:
The use case for this is not in the context of XML but rather in situations where I have a a string that I want to conform to a one of the XSD types and I want a standard way to check that it conforms. For example the string could be a value I extract from an incoming JSON request, or from a URL or any other place ... etc.
Below are some classes available in the JDK/JRE that you could potentially use:
javax.xml.datatype.XMLGregorianCalendar
For date/time types you could use javax.xml.datatype.XMLGregorianCalendar which is included as part of the JDK/JRE since Java SE 5.
DatatypeFactory df = DatatypeFactory.newInstance();
XMLGregorianCalendar xgc = df.newXMLGregorianCalendar("2012-06-18");
return DatatypeConstants.DATE.equals(xgc.getXMLSchemaType());
javax.xml.bind.DatatypeConveter
There is also javax.xml.bind.DatatypeConveter that will throw an IllegalArgumentException for bad values:
DatatypeConverter.parseDate("2012-06-18");
Here is a solution that uses the Xerces parser/validator. It uses .impl classes however. Those are not part of the public API and subject to change. But if you stick to a certain version, you should be fine.
First, the dependency:
<dependency>
<groupId>xerces</groupId>
<artifactId>xerces</artifactId>
<version>2.4.0</version>
</dependency>
And here is a small program that works like you described:
import org.apache.xerces.impl.dv.InvalidDatatypeValueException;
import org.apache.xerces.impl.dv.xs.DateDV;
public class XSDValidator {
public static void main(final String[] args) {
System.out.println(isXSDDate("2012-09-18"));
System.out.println(isXSDDate("Hello World"));
}
private static boolean isXSDDate(final String string) {
try {
new DateDV().getActualValue(string);
return true;
} catch(final InvalidDatatypeValueException e) {
return false;
}
}
}
Output:
true
false
All you have to do yourself is to create methods for each of the data types. You should be able to find all the required classes in the org.apache.xerces.impl.dv.xs package.
Again, this is kind of abusing the Xerces library, as these classes are not part of the public API. So if you find another, cleaner solution, let us know.
I've developed a webservice and rightfully my users would like to see documentation. I'd prefer to simply document my code, either with javadoc comments or with an explicit annotation, e.g.
#XmlComment("This is used to [blah blah]")
#XmlElement(name = "referenceDate", namespace = NAMESPACE, type = Date.class)
public void setReferenceDate(Date referenceDate) {
this.referenceDate = referenceDate;
}
or
/**
* This is used to [blah blah]
*/
#XmlElement(name = "referenceDate", namespace = NAMESPACE, type = Date.class)
public void setReferenceDate(Date referenceDate) {
this.referenceDate = referenceDate;
}
The above aren't supported, as evidenced here:
JAXB-273 - 2006 request to make xs:documentation elements from annotations
JAXB-369 - 2007 request to make xs:documentation elements from comments
SO-470001 - "You can't do that" stackoverflow question
So I understand I can't use the above to I comment my service. But... Surely there's still a way to do so in a non-manual fashion. Must I hand-craft all my XML just for this? If that is the answer, why isn't there more attention on getting this feature into JAXB? Seems downright mandatory for an enterprise-grade webservice, right?
You're right it's poor. Most focus these days is on contract-first, so I guess it's not been prioritized. You could use XSLT to add in the comments to the WSDL from a separate XML doc. Not as good as generating it from the Java code, but better than nothing. Here's an ancient posting doing it http://www.gridlab.org/WorkPackages/wp-5/guide/wsdltips.html
Converting JSON to Java
The above question is with reference to what has been described on the above thread. There are so many API(s) which provide the flexibility to return responses either in XML or JSON. **I would like to know if there is a way to automatically construct the java bean corresponding to a JSON response. **
lets say you get an object like
[
{
"name":"Java 6 Greatest Hits",
"Author":"Jim Bob Jones",
"price":10.25
},
{
"name":"How to raise a goat",
"Author":"Sir Paxton",
"price":55.97
},
{
"name":"Snow - It is cold",
"Author":"Dr. White",
"price":9.99
}
]
And you want a class like
public class Book{
private String author;
private String name;
private Number price
}
with getters and setters
One option is to use a service like JSONGen, which will create that class. You need to use it first, and include the generated code in your project.
Another option could be dynamically generate the class using javassist or CGLib, but that class would be useless unless you use reflection to access its members, so even if it would be a class, it will behave like a really annoying Map. In no way will be better that simple using JSONObject
seems a simple Message Type Entity not meet you requirement ?
if you want convert a json to an existed and known java bean class,
many lib can do so, like
http://json-lib.sourceforge.net/apidocs/net/sf/json/class-use/JSONObject.html
JSONObject.toBean(JSONObject jsonObject, Class beanClass)
Creates a bean from a JSONObject, with a specific target class.
btw, if you are communicating with restful webservice, org.springframework.web.client.RestTemplate will help you get direct bean result
insteadof json.
if class does not exists, you need program with java reflect mechanism.
try use CGLIB ,http://cglib.sourceforge.net/, dynamic create some class like BeanMap. i wrote a simple sample,
but be ware, opearting class byte is hard and you may meet strange trouble with JVM . Strongly not encourage to do so.
public static BeanMap generateBean(JSONObject json) {
BeanGenerator generator = new BeanGenerator();
Iterator keys = json.keys();
while (keys.hasNext()) {
Object key = keys.next();
Object value = json.get(key);
Class keyClass = guessValueClass(value);
generator.addProperty(key.toString(), keyClass);
}
Object result = generator.create();
BeanMap bean = BeanMap.create(result);
keys = json.keys();
while (keys.hasNext()) {
Object key = keys.next();
Object value = json.get(key);
bean.put(key, value);
}
return bean;
}
/**
* TODO fix guess
*/
static Class guessValueClass(Object value) {
try {
Integer.parseInt(value.toString());
return Integer.class;
} catch (NumberFormatException e1) {
}
try {
Double.parseDouble(value.toString());
return Double.class;
} catch (NumberFormatException e1) {
}
return String.class;
}
I believe the main issue here is that the JSON response lacks type information and last time I checked :-) in Java you need to declare the type of a class property. So some heuristics will be needed to infer the type form the value in the JSON response.
For a related question here in SO have a look at: Generate Java class from JSON?
Yes check out http://flexjson.sourceforge.net
If you're wanting to generate Java classes from JSON, perhaps you could try Jackson. It provides a lot of JSON-related functionality, including the ability to generate bytecode from arbitrary JSON. See this blog post for details.
If you're using Jackson (the most popular library there), try
https://bitbucket.org/astav/jsontojava/wiki/Home
Its open source and anyone should be able to contribute.
Summary
A JsonToJava source class file generator that deduces the schema based on supplied sample json data and generates the necessary java data structures.
It encourages teams to think in Json first, before writing actual code.
Features
Can generate classes for an arbitrarily complex hierarchy (recursively)
Can read your existing Java classes and if it can deserialize into those structures, will do so
Will prompt for user input when ambiguous cases exist