I want to generate JSON schema where "additionalProperties" : false
will be applied for all classes which I have.
Suppose I have following classes:
class A{
private String s;
private B b;
public String getS() {
return s;
}
public B getB() {
return b;
}
}
class B{
private BigDecimal bd;
public BigDecimal getBd() {
return bd;
}
}
When I am generating schema as following like below code the schema property "additionalProperties" : false
was applying only for the class A
.
ObjectMapper mapper = new ObjectMapper();
JsonSchemaGenerator schemaGen = new JsonSchemaGenerator(mapper);
ObjectSchema schema = schemaGen.generateSchema(A.class).asObjectSchema();
schema.rejectAdditionalProperties();
mapper.writerWithDefaultPrettyPrinter().writeValueAsString(schema);
How can I generate the schema where "additionalProperties" : false
will be applied on all classes?
Example of schema
{
"type" : "object",
"id" : "urn:jsonschema:com.xxx.xxx:A",
"additionalProperties" : false,
"properties" : {
"s" : {
"type" : "string"
},
"b" : {
"type" : "object",
"id" : "urn:jsonschema:com.xxx.xxx:B",
"properties" : {
"bd" : {
"type" : "number"
}
}
}
}
}
Note: I don't want to generate schemes part by part.
For info: I have opened issue for this scenario if someone interested you can support fix of this issue. Generate json schema which should rejects all additional content
You will need to specify the schema for each properties like:
ObjectMapper mapper = new ObjectMapper();
JsonSchemaGenerator schemaGen = new JsonSchemaGenerator(mapper);
ObjectSchema schemaB = schemaGen.generateSchema(B.class).asObjectSchema();
schemaB.rejectAdditionalProperties();
ObjectSchema schema = schemaGen.generateSchema(A.class).asObjectSchema();
schema.rejectAdditionalProperties();
schema.putProperty("b", schemaB);
You can leverage reflection api to automatically do it for you. Here is a quick and dirty example:
public static void main(String[] args) throws JsonProcessingException {
final ObjectMapper mapper = new ObjectMapper();
final JsonSchemaGenerator schemaGen = new JsonSchemaGenerator(mapper);
ObjectSchema schema = generateSchema(schemaGen, A.class);
schema.rejectAdditionalProperties();
System.out.print(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(schema));
}
public static <T> ObjectSchema generateSchema(JsonSchemaGenerator generator, Class<T> type) throws JsonMappingException {
ObjectSchema schema = generator.generateSchema(type).asObjectSchema();
for (final Field field : type.getDeclaredFields()) {
if (!field.getType().getName().startsWith("java") && !field.getType().isPrimitive()) {
final ObjectSchema fieldSchema = generateSchema(generator, field.getType());
fieldSchema.rejectAdditionalProperties();
schema.putProperty(field.getName(), fieldSchema);
}
}
return schema;
}
Well I would go to a simpler route if you don't want to use reflections. I would use JSONPath. So you would need to add below to your pom.xml
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<version>2.3.0</version>
</dependency>
Then below code demonstrates how to alter the generated JSON file
package taruntest;
import com.jayway.jsonpath.*;
public class Test {
public static void main(String[] args) throws Exception {
String data = "{\n" +
" \"type\" : \"object\",\n" +
" \"id\" : \"urn:jsonschema:com.xxx.xxx:A\",\n" +
" \"additionalProperties\" : false,\n" +
" \"properties\" : {\n" +
" \"s\" : {\n" +
" \"type\" : \"string\"\n" +
" },\n" +
" \"b\" : {\n" +
" \"type\" : \"object\",\n" +
" \"id\" : \"urn:jsonschema:com.xxx.xxx:B\",\n" +
" \"properties\" : {\n" +
" \"bd\" : {\n" +
" \"type\" : \"number\"\n" +
" }\n" +
" }\n" +
" }\n" +
" }\n" +
"}";
DocumentContext doc = JsonPath.parse(data);
doc.put("$..[?(@.id =~ /urn:jsonschema:.*/)]", "additionalProperties", false);
String modified = doc.jsonString();
System.out.println(modified);
}
}
The output of the run is (formatted manually)
{
"type": "object",
"id": "urn:jsonschema:com.xxx.xxx:A",
"additionalProperties": false,
"properties": {
"s": {
"type": "string"
},
"b": {
"type": "object",
"id": "urn:jsonschema:com.xxx.xxx:B",
"properties": {
"bd": {
"type": "number"
}
},
"additionalProperties": false
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With