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);
}
Related
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/
I have a complex model class in Java that has attributes of different class. I wanted to get the schema of the class in yml format for better readability. I was able get the structure of the class to a JSON file but I feel that yml is less cluttered and easy to ready.
Example
From
public class Phone {
public String name;
public String number;
}
To
Phone:
fields:
name:
type: String
number:
type: String
The Jackson library offers the ability to generate a JSONSchema from a Java class. You should be able to serialize it into a YAML, although I haven't actually tested this part. Here how it might look like :
ObjectMapper m = new ObjectMapper();
SchemaFactoryWrapper visitor = new SchemaFactoryWrapper();
m.acceptJsonFormatVisitor(m.constructType(Phone.class), visitor);
JsonSchema jsonSchema = visitor.finalSchema();
ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
mapper.writeValue(yamlFile, jsonSchema);
You may need this configuration if you use enums
mapper.configure(SerializationConfig.Feature.WRITE_ENUMS_USING_TO_STRING, true);
More details at the github page of the Yaml module and the JSON schema module
From RAM to File
If your use case is to just serialize your existing objects, without reading them first, you might try the approach from this answer using Jackson; it just writes to a file an example object.
// Create an ObjectMapper mapper for YAML
ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
// Write object as YAML file
mapper.writeValue(new File("/path/to/yaml/file"), example);
You can try http://jyaml.sourceforge.net/
The project is no longer active though.
An other approach may be the read the class files using the ASM library. It has a nice visitor API which lets you fairly simply transform the bytecode into an other representation like YAML (start here: http://asm.ow2.org/asm50/javadoc/user/org/objectweb/asm/ClassVisitor.html ). But it might be an overkill for your task.
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.
I would like to know how to parse a JSON feed by items (eg. url / title / description for each item). I have had a look to the doc / api but, it didn't help me.
This is what I got so far
import com.google.gson.Gson;
import com.google.gson.JsonObject;
public class ImportSources extends Job {
public void doJob() throws IOException {
String json = stringOfUrl("http://feed.test/all.json");
JsonObject jobj = new Gson().fromJson(json, JsonObject.class);
Logger.info(jobj.get("responseData").toString());
}
public static String stringOfUrl(String addr) throws IOException {
ByteArrayOutputStream output = new ByteArrayOutputStream();
URL url = new URL(addr);
IOUtils.copy(url.openStream(), output);
return output.toString();
}
}
Depends on the actual JSON format. You can in fact just create a custom Javabean class which matches the JSON format. Any fields in JSON can be mapped as String, Integer, Boolean, etc Javabean properties. Any arrays can be mapped as List properties. Any objects can be mapped as another nested Javabean property. It greatly eases further processing in Java.
Without a JSON string example from your side, it's only guessing how it would look like, so I can't give a basic example here. But I've posted similar answers before here, you may find it useful:
Converting JSON to Java
Generate Java class from JSON?
Gson has also an User Guide, you may find it useful as well.
Gson 1.4 has a new API JsonStreamParser that lets you parse multiple JSON objects one by one from a stream.
You can create corresponding java classes for the json objects. The integer, string values can be mapped as is. Json can be parsed like this-
Gson gson = new GsonBuilder().create();
Response r = gson.fromJson(jsonString, Response.class);
Here is an example- http://rowsandcolumns.blogspot.com/2013/02/url-encode-http-get-solr-request-and.html
I don't know if GSON can do streaming/incremental binding (I thought it did not).
But is there specific reason to only consider that particular library? Other Java JSON processing libraries do allow such processing (you can check links the other answer has for some ideas), since it is quite important feature when processing large feeds.