1

I have a class:

class Setting {

    String configurationName;
    String configuration; 
} 

I want to return the string representation how configuration will look like. This can be different object based on some conditions.

In one of service I do below :

@GET
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response getConfigurationSetting ()
{
    try {

        Setting settingPojo = new Setting();
        settingPojo.setCOnfigurationName("DataBase");

        ObjectMapper mapper = new ObjectMapper();

        SchemaFactoryWrapper visitor = new SchemaFactoryWrapper();

        mapper.acceptJsonFormatVisitor(OracleConfiguration.class, visitor);

        JsonSchema schema = visitor.finalSchema();

        settingPojo.setConfiguraton(mapper.writeValueAsString(schema));

        return Response.status(HTTP.CodeOK).entity(settingPojo).build();
    } catch (Exception ex) {
        // exception logic
    }
}

There can be different class like this : "MySQLConfiguration.class".

Sample :

{
    configurationName : "DataBase",
    configuration: "{
       \"type\":\"object\",
       \"id\":\"urn\":\"jsonschema\":\"database\":\"model\":\"OracleConfiguration\",
       \"properties\":{
          \"numberOfConnection\":{
             \"type\":\"integer\"
          },
          \"connectionDate\":{
             \"type\":\"integer\",
             \"format":\"utc-millisec\"
          },
          \"isconnected\":{
             \"type\":\"boolean\"
          }
       }
    }"
}
  

Problems with above output:

  1. I want to remove id property from the string.
  2. I am getting that weird extra backslash for escape character. I do not see that while debugging and executing this line : mapper.writeValueAsString(schema).But I see that backslash and extra quotes after I set to property.

Any idea how to resolve these?

Michał Ziober
  • 37,175
  • 18
  • 99
  • 146
MrSham
  • 539
  • 3
  • 8
  • 19
  • 2
    Stop double-encoding your JSON. – chrylis -cautiouslyoptimistic- Jul 02 '21 at 23:12
  • @chrylis-cautiouslyoptimistic- thanks for response .. did not get you.. what do you mean stop double encoding json? I want to show the user what data type that class will be – MrSham Jul 02 '21 at 23:19
  • `JsonSchema` object is encoded two times. First time it is encoded directly by you: `mapper.writeValueAsString(schema)`. Second time it is encoded by Spring. Change type from `String` to `Object` - `Object configuration;` and in controller just set it without extra serialisation: `settingPojo.setConfiguraton(schema);` – Michał Ziober Jul 06 '21 at 20:02

1 Answers1

0
  1. You can instruct Jackson to remove id using MixIn feature. Take a look at the example.
  2. Object is serialised twice, once directly by you in the controller method, second - by Spring.

In your example you need to:
Use @JsonRawValue annotation in Setting class:

class Setting {
    String configurationName;

    @JsonRawValue
    String configuration;
}

Create a MixIn abstract class:

abstract class JsonSchemaWithoutId {

    @JsonIgnore
    public String id;

    @JsonIgnore
    public abstract String getId();
}

Simple usage:

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonRawValue;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.module.jsonSchema.JsonSchema;
import com.fasterxml.jackson.module.jsonSchema.factories.SchemaFactoryWrapper;
import lombok.Data;

import java.io.File;
import java.io.IOException;

public class JsonMixInAndSchemaApp {

    public static void main(String[] args) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        mapper.enable(SerializationFeature.INDENT_OUTPUT);
        mapper.addMixIn(JsonSchema.class, JsonSchemaWithoutId.class);

        Setting settingPojo = new Setting();
        settingPojo.setConfigurationName("Setting");

        SchemaFactoryWrapper visitor = new SchemaFactoryWrapper();
        mapper.acceptJsonFormatVisitor(Setting.class, visitor);
        JsonSchema schema = visitor.finalSchema();

        settingPojo.setConfiguration(mapper.writeValueAsString(schema));

        mapper.writeValue(System.out, settingPojo);
    }
}

Above code prints

{
  "configurationName" : "Setting",
  "configuration" : {
  "type" : "object",
  "properties" : {
    "configurationName" : {
      "type" : "string"
    },
    "configuration" : {
      "type" : "string"
    }
  }
}
}
Michał Ziober
  • 37,175
  • 18
  • 99
  • 146