declare java.util.Map into json-schema - java

I need to map a java.util.Map instance into a JSON-schema that is used by org.jsonschema2pojo maven plugin to create a POJO.
I didn't find a good and simple solution for this.
Could someone help me please?
This is my actual json-schema file
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Response",
"description": "A Response object",
"type": "object",
"properties": {
"result": {
"type": "string",
"description": "describes response status"
},
"msg": {
"type": "string",
"description": "user msgs"
}
},
"required": ["result"],
"additionalProperties": false
}
I need to add a field "errors" that is converted into a java.util.Map<String, String> in Java.

AFAIK additionalProperties does the job.
You can declare an errors property of type Map<String, Object> for example like this (this is yaml now):
...
properties:
errors:
type: object
additionalProperties:
type: object
You don't specify the type of the keys, since this describes a json document, which naturally has strings as keys on objects.
instead of type: object you can also do type: string for Map<String, String> or reference another definition if you have your own type as values in that map.

Related

Validate Map<String,Object> object matches json schema

I have a json schema, for example:
{
"type": "object",
"ignoreUnknown": true,
"properties": {
"address" : {
"type" : "string"
}
}
}
I want to check whether an object of type Map<String,Object> matches the schema or not.
The schema is received as a String.
How can I achieve this in Java? (Preferably using Jackson)
Thanks.
Although it isn't Jackson-based, you can do that using the everit-org/json-schema library as follows:
Map<String, Object> myInstance = ...
SchemaLoader.builder()
.schemaJson(new JSONObject("{my-schema-json}"))
.build().load().build().validate(new JSONObject(myInstance));
Disclaimer: I am a developer of this library

What point of same properites at that json?

When I get this json at POST method I need create a object. But I can't see what I need do exactly with this code. Why there is a lot of same properties? Are they a object of different class in fields class?or what? If they are why not like that host:{ "value":"120.515.151.124"}. Could someone help or show some documents about that?
{
"fields": [
{
"name": "host",
"value": "102.164.152.128"
},
{
"name": "port",
"value": "8564"
},
{
"name": "accessKey",
"value":
"(here is a 64 bit a key like(531b8e6c...)"
},
{
"name": "secretKey",
"value":
"(also here is a 64 bit a key like(531b8e6c...)"
}
]
}
fields is an array of key value pairs.. So, this object will contain a fields object, which is a map. Can you try like this..
public class MyClass {
Map<String, String> fields;
}

Jackson map JSON containing different items for same object

I've got the follwoing JSON structure with the corresponding DTOs in Java:
{
"kind": "object 1",
"selfLink": "some_link",
"items": [
{
"kind": "subkind 1",
"name": "server 1",
"anotherObject": {
"link": "some_link",
"isSubcollection": true,
"items": [
{
"att 1": "value",
"att2": "value",
"att3": "value"
},
{
"att5": "value" ,
"att6": "value" ,
"att7": "value" ,
"att8": "value"
}
]
}
}
]
}
Now I want to map this into corresponding DTOs using Jackson. Using the #JsonIgnoreUnknown annotation, this works fine. The problem is within the items array: How can I map different classes from the same JSON list in Jackson? Of course I could create a huge class containing both's attributes, but that would not be my way of choice.
I hope you can help me.

Jackson - Deserialize Array without property name

I have the following JSON response from shipcloud.io:
[
{
"name": "dhl",
"display_name": "Deutsche Post DHL",
"services": [
"standard",
"returns",
"one_day",
"one_day_early"
],
"package_types": [
"parcel",
"bulk"
]
},
{
"name": "dpag",
"display_name": "Deutsche Post",
"services": [
"standard"
],
"package_types": [
"letter",
"parcel_letter",
"books"
]
},
{
"name": "dpd",
"display_name": "DPD - Dynamic Parcel Distribution",
"services": [
"standard",
"returns",
"one_day",
"one_day_early"
],
"package_types": [
"parcel",
"parcel_letter"
]
}
]
How can I deserialize this JSON array with Jackson? Usually I use a simple POJO and define
the property name of the list / array (#JsonProperty("blub") e.g.). Problem is, there is no property name used here...
I tried it using an empty property name, but it didn't work.
I'm just getting this error message:
Can not deserialize instance of Response.CarriersResponse out of
START_ARRAY token
If you want to use jackson, this is the solution that works for me:
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, false);
You are deserializing multiple objects of the type, so you need to do it as a list, like this
// somewhere in an example TypeReferences class
public static final TypeReference<List<Response.CarriersResponse>> CARRIER_RESPONSES = new TypeReference<List<Response.CarriersResponse>>() {
};
// elsewhere where you're calling the mapper
List<Response.CarriersResponse> responses = mapper.readValue(text, TypeReferences.CARRIER_RESPONSES);
You could instantiate it in-place, but that's a design decision between performance vs total memory consumption.
Try to deserialize to Response.CarriersResponse[] class.
Response.CarriersResponse[] responses = mapper.readValue(text, Response.CarriersResponse[].class);

additionalProperties eliminates all model properties

I have run into this issue now with implementing arbitrary field behaviour with additionalProperties. Below is my model with additional properties.
"CObject": {
"type": "object",
"properties": {
"_id": {
"type": "string"
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"updatedAt": {
"type": "string",
"format": "date-time"
}
},
"additionalProperties": {
"type": "string"
}
}
Indeed the only change I see in the generated java client is that my CObject.java now sub-classes HashMap class. I expected that a call to put([key],[value]) on CObject would just add a new property in the request body. On running a test, I realized that all properties within CObject are absent in the final request body. So, the client only sends a request body with properties defined arbitrarily and eliminates all other properties defined in the specification. Am using the latest swagger-codegen(2.1.6 snapshot). how can I get past this issue???
NB I don't want the map values to appear under their own property, I want the key value pairs to appear under the same hierarchy as the rest of the properties defined in the spec.
In the JSON you provided, "additionalProperties" is just a property name and its type is string. Let's say the property name is "keyValuePair", then the correct way to use additionalProperties is
"keyValuePair": {
{
"type": "object",
"additionalProperties": {
"type": "string"
}
}
}

Categories

Resources