I'm trying to deserialize Json result from a web service into POJO.
ClientResource clientResource = new ClientResource("http://itunes.apple.com/search?term=marc+jordan&media=music&entity=album");
AlbumInfoResource resource = clientResource.wrap(AlbumInfoResource.class);
AlbumInfo albumInfo = resource.retrieve();
The resulting albumInfo is null, no exception is thrown.
I'm new to Restlet, what I'm doing wrong?
Interface:
public interface AlbumInfoResource {
#Get
public AlbumInfo retrieve();
}
The Json result from the web service looks like this:
{
"resultCount": 49,
"results": [
{
"wrapperType": "collection",
"collectionType": "Album",
"artistId": 771969,
"collectionId": 205639995,
"amgArtistId": 4640,
"artistName": "Marc Jordan",
"collectionName": "This Is How Men Cry",
"collectionCensoredName": "This Is How Men Cry",
"artistViewUrl": "http://itunes.apple.com/us/artist/marc-jordan/id771969?uo=4",
"collectionViewUrl": "http://itunes.apple.com/us/album/this-is-how-men-cry/id205639995?uo=4",
"artworkUrl60": "http://a5.mzstatic.com/us/r30/Music/cd/3f/13/mzi.rxpvpvdd.60x60-50.jpg",
"artworkUrl100": "http://a1.mzstatic.com/us/r30/Music/cd/3f/13/mzi.rxpvpvdd.100x100-75.jpg",
"collectionPrice": 9.9,
"collectionExplicitness": "notExplicit",
"trackCount": 10,
"copyright": "1999 Cafe Productions Inc.",
"country": "USA",
"currency": "USD",
"releaseDate": "2006-11-07T08:00:00Z",
"primaryGenreName": "Jazz"
},
...
...
}
]
}
The AlbumInfo class:
public class AlbumInfo implements Serializable {
private static final long serialVersionUID = 1L;
private int _resultCount;
private ArrayList<Album> _albums;
public AlbumInfo() {
_albums = new ArrayList<Album>();
}
public AlbumInfo(int resultCount, ArrayList<Album> albums) {
_resultCount = resultCount;
_albums = albums;
}
public int getResultCount() {
return _resultCount;
}
public void setResultCount(int resultCount) {
_resultCount = resultCount;
}
public ArrayList<Album> getAlbums() {
return _albums;
}
public void setAlbums(ArrayList<Album> _albums) {
this._albums = _albums;
}
}
The Album class would be to big to post here, but I have mapped the elements as reasonable as I could.
If you haven't already, you need to add Restlet's JacksonConverter to the list of registered converters:
List<ConverterHelper> converters = Engine.getInstance().getRegisteredConverters();
converters.add(new JacksonConverter());
and, of course, add org.restlet.ext.jackson.jar to your build path.
Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB 2 (JSR-222) expert group.
The following is how it could be done with MOXy by leveraging JAXB annotations:
AlbumInfo
package forum9966753;
import java.io.Serializable;
import java.util.ArrayList;
import javax.xml.bind.annotation.*;
#XmlType(propOrder={"resultCount", "albums"})
public class AlbumInfo implements Serializable {
private static final long serialVersionUID = 1L;
private int _resultCount;
private ArrayList<Album> _albums;
public AlbumInfo() {
_albums = new ArrayList<Album>();
}
public AlbumInfo(int resultCount, ArrayList<Album> albums) {
_resultCount = resultCount;
_albums = albums;
}
public int getResultCount() {
return _resultCount;
}
public void setResultCount(int resultCount) {
_resultCount = resultCount;
}
#XmlElement(name="results")
public ArrayList<Album> getAlbums() {
return _albums;
}
public void setAlbums(ArrayList<Album> _albums) {
this._albums = _albums;
}
}
Album
Below is a scaled down version of your Album class:
package forum9966753;
public class Album {
private String wrapperType;
public String getWrapperType() {
return wrapperType;
}
public void setWrapperType(String wrapperType) {
this.wrapperType = wrapperType;
}
}
jaxb.properties
To specify MOxy as your JAXB provider you need to add a file called jaxb.properties in the same package as your domain classes with the following entry:
javax.xml.bind.context.factory = org.eclipse.persistence.jaxb.JAXBContextFactory
Demo
package forum9966753;
import java.io.InputStream;
import java.net.*;
import java.util.List;
import javax.xml.bind.*;
import javax.xml.transform.stream.StreamSource;
import org.example.Customer;
public class JavaSEClient {
private static final String MEDIA_TYPE = "application/json";
public static void main(String[] args) throws Exception {
String uri = "http://itunes.apple.com/search?term=marc+jordan&media=music&entity=album";
URL url = new URL(uri);
HttpURLConnection connection =
(HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("Accept", MEDIA_TYPE);
JAXBContext jc = JAXBContext.newInstance(AlbumInfo.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
unmarshaller.setProperty("eclipselink.media-type", MEDIA_TYPE);
unmarshaller.setProperty("eclipselink.json.include-root", false);
InputStream xml = connection.getInputStream();
AlbumInfo albumInfo = unmarshaller.unmarshal(new StreamSource(xml), AlbumInfo.class).getValue();
connection.disconnect();
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setProperty("eclipselink.media-type", MEDIA_TYPE);
marshaller.setProperty("eclipselink.json.include-root", false);
marshaller.marshal(albumInfo, System.out);
}
}
Output
Below is the output from running the demo code. As the sample domain model only contains a couple properties the output is much smaller than the output. The JAXB mappings can easily be applied to map the rest of the document.
{
"resultCount" : 49,
"results" : [ {
"wrapperType" : "collection"
} ]
}
For More Information
MOXy as Your JAX-RS JSON Provider - Client Side
Try using JAXB annotations or use Jersey for JSON mappings. This manual could be useful for you: link
Recently I had to develop an Android app with Restlet framework and I spent a lot of time to understand how to deserialize a JSONObject.
Here I'm going t explain my method.
I also published a complete Android App on GitHub here:
https://github.com/alchimya/android-restlet
Restlet 2.3.2 includes Gson lib.
With Gson is very simple to map and deserialize a resource.
1) Map your entity base with a class as following:
import com.google.gson.annotations.SerializedName;
import java.io.Serializable;
public class Album implements Serializable {
#SerializedName("wrapperType")
private String wrapperType;
#SerializedName("collectionType")
private String collectionType;
#SerializedName("artistId")
private String artistId;
public String getWrapperType() {
return wrapperType;
}
public void setWrapperType(String wrapperType) {
this.wrapperType = wrapperType;
}
public String getCollectionType() {
return collectionType;
}
public void setCollectionType(String collectionType) {
this.collectionType = collectionType;
}
public String getArtistId() {
return artistId;
}
public void setArtistId(String artistId) {
this.artistId = artistId;
}
......
......
......
}
Note: in the previous class each property has an annotation (#SerializedName) to map the corresponding JSON field. For further informations see this tutorial:
http://www.javacodegeeks.com/2011/01/android-json-parsing-gson-tutorial.html
2) Create a class with a List attribute:
public class Albums {
public List<Album> results;
}
3) Consume your resource with Restlet
String uri="http://itunes.apple.com/search?term=marc+jordan&media=music&entity=album";
ClientResource resource = new ClientResource(url);
Representation rep = resource.get();
JsonRepresentation represent = new JsonRepresentation(rep);
JSONObject jsonobject = represent.getJsonObject();
String jsonText = jsonobject.toString();
Gson gson = new Gson();
Albums response = gson.fromJson(jsonText, Albums.class);
Into response.results there will be all deserialized items.
Related
I'm Java beginner. Just added JSON. Simple dependency and it's so easy to convert data to JSON format.
example :
public void Post_test3_positive(){
JSONObject user = new JSONObject();
user.put("name","John");
user.put("email","John#inbox.lv");
given()
.body(user.toJSONString())
.when().post("/api/user/createUserPost")
.then().statusCode(201)
Is there any easy way to convert request body (username and email ) to XML format?
Thanks
Hi try this to convert map to xml string :
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import java.util.AbstractMap;
import java.util.HashMap;
import java.util.Map;
public class Test {
public static void main(String[] args) {
Map<String,String> map = new HashMap<String,String>();
map.put("name","chris");
map.put("island","faranga");
XStream magicApi = new XStream();
magicApi.registerConverter(new MapEntryConverter());
magicApi.alias("root", Map.class);
String xml = magicApi.toXML(map);
System.out.println("Result of tweaked XStream toXml()");
System.out.println(xml);
Map<String, String> extractedMap = (Map<String, String>) magicApi.fromXML(xml);
assert extractedMap.get("name").equals("chris");
assert extractedMap.get("island").equals("faranga");
}
public static class MapEntryConverter implements Converter {
public boolean canConvert(Class clazz) {
return AbstractMap.class.isAssignableFrom(clazz);
}
public void marshal(Object value, HierarchicalStreamWriter writer, MarshallingContext context) {
AbstractMap map = (AbstractMap) value;
for (Object obj : map.entrySet()) {
Map.Entry entry = (Map.Entry) obj;
writer.startNode(entry.getKey().toString());
Object val = entry.getValue();
if ( null != val ) {
writer.setValue(val.toString());
}
writer.endNode();
}
}
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
Map<String, String> map = new HashMap<String, String>();
while(reader.hasMoreChildren()) {
reader.moveDown();
String key = reader.getNodeName(); // nodeName aka element's name
String value = reader.getValue();
map.put(key, value);
reader.moveUp();
}
return map;
}
}
}
I use java POJO and convert it to json/xml by using Jackson library.
#Data
#AllArgsConstructor
#XmlRootElement
#NoArgsConstructor
static class Example {
private String name;
private String email;
}
#Test
void name() {
Example payload = new Example("John", "John#inbox.lv");
given().log().body()
.contentType(ContentType.JSON)
.body(payload)
.when().post("https://postman-echo.com/post");
given().log().body()
.contentType(ContentType.XML)
.body(payload)
.when().post("https://postman-echo.com/post");
}
result:
Body:
{
"name": "John",
"email": "John#inbox.lv"
}
Body:
<example>
<email>John#inbox.lv</email>
<name>John</name>
</example>
pom.xml
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.4</version>
</dependency>
Wanted to covert an xml String to Json and I am doing it as below.
XML which has to be converted
<Item>
<Property name="Description" value="Description 1"/>
<Property name="EffDate" value="01/05/2017"/>
<Property name="ExpDate" value="12/31/9999"/>
<Property name="Status" value="Launched"/>
</Item>
I have created a Class for the xml as below.
public class Context {
#XmlElement(name = "Item")
private List<Item> offer;
}
public class Item {
#XmlElement(name = "Property")
private List<Property> properties;
}
public class Property {
#XmlAttribute
private String name;
#XmlAttribute
private String value;
}
I am using Gson libraries to convert this Java object to Json - g.toJson.
Comverted JSON -
"offer": [{
"properties": [{
"name": "Description",
"value": "Description 1"
},
{
"name": "EffDate",
"value": "01/05/2017"
},
{
"name": "ExpDate",
"value": "12/31/9999"
},
{
"name": "Status",
"value": "Launched"
}]
}]
But we wanted to convert the JSON as below -
"offer": [{
"Description" : "Description 1",
"EffDate":"01/05/2017",
"ExpDate": "12/31/9999",
"Status": "Launched"
}]
Is there a way to convert the properties name and value as Item class properties.?
Try using this link: https://github.com/stleary/JSON-java This is a JSON Helper class that can convert XML to JSON for example:
public class Main {
public static int PRETTY_PRINT_INDENT_FACTOR = 4;
public static String TEST_XML_STRING =
"<?xml version=\"1.0\" ?><test attrib=\"moretest\">Turn this to JSON</test>";
public static void main(String[] args) {
try {
JSONObject xmlJSONObj = XML.toJSONObject(TEST_XML_STRING);
String jsonPrettyPrintString = xmlJSONObj.toString(PRETTY_PRINT_INDENT_FACTOR);
System.out.println(jsonPrettyPrintString);
} catch (JSONException je) {
System.out.println(je.toString());
}
}
}
Hope this helps :)
It is possible using FasterXML library. where you can write your custom logic for generating XML and JSON. By overriding serialize of JsonSerializer class.
Need to write Serializer like :
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
public class ContextSerializer extends JsonSerializer<Context> {
#Override
public void serialize(Context t, JsonGenerator jg, SerializerProvider sp) throws IOException, JsonProcessingException {
jg.writeStartObject();
jg.writeArrayFieldStart("offer");
for (Item i : t.offer) {
jg.writeStartObject();
for (Property property : i.properties) {
jg.writeStringField(property.name, property.value);
}
jg.writeEndObject();
}
jg.writeEndArray();
jg.writeEndObject();
}
}
For convert:
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.JAXBException;
public class Main {
public static void main(String[] args) throws JAXBException, JsonProcessingException {
Context c = new Context();
List<Item> offer = new ArrayList<>();
Item pr = new Item();
pr.properties = new ArrayList<>();
Property p = new Property();
p.name = "asdf";
p.value = "va1";
pr.properties.add(p);
p = new Property();
p.name = "asdf1";
p.value = "va11";
pr.properties.add(p);
offer.add(pr);
c.offer = offer;
try {
SimpleModule module = new SimpleModule();
module.addSerializer(Context.class, new ContextSerializer());
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(module);
objectMapper.setSerializationInclusion(Include.NON_DEFAULT);
String json = objectMapper.writeValueAsString(c);
System.out.println(json);
} catch (Exception e) {
System.out.println(""+e);
}
}
}
O/P JSON : (Provided O/P JSON is wrong in your question if you give the name to the list("offer") then it always inside object link)
{
"offer": [{
"asdf": "va1",
"asdf1": "va11"
}
]
}
Maven Dependency for package is:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.0.pr3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0.pr3</version>
</dependency>
If you are using Java 8 or later, you should check out my open source library: unXml. unXml basically maps from Xpaths to Json-attributes.
It's available on Maven Central.
Example
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.nerdforge.unxml.factory.ParsingFactory;
import com.nerdforge.unxml.parsers.Parser;
import org.w3c.dom.Document;
public class Parser {
public ObjectNode parseXml(String xml){
Parsing parsing = ParsingFactory.getInstance().create();
Document document = parsing.xml().document(xml);
Parser<ObjectNode> parser = parsing.obj("/")
.attribute("offer", parsing.arr("/Item")
.attribute("Description", "Property[#name='Description']/#value")
.attribute("EffDate", "Property[#name='EffDate']/#value")
.attribute("ExpDate", "Property[#name='ExpDate']/#value")
.attribute("Status", "Property[#name='Status']/#value")
)
.build();
ObjectNode result = parser.apply(document);
return result;
}
}
It will return a Jackson ObjectNode, with the following json:
{
"offer": [
{
"Status": "Launched",
"Description": "Description 1",
"ExpDate": "12/31/9999",
"EffDate": "01/05/2017"
}
]
}
You may convert xml to a map, modify it and then convert to a json. Underscore-java library has static methods U.fromXml(xml) and U.toJson(json). I am the maintainer of the project.
I have a User
public class User {
private String name;
private String email;
public User () { }
public User(String name) {
this.name = name;
}
public User(String name, String email) {
this(name);
this.email = email;
}
// getters and setters
}
Also I have simple POJO Comment
public class Comment {
private String comment;
private Date date;
private String author;
public Comment() { }
public Comment(String comment, Date date, String author) {
this.comment = comment;
this.date = date;
this.author = author;
}
// getters and setters
}
How I want insert new user into collection with some kind of comments about him like this:
public static void main(String[] args) {
MongoClient client = new MongoClient();
MongoDatabase db = client.getDatabase("example");
MongoCollection<Document> collection = db.getCollection("object_arrays");
collection.drop();
List<Comment> reviews = new ArrayList<Comment>(){{
add(new Comment("cool guy", new Date(), "John Doe"));
add(new Comment("best joker", new Date(), "Vas Negas"));
add(new Comment("very stupid but very funny man", new Date(), "Bill Murphy"));
}};
Document user = new Document();
user.append("user", new User("0xFF", "email#email.com"))
.append("reviews", reviews)
.append("createDate", new Date());
collection.insertOne(user);
}
Unfortunately, I've got Exception:
Exception in thread "main" org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class com.mongodb.course.com.mongodb.course.model.User.
at org.bson.codecs.configuration.CodecCache.getOrThrow(CodecCache.java:46)
at org.bson.codecs.configuration.ProvidersCodecRegistry.get(ProvidersCodecRegistry.java:63)
at org.bson.codecs.configuration.ChildCodecRegistry.get(ChildCodecRegistry.java:51)
at org.bson.codecs.DocumentCodec.writeValue(DocumentCodec.java:174)
at org.bson.codecs.DocumentCodec.writeMap(DocumentCodec.java:189)
at org.bson.codecs.DocumentCodec.encode(DocumentCodec.java:131)
at org.bson.codecs.DocumentCodec.encode(DocumentCodec.java:45)
at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:63)
at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:29)
at com.mongodb.connection.InsertCommandMessage.writeTheWrites(InsertCommandMessage.java:101)
at com.mongodb.connection.InsertCommandMessage.writeTheWrites(InsertCommandMessage.java:43)
at com.mongodb.connection.BaseWriteCommandMessage.encodeMessageBodyWithMetadata(BaseWriteCommandMessage.java:129)
at com.mongodb.connection.RequestMessage.encodeWithMetadata(RequestMessage.java:160)
at com.mongodb.connection.WriteCommandProtocol.sendMessage(WriteCommandProtocol.java:212)
at com.mongodb.connection.WriteCommandProtocol.execute(WriteCommandProtocol.java:101)
at com.mongodb.connection.InsertCommandProtocol.execute(InsertCommandProtocol.java:67)
at com.mongodb.connection.InsertCommandProtocol.execute(InsertCommandProtocol.java:37)
at com.mongodb.connection.DefaultServer$DefaultServerProtocolExecutor.execute(DefaultServer.java:159)
at com.mongodb.connection.DefaultServerConnection.executeProtocol(DefaultServerConnection.java:286)
at com.mongodb.connection.DefaultServerConnection.insertCommand(DefaultServerConnection.java:115)
at com.mongodb.operation.MixedBulkWriteOperation$Run$2.executeWriteCommandProtocol(MixedBulkWriteOperation.java:455)
at com.mongodb.operation.MixedBulkWriteOperation$Run$RunExecutor.execute(MixedBulkWriteOperation.java:646)
at com.mongodb.operation.MixedBulkWriteOperation$Run.execute(MixedBulkWriteOperation.java:401)
at com.mongodb.operation.MixedBulkWriteOperation$1.call(MixedBulkWriteOperation.java:179)
at com.mongodb.operation.MixedBulkWriteOperation$1.call(MixedBulkWriteOperation.java:168)
at com.mongodb.operation.OperationHelper.withConnectionSource(OperationHelper.java:230)
at com.mongodb.operation.OperationHelper.withConnection(OperationHelper.java:221)
at com.mongodb.operation.MixedBulkWriteOperation.execute(MixedBulkWriteOperation.java:168)
at com.mongodb.operation.MixedBulkWriteOperation.execute(MixedBulkWriteOperation.java:74)
at com.mongodb.Mongo.execute(Mongo.java:781)
at com.mongodb.Mongo$2.execute(Mongo.java:764)
at com.mongodb.MongoCollectionImpl.executeSingleWriteRequest(MongoCollectionImpl.java:515)
at com.mongodb.MongoCollectionImpl.insertOne(MongoCollectionImpl.java:306)
at com.mongodb.MongoCollectionImpl.insertOne(MongoCollectionImpl.java:297)
at com.mongodb.course.week3.ArrayListWithObject.main(ArrayListWithObject.java:34)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
I understand that Java driver for MongoDB can't convert my object into Document and it want some kind of converter. Also I know about Codec, CodecRegistry and CodecProvider interfaces. By the way, is there a simpler way to convert object into mongo document? Can you show me example how can I do it?
Thank you.
The problem with the code you posted is that it doesnt know by default how to serialise your pojo objects into Json to save them into the databse. You can do this with the MongoDB Java drivers, but you need to do some work to serialise the Comment ArrayList and User pojos. If you add some Jackson mapping code you can do this as follows:
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.bson.Document;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mongodb.MongoClient;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
public class Problem {
public static void main(String[] args) {
try (final MongoClient client = new MongoClient()) {
final MongoDatabase db = client.getDatabase("example");
final MongoCollection<Document> collection = db.getCollection("object_arrays");
collection.drop();
final List<Comment> reviews = new ArrayList<Comment>() {
{
add(new Comment("cool guy", new Date(), "John Doe"));
add(new Comment("best joker", new Date(), "Vas Negas"));
add(new Comment("very stupid but very funny man", new Date(), "Bill Murphy"));
}
};
final ObjectMapper mapper = new ObjectMapper();
final User user = new User("0xFF", "email#email.com");
try {
//Create a Document representation of the User object
final String userJson = mapper.writeValueAsString(user);
final Document userDoc = Document.parse(userJson);
//Convert the review ArrayList into a Mongo Document. Need to amend this if not using Java8
final List<Document> reviewDocs = reviews.stream().map(convertToJson())
.map(reviewJson -> Document.parse(reviewJson)).collect(Collectors.toList());
//Wrap it all up to it can be saved to the database
final Document wrapperDoc = new Document();
wrapperDoc.append("user", userDoc).append("reviews", reviewDocs).append("createDate", new Date());
collection.insertOne(wrapperDoc);
} catch (final JsonProcessingException e) {
e.printStackTrace();
}
}
}
private static Function<Comment, String> convertToJson() {
final ObjectMapper mapper = new ObjectMapper();
return review -> {
try {
return mapper.writeValueAsString(review);
} catch (final JsonProcessingException e) {
e.printStackTrace();
}
return "";
};
}
}
*this uses some Java8 code which you might need to change depending on which version of Java you're using
As the other answer on this question says there are frameworks out there that can combine the serialisation of Objects and interaction with MongoDB so that you dont need to hand-crank the serialisation code. For example Spring has a Mongo driver, and I have used another called Jongo, which I have found to be quite good.
If you want to work with Java objects like this, Morphia is your best bet. There is work being done now to support arbitrary Java classes like you're trying but it's not done yet.
I am using Jackson objectMapper to read JSON to JsonNode, Then I am using xmlMapper to serialize this to XML.
I'd like to set an XML attribute value by parsing a JSON attribute with tag "#". Any help would be appreciated. Thanks.
EXAMPLE JSON:
{
"response" : {
"label" : {
"#data" : "someValue"
}
}
}
NEED TO MAP TO XML:
<response>
<label data="someValue" />
</response>
This is what I can get right now:
<response>
<label>
<#data>someValue</#data>
</label>
</response>
CODE:
JsonNode root = objectMapper.readTree(JSON);
xml = xmlMapper.writeValueAsString(root);
well, I found a solution that produces the required output. However, I am not sure if this is an optimal solution, in a sense that it requires custom inner classes to be able to specify the annotations that tell the mappers how to parse.
import java.util.*;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.type.TypeFactory;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
public class JSONTest
{
#SuppressWarnings("unchecked")
public static void main(String[] args)
{
try {
String jsonInput = "{ \"response\" : { \"label\" : { \"#data\" : \"someValue\" } }}";
ObjectMapper om = new ObjectMapper();
TypeFactory tf = om.getTypeFactory();
JavaType mapType = tf.constructMapType(HashMap.class, String.class, response.class);
Map<String, response> map = (Map<String, response>)om.readValue(jsonInput, mapType);
XmlMapper xmlMapper = new XmlMapper();
String ss = xmlMapper.writeValueAsString(map.get("response"));
System.out.println(ss);
} catch (Exception e) {
e.printStackTrace();
}
}
public static class response {
public Label label;
}
public static class Label {
#JsonProperty("#data")
#JacksonXmlProperty(isAttribute = true)
public String data;
}
}
output:
<response><label data="someValue"/></response>
I have a service that does the following:
receives different XML requests
turns them into JIBX-generated Java objects
maps the JIBX-generated Java objects into POJOs
sends the POJOs to another service
gets a POJO response back
maps POJO back into JIBX-generated Java objects
turns JIBX-generated Java objects back into XML
returns XML to client.
I'd like to make this process more efficient. Can anyone suggest how? Can JIBX map directly into my POJOs?
Yes Jibx can map directly to your POJOs using Jibx mapping files. I think the below link will be very helpful to understand Jibx binding.
Jibx Introduction
In this you needed library which is available in the url(4shared.com) commented in comments.
package com.xml.Sample.MainP;
import java.io.File;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import com.xml.Sample.Actions.XMLAction;
import com.xml.Sample.Model.States;
public class Retrieve {
public static String XMLModelName = "com.xml.Sample.Model.States";
private static String cities = "E:\\Webeclipseworkspace\\Samples\\src\\Srates.xml";
public static void main(String[] args) {
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
File f = new File(cities);
Document doc = db.parse(f);
doc.getDocumentElement().normalize();
XMLAction xmla = new XMLAction();
List<States> listXML = xmla.readData(XMLModelName, doc);
// System.out.println(listXML);
String xmlData = xmla.writtingData(listXML);
System.out.println(xmlData);
} catch (Exception e) {
// TODO: handle exception
System.out.println(e);
}
}
}
package com.xml.Sample.Model;
import com.xml.Sample.XMLAnn.XMLColumn;
import com.xml.Sample.XMLAnn.XMLReport;
#XMLReport(reportName = "row")
public class Directory {
private String city_id;
private String city_name;
private String state_id;
#XMLColumn(label = "city_id")
public String getCity_id() {
return city_id;
}
public void setCity_id(String city_id) {
this.city_id = city_id;
}
#XMLColumn(label = "city_name")
public String getCity_name() {
return city_name;
}
public void setCity_name(String city_name) {
this.city_name = city_name;
}
#XMLColumn(label = "state_id")
public String getState_id() {
return state_id;
}
public void setState_id(String state_id) {
this.state_id = state_id;
}
}
Here I Created Own Library For Converting Pojo classes to xml and xml to pojo classes.
Use Below Link(4Shared.com) at Comments to download Library to add for The Above Code.
String(XML in String) to List
1. FolderItem.java
<code>
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
#XmlAccessorType(XmlAccessType.FIELD)
public class FolderItem {
long itemId ;
String itemName;
String itemType;
String description;
String[] tags;
String path;
/* setters and getters
Annotations not required*/
}
</code>
2. FolderItems.java
<code>
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class FolderItems {
#XmlElement
private List<FolderItem> folderItem;
/* setter and getter */
}
</code>
3. Testing--main method
<code>
class Test{
public static void main(String[] args) throws Exception {
FolderItems f = (FolderItems)strToVo(content, FolderItems.class);
System.out.println(f);
}
static Object strToVo(String content, Class c) throws JAXBException {
JAXBContext jc = JAXBContext.newInstance(c);
Unmarshaller unmarshaller = jc.createUnmarshaller();
return unmarshaller.unmarshal(new InputSource(new StringReader(content)));
}
}
</code>
4. XML in String
<code>
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<FolderItems>
<folderItem>
<description>Lapse notice invoice for additional interests/additional insureds</description>
<itemId>480004439</itemId>
<itemName>Lapse_Invoice_AI</itemName>
<itemType>application/x-thunderhead-ddv</itemType>
<path>/Templates/Billing Center/Lapse_Invoice_AI</path>
<tags></tags>
</folderItem>
</FolderItems>
</code>