简体   繁体   中英

multiple json bindings in java

Java has several XML binding frameworks that map Java objects into XML and back. These frameworks allows one to map various Java hierarchies and classes into the chosen XML structure. They can be configured through a separate configuration file. These frameworks include Castor, JiBX and the like. Other frameworks can be configured programmatically.

Most JSON binding frameworks simply map the Java object directly into json. Most do not extend the flexibility of mapping complex Java hierarchies into any arbitrary chosen JSON object representation. The configuration is usually pretty limited.

I'm currently trying to build a web service that returns json responses. If my Java domain classes changes in any way, my json responses will change as well, causing any service clients, expecting the old version of json responses, to break.

Are there any fully flexible JSON binding frameworks out there that can map multiple bindings into the same set of classes?

Or (perhaps the more fundamental question is) how do I support different versions of JSON bindings on the same set of Java classes?

Or should I simply make sure my domain classes never change? (This does not sound feasible)

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

The MOXy component in EclipseLink 2.4 will contain the type of JSON binding you are looking for. In the example below an Address object is mapped to the response of running Google's Geocoding API V2 . This example demonstrates how the path based mapping eliminates the need to for close relationship between classes and JSON structure.

package blog.geocode.json;

import javax.xml.bind.annotation.XmlType;
import org.eclipse.persistence.oxm.annotations.XmlPath;

@XmlType(propOrder={"country", "state", "city", "street", "postalCode"})
public class Address {

    @XmlPath("Placemark/ns:AddressDetails/ns:Country/ns:AdministrativeArea/ns:Locality/ns:Thoroughfare/ns:ThoroughfareName/text()")
    private String street;

    @XmlPath("Placemark/ns:AddressDetails/ns:Country/ns:AdministrativeArea/ns:Locality/ns:LocalityName/text()")
    private String city;

    @XmlPath("Placemark/ns:AddressDetails/ns:Country/ns:AdministrativeArea/ns:AdministrativeAreaName/text()")
    private String state;

    @XmlPath("Placemark/ns:AddressDetails/ns:Country/ns:CountryNameCode/text()")
    private String country;

    @XmlPath("Placemark/ns:AddressDetails/ns:Country/ns:AdministrativeArea/ns:Locality/ns:PostalCode/ns:PostalCodeNumber/text()")
    private String postalCode;

}

As you mention having a separate mapping document is key to applying multiple mappings to an object model. The MOXy binding document can be leveraged for both XML and JSON binding:

You can try the JSON binding out today using one of the milestone builds:

If you are using JAXB in combination with JAX-RS (Java API for RESTful webservices), this is easy. JAX-RS (or at least Jersey , the JAX-RS reference implementation) understands JAXB annotations and to make it output JSON instead of XML you only need to change the media type of your webservice method, for example:

@GET @Path("{customerId}")
@Produces(MediaType.TEXT_XML)  // Change this to MediaType.APPLICATION_JSON
public Customer getCustomer(@PathParam("customerId") String customerId) {
    // ...
}

Where Customer is a class annotated using JAXB mapping annotations (which might refer to other classes with annotations etc.).

Good question. One I've been wrestling with myself on a little larger scale.

The problem is that serializing an object breaks encapsulation. But then, so does displaying it on a UI. But if you don't do that, what good is it?

The only solution I've been able to come up with is to create a View Object. A view object has getters and setters that allow for the externalization of the view portions of the data without any of the private data needed to do actual processing.

Problem is that this requires some duplicate coding, but it seems to prevent some long term architectural issues.

Sorry that I'm not more helpful, but this is just one of those nasty issues that software engineers will wrestle with forever.

My $.02.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM