I´m using ElasticSearch to store some data related to events that are happening with objects, a Track and Trace Model. To do that I used JAXB to generate de model classes using a XSD file.
I can save the data on ES easily transforming the Data data comes in XML to POJO and after that to JSON.
The problem that I´m having is to get the data back. I´m trying to use the same logic JSON to POJO (using JAXB) and POJO to XML on the web service. Like that:
JAXBContext jc = JAXBContext.newInstance(EPCISDocumentType.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
unmarshaller.setProperty("eclipselink.media-type", "application/json");
unmarshaller.setProperty("eclipselink.json.include-root", true);
String eventJSON = elasticEvent.getSpecific("event", "raw", eventID);
The String comes with the expected event but when I try to transform to POJO the object comes only with the outer most class (EPCISDocumentType) but with 0 contents. I´m trying like that:
StreamSource eventStream = new StreamSource(new StringReader(eventJSON));
EPCISDocumentType foundEvent = unmarshaller.unmarshal(eventStream,EPCISDocumentType.class).getValue();
The problem is why this is happening, I´m using exactly the same libraries to do Marshal but I can´t unmarshal it back to the same content.
I use ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper) for both marshaling and unmarshaling. It's much easier to use.
See bellow:
ObjectMapper mapper = new ObjectMapper();
//Get the json as String
String objectAsJsonString= mapper.writeValueAsString(foundEvent);
//Create the object from the String
EPCISDocumentType foundEvent = mapper.readValue(objectAsJsonString,EPCISDocumentType.class);
When you have lists of objects you want to marshal/unmarshal, it works only if you put the list in a wrapper.
Also jackson is more performant than jaxb.
Check these tests: http://tuhrig.de/jaxb-vs-gson-and-jackson/
Related
I am trying to parse a json received from server in different custom objects, all implement single interface. My Json looks like
I have created classes MyFile, Display, PlayList and Manager. All implement EntityIFace.
First I created a wrapper class with one element of type List and tried restTemplate.exchange but list was null.
Then I decided to read json in String and parse it.
ResponseEntity responseEntity = restTemplate.getForEntity(baseUrl, String.class);
How can I read this json String into List of EntityIFace. Is there are way I can implement custom ObjectMapper? Or any other way to read this structure?
Thanks in Advance
Found a solution ..
I am reading json in String and parsing it using code below
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonNode = mapper.readTree(json);
JsonNode arrayNode = jsonNode.get("entities");
and Then getting entities using jsonNode.get() method.
I am using Json type for my data, and i need a json schema to make a better description.
Can a sample Java code provide json schema?
I want a sample example.
Generally data model ( Java POJOs ) for the JSON is shared between data transferring parties.
But if you really want, then "jackson" can be used, example below converts a Java class to JSON Schema. You can furthe play around or look for similar libraries, tio suit your requirement.
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.module.jsonSchema.JsonSchemaGenerator;
private String getJsonSchema(Class clazz) throws IOException
{
ObjectMapper mapper = new ObjectMapper();
JsonSchemaGenerator schemaGen = new JsonSchemaGenerator(mapper);
com.fasterxml.jackson.module.jsonSchema.JsonSchema schema = schemaGen.generateSchema(clazz);
return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(schema);
}
In Play Framework we have the helper method Json.toJson() to generate JsonNodes from the request body or DB queries, but I don't know how to remove specific fields from the object after it has been generated.
Play uses FasterXML/jackson under the hood.
For example, let's say that you want to retrieve the payload from a request. You call request().body().asJson(), in your controller and you get a JsonNode.
A JsonNode doesn't have insertion capabilities but ObjectNode has.
1. Creating an ObjectNode(showing 2 common ways to do it):
a. Casting to ObjectNode
ObjectNode json = (ObjectNode) request().body().asJson();
b. Using an ObjectMapper(gives you more control like serialization features)
ObjectMapper mapper = new ObjectMapper();
//set serialization features in cases where you need them
mapper.configure(SerializationFeature.WRITE_EMPTY_JSON_ARRAYS, false);
mapper.setSerializationInclusion(Include.NON_NULL);
ObjectNode json = mapper.createObjectNode();
2. Adding/removing elements (linked the ObjectNode API so you can check all of the available methods)
json.remove("fieldName");
json.put("anotherFieldName", "yesWeCan")
.put("canWeDoBoolean", true)
.put("howAboutNumbers", 1234567890);
Don't forget to check the rest of the documentation/tutorials as jackson is a complex library and you might want to educate yourself on the subject.
What is the way to generate a Java object with get and set methods?
You should write a java bean with properties maching the JSON key's, from that point since you already have a reader its a simple as
YourObject obj = gson.fromJson(br, YourObject.class);
UPDATE
With respect to your comment, when you don't want or can't create a bean it usually boils down to parsing JSON to map. GSON (afaik) doesn't have a built-in for this, but its not hard to build a method that will traverse GSON's objects. You have an example in this blog
http://itsmyviewofthings.blogspot.it/2013/04/jsonconverter-code-that-converts-json.html
As you seem to be open to alternatives, take a look at Jackson as well (the two libs are the de-facto standard in JAVA).
With jackson you don't have to create a bean to support deserialization, e.g.
String json = "{\"id\":\"masterslave\"}";
Map<String,String> map = new HashMap<String,String>();
ObjectMapper mapper = new ObjectMapper();
//convert JSON string to Map
map = mapper.readValue(json,
new TypeReference<HashMap<String,String>>(){});
http://www.jsonschema2pojo.org/
That link helps generate the Java object format based on the GSON you feed in. Just make sure you set the settings exactly as you need it. As always, it's not a good idea to just copy-paste generated code, but it might be of help.
Does anyone know if there is the ability to generate objects for JSON data? I know there are generic JSON object libraries, but I am looking for more specific - similar to how jaxb can convert SOAP definitions or XSDs into an object model. I know there would need to be some sort of JSON definition file (which I do not know if that concept even exists within JSON), but I feel like that would be a lot more beneficial. Think:
Generic case:
genericJsonObect.get("name");
Specific case:
specificJsonObject.getName();
Jackson and XStream have the ability to map json to POJOs.
Do you want the .java source file to be generated for you? Or to map exiting java beans to JSON objects?
If the former, there is no such a library ( that I'm aware of ) if the later, Google GSON is exactly what you need.
From the samples:
class BagOfPrimitives {
public int value1 = 1;
private String value2 = "abc";
private transient int value3 = 3;
BagOfPrimitives() {
// no-args constructor
}
}
(Serialization)
BagOfPrimitives obj = new BagOfPrimitives();
Gson gson = new Gson();
String json = gson.toJson(obj);
System.out.println( json );
Prints
{"value1":1,"value2":"abc"}
( Deserialization )
BagOfPrimitives obj2 = gson.fromJson(json, BagOfPrimitives.class);
System.out.println( obj2.value1 ) ; // value1 is 1
I think the Jackson data mapper can do what you need. It can serialize/deserialize a real Java object into a Json tree.
But others API should also work :
Sojo
FlexJSON
Gson
I am not familiar of such code generation project, although I am sure many Java JSON library projects would be interested in having such thing. Main issue is that there is good Schema language for JSON that would allow code generation; JSON Schema only works for validation.
However: one possibility you could consider is to just use JAXB to generate beans, and then use Jackson to use those beans. It has support for JAXB annotations so you would be able to work with JSON and beans generated.
I have found this site very useful.
http://jsongen.byingtondesign.com/ and have used it in our projects.