I have a java object (let's name it JsonValidator) that can be configured in YAML file.
I would like to describe a schema of JSON objects in YAML notation something like this
And then I need to validate JSON objects according to the schema. Does anybody know any Java libs I can use or any examples?
Thanks
The schema of a json document can be defined using json schema (actually, OpenAPI uses a custom flavor of json schema). It is essentially a json document defining the structure of an other json document. There are a few java implementations out there. If you want to stick to YAML for defining the schema, then will first need to convert YAML to JSON and then use the json schema validator, see this SO question for doing that.
You can find some Java validators for JSON Schema here.
Related
I have the next task: read XML file from some directory and convert it to JSON string.
The problem: initial XML and JSON have different names for corresponding properties, e.g. x_date in XML and j_date in JSON.
I have created the class with required field for JSON with such annotations:
public class Card {
#JacksonXmlProperty(localName = "x_date")
#JsonProperty("j_date")
private String date;
// other fields
I have tried to serialize/deserialize test XML file, and it's seems work correctly.
But I'm not sure that is ok to annotate fields with #JacksonXmlProperty and #JsonProperty annotations at the same time. Maybe it's better to create one class per XML part and one for the JSON and transfer the data between them some mapper (e.g. Orika)?
Any suggestions?
Finally solved this by splitting logic in two separate classes: Card.class for XML data with help of #JacksonXmlProperty annotation and CardDto.class which uses #JsonProperty. Mapping between these classes is handled by Orika mapper.
This split will ease further customization of both classes and will allow add new functionality (e.g. persist data to the database using new entity class).
I have a Kotlin Gradle Spring Boot and Spring Webflux application which accepts a JSON as its request body. I have an openapi generated Java class, which the JSON request body can be casted into.
On the other hand, I also have an Avro schema which is the same as the openapi, except the field names have been cleaned up. The JSON request body has fields where the names start with special character, e.g. $device_version, +ip_address, ~country. So, in the Avro schema, I remove them as Avro only allows the field name to start with either an alphabet or underscore.
Casting from JSON request body to openapi generated Java class is no problem, however, casting it to Avro schema generated Java class is a problem due to the field names.
I mean, I can manually set the fields but the JSON object is quite huge.
Is there an elegant and quick solution to convert that JSON request body containing different field names due to special character to the Avro schema generated class?
Packages used
org.hidetake.swagger.generator
org.openapitools:openapi-generator-cli (with swaggerCodeGen)
com.commercehub.gradle.plugin:gradle-avro-plugin
I have a requirement where in i've a complex db query returning certain result set. I have to map the result to POJO. How can i achieve this with an optimized code? Finally I have to parse the pojo to create a json (json schema is pasted below).
db_objects_json_schema_image
Example of query result set (pipe separated):
object_id|object_name|object_owner|object_type|status|parent_id|last_modified_timestamp
123_S1|ABC_S1|XYZ_S1|schema|valid|none|2019-11-09_20:40:11
123_S1T1|ABC_S1T1|XYZ_S1T1|table|valid|123_S1|2019-11-09_20:40:11
123_S1T1C1|ABC_S1T1C1|XYZ_S1T1C1|column|valid|123_S1T1|2019-11-09_20:40:11
123_S1T1C2|ABC_S1T1C2|XYZ_S1T1C2|column|valid|123_S1T1|2019-11-09_20:40:11
123_S1T1C3|ABC_S1T1C3|XYZ_S1T1C3|column|valid|123_S1T1|2019-11-09_20:40:11
123_S1T2|ABC_S1T2|XYZ_S1T2|table|valid|123_S1|2019-11-09_20:40:11
123_S1T2C1|ABC_S1T2C1|XYZ_S1T2C1|column|valid|123_S1T2|2019-11-09_20:40:11
123_S1T2C2|ABC_S1T2C2|XYZ_S1T2C2|column|valid|123_S1T2|2019-11-09_20:40:11
123_S1T2C3|ABC_S1T2C3|XYZ_S1T2C3|column|valid|123_S1T2|2019-11-09_20:40:11
123_S1V1|ABC_S1V1|XYZ_S1V1|view|valid|123_S1|2019-11-09_20:40:11
123_S1V1C1|ABC_S1V1C1|XYZ_S1V1C1|column|valid|123_S1V1|2019-11-09_20:40:11
123_S1V1C2|ABC_S1V1C2|XYZ_S1V1C2|column|valid|123_S1V1|2019-11-09_20:40:11
123_S1V1C3|ABC_S1V1C3|XYZ_S1V1C3|column|valid|123_S1V1|2019-11-09_20:40:11
123_S1V2|ABC_S1V2|XYZ_S1V2|view|valid|123_S1|2019-11-09_20:40:11
123_S1V2C1|ABC_S1V2C1|XYZ_S1V2C1|column|valid|123_S1V2|2019-11-09_20:40:11
123_S1V2C2|ABC_S1V2C2|XYZ_S1V2C2|column|valid|123_S1V2|2019-11-09_20:40:11
123_S1V2C3|ABC_S1V2C3|XYZ_S1V2C3|column|valid|123_S1V2|2019-11-09_20:40:11
PS: I tried row mapper approach but confused on how to maintain parent-child relationships like a schema can have list of tables/views. Similarly a table/view can have multiple columns.
It would be much easier if you used an ORM tool like hibernate. That way, your queries can easily return entity pojos which can later be converted to JSON using a tool like Jackson or GSON
We are using the spring-data-elasticsearch project to interface with our elasticsearch clusters, and have been using it now for around a year. Recently, we moved to elasticsearch 5.x (from 2.x) where we now have the "keyword" datatype.
I would like to index these keywords as lowercase values, which I know can be done with field normalizers. I can't find anywhere in the documentation or online where I can add a normalizer to a field through the annotation based mapping.
E.g
#Field(type = FieldType.keyword, <some_other_param = some_normalizer>)
Is this something that can be done? I know that we can use JSON based mapping definitions as well, so I will fall back to that option if needed, but would like to be able to do it this way if possible.
Any help would be very appreciated!
Since the pull request of #xhaggi has been merged (spring-data-elasticsearch 3.1.3+ or Spring Boot 2.1.1), we have a normalizer field in the #Field annotation.
To use it, we need:
declare a #Field or an #InnerField with params type = FieldType.Keyword, normalizer = "%NORMALIZER_NAME%"
add #Setting(settingPath = "%PATH_TO_NORMALIZER_JSON_FILE%") at the class level.
put the normalizer mapping into a json file at %PATH_TO_NORMALIZER_JSON_FILE%
Example of usage
FYI, for anyone looking at this, the answer is there is not a way to do this at this time.
You can do this, however, by creating your mappings file as JSON in the Elasticsearch format. See:
https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-put-mapping.html
You can then create that JSON file and link it to your Domain model with.
#Mapping(mappingPath = "some/path/mapping.json")
Note that this is not, in my experience, compatible with the provided annotation based mapping for fields.
There is a pending issue https://jira.spring.io/browse/DATAES-492 waiting for review.
Note: Editing this to rephrase it around JAXB in hopes of getting new answers. I'm using CXF, but it's using JAXB for the mappings.
I've got a POJO model. Right now I have it mapped via annotations and using JAXB to spew/read XML. However that's only one XML format and I need to map that POJO model to one of various XML formats depending on the 3rd party system I'm integrating with (e.g. various 3rd parties all have the concept of a "person", but map it differently). I've read through the entire JAXB tutorial, but everything is centered around annotations. Is there some external way to map the classes so I can read/write multiple mappings where I pick the mapping to use at any given point (i.e. I know I'm spewing a "person" to Foo Inc., so use the foo mapping)?
Edit: I just found something called JAXBIntroductions that might do the job.
http://community.jboss.org/wiki/JAXBIntroductions
If you are using EclipseLink JAXB (MOXy) you can take advantage of the externalized mapping feature to apply many XML representations to your POJOs.
http://wiki.eclipse.org/EclipseLink/Examples/MOXy/EclipseLink-OXM.XML
Also, since MOXy's mappings are XPath based you can actually map your POJOs to a wide variety of XML schemas.
you can use XStream for this. you can work without annotations like this:
XStream xstream = new XStream();
XStream xstream = new XStream(new DomDriver());
xstream.alias("person", Person.class);
xstream.alias("phonenumber", PhoneNumber.class);
hope that helps
EDIT: create another XStream instance for a different output
Person demo = new Person("Chris");
XStream xStream = new XStream();
xStream.alias("person", Person.class);
System.out.println(xStream.toXML(demo));
XStream xStream2 = new XStream();
xStream2.alias("dev", Person.class);
System.out.println(xStream2.toXML(demo));
output:
<person>
<name>Chris</name>
</person>
<dev>
<name>Chris</name>
</dev>
you can try http://code.google.com/p/jlibs/wiki/SAX2JavaBinding
This is also based on annotations. but annotations are not on your POJO.