How to remove the id field ("id" : "urn:jsonschema:org:gradle:Person")
from JSON schema created using Jackson?
Generated Schema
{
"type" : "object",
"id" : "urn:jsonschema:org:gradle:Person",
"properties" : {
"name" : {
"type" : "string"
}
}
}
For POJO class (Person.class)
import com.fasterxml.jackson.annotation.JsonProperty;
public class Person {
#JsonProperty("name")
private String name;
}
Using JSON Schema Generator
import java.io.IOException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.module.jsonSchema.JsonSchema;
import com.fasterxml.jackson.module.jsonSchema.JsonSchemaGenerator;
public final class GetJsonSchema {
public static String getJsonSchema2(Class clazz) throws IOException {
ObjectMapper mapper = new ObjectMapper();
JsonSchemaGenerator jsonSchemaGenerator = new JsonSchemaGenerator(mapper);
JsonSchema jsonSchema = jsonSchemaGenerator.generateSchema(clazz);
return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonSchema);
}
}
Invoked like
System.out.println(JsonSchema.Create(Person.class));
Just set id to null.
E.g.:
jsonSchema.setId(null);
As sachin said, jsonSchema.setId(null) is a good way to accomplish your goal. But Venkat is right in that complex types will still have the id's.
One way to remove them is to use a custom SchemaFactoryWrapper, which will instantiate its own visitorContext which will refuse to provide a URN. However, it's important to note this won't work if one type refers to itself (for example, a status object that might have children status objects).
For example:
private static class IgnoreURNSchemaFactoryWrapper extends SchemaFactoryWrapper {
public IgnoreURNSchemaFactoryWrapper() {
this(null, new WrapperFactory());
}
public IgnoreURNSchemaFactoryWrapper(SerializerProvider p) {
this(p, new WrapperFactory());
}
protected IgnoreURNSchemaFactoryWrapper(WrapperFactory wrapperFactory) {
this(null, wrapperFactory);
}
public IgnoreURNSchemaFactoryWrapper(SerializerProvider p, WrapperFactory wrapperFactory) {
super(p, wrapperFactory);
visitorContext = new VisitorContext() {
public String javaTypeToUrn(JavaType jt) {
return null;
}
};
}
}
private static final String printSchema(Class c) {
try {
ObjectMapper mapper = new ObjectMapper();
IgnoreURNSchemaFactoryWrapper visitor = new IgnoreURNSchemaFactoryWrapper();
mapper.acceptJsonFormatVisitor(c, visitor);
JsonSchema schema = visitor.finalSchema();
schema.setId(null);
ObjectWriter writer = mapper.writerWithDefaultPrettyPrinter();
String asString = writer.writeValueAsString(schema);
return asString;
} catch(Exception e) {
e.printStackTrace();
return null;
}
}
Related
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:
I want to remove id property from the string.
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?
You can instruct Jackson to remove id using MixIn feature. Take a look at the example.
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"
}
}
}
}
I use Jackson to serialise POJOs into CSV. Now we need to change the naming for certain fields to snake_case. This is easily done by #JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class).
For compatibility reasons we need some of the renamed fields also with their old name.
E.g.:
public class Pojo {
private int someField;
}
Default will serialise to "someField", SnakeCaseStrategy will serialise to "some_field".
How to get serialization with both?:
{
"someField" : "one",
"some_field" : "one"
}
My first try was a mixin:
public abstract class PojoFormat {
#JsonProperty("someField")
abstract String getSomeField();
}
but this effectively only undoes the naming strategy change.
So how to copy a field in serialization - preferable not by changing the Pojo (this copied fields should be removed when all clients can cope with it).
Little update:
in my real class there some nested class that use JsonUnwrapped and the doc stated that this is not working with custom serializer (didn't know that this makes a difference here).
Well, I have never seen this before, I would be very happy if someone here in this site knows how.
The easy way, in my opinion, is to use a Custom Serializer.
For example:
Using the #JsonSerialize annotation
Register a module
Dynamic Serializer with Reflection
#JsonSerialize annotation
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
#JsonSerializer(using=PojoSerializer.class)
class Pojo {
private String myValue;
// getters and setters
}
class PojoSerializer extends StdSerializer<Pojo> {
public PojoSerializer() {
super(Pojo.class);
}
#Override
public void serialize(Pojo value, JsonGenerator gen, SerializerProvider provider) throws IOException {
gen.writeStartObject();
gen.writeStringField("myValue", value.getMyValue());
gen.writeStringField("my_value", value.getMyValue());
gen.writeEndObject();
}
}
Module
static class Pojo {
private String myValue;
public String getMyValue() {
return myValue;
}
public Pojo setMyValue(String myValue) {
this.myValue = myValue;
return this;
}
}
static class PojoSerializer extends StdSerializer<Pojo> {
public PojoSerializer() {
super(Pojo.class);
}
#Override
public void serialize(Pojo value, JsonGenerator gen, SerializerProvider provider) throws IOException {
gen.writeStartObject();
gen.writeStringField("myValue", value.getMyValue());
gen.writeStringField("my_value", value.getMyValue());
gen.writeEndObject();
}
}
public static void main(String[] args) throws JsonProcessingException {
final ObjectMapper mapper = new ObjectMapper();
final SimpleModule module = new SimpleModule("PojoModule");
module.addSerializer(Pojo.class, new PojoSerializer());
mapper.registerModule(module);
final Pojo pojo = new Pojo();
pojo.setMyValue("This is the value of my pojo");
System.out.println(mapper.writeValueAsString(pojo));
}
Reflection
I write some code for you, you might want to see to get new ideias.
This works as a generic way(just to not write several serializers).
// The serializer will be register in the ObjectMapper module.
static class Pojo {
private String myValue = "With snake and camel";
private String value = "Without snake case";
private String thirdValue = "snake & camel";
}
// using the annotation
#JsonSerialize(using = PojoSerializer.class)
static class Pojo2 {
private String pojoName = "Pojo 2";
private String pojo = "pojp";
}
static class PojoSerializer extends StdSerializer<Object> {
public PojoSerializer() {
super(Object.class);
}
#Override
public void serialize(Object value, JsonGenerator gen, SerializerProvider provider) throws IOException {
gen.writeStartObject();
final Field[] fields = value.getClass().getDeclaredFields();
for(final Field field : fields) {
final String name = field.getName();
final String fieldValue;
try {
// Do not use this!
fieldValue = (String)field.get(value);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
byte firstUpperCase = -1;
for(byte index = 0; index < name.length(); index++) {
final char caractere = name.charAt(index);
// A ascii code is 66 decimal, and 90 is the Z in decimal
if(caractere > 'A' && caractere < 'Z') {
// found the first upper
firstUpperCase = index;
break;
}
}
// writes the normal field name
gen.writeStringField(name, fieldValue);
// if the name is in camel case, we will write in snake case too.
if(firstUpperCase != -1) {
final char lowerLetter = (char)((int) name.charAt(firstUpperCase) + 32);
final String left = name.substring(0, firstUpperCase);
final String right = String.format("%c%s",lowerLetter, name.substring(firstUpperCase + 1));
gen.writeStringField(String.format("%s_%s", left, right), fieldValue);
}
}
gen.writeEndObject();
}
}
You can try to use JsonAnyGetter annotation and define for every POJO extra mapping for backward compatibility.
Let's create a simple interface:
interface CompatibleToVer1 {
#JsonAnyGetter
Map<String, Object> getCompatibilityView();
}
and two classes which implement it:
#Data
#NoArgsConstructor
#AllArgsConstructor
#JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
class RootPojo implements CompatibleToVer1 {
private int rootId;
#JsonUnwrapped
private SomePojo pojo;
#Override
public Map<String, Object> getCompatibilityView() {
return Collections.singletonMap("rootId", rootId);
}
}
#Data
#NoArgsConstructor
#AllArgsConstructor
#JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
class SomePojo implements CompatibleToVer1 {
private int someField;
private String someName;
#Override
public Map<String, Object> getCompatibilityView() {
Map<String, Object> extra = new LinkedHashMap<>();
extra.put("someField", someField);
return extra;
}
}
As you can see, I defined extra columns for each POJO with custom names. Serialising to JSON is straightforward:
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
SomePojo pojo = new SomePojo(123, "Tom");
mapper.writeValue(System.out, new RootPojo(1, pojo));
Above code prints:
{
"root_id" : 1,
"some_field" : 123,
"some_name" : "Tom",
"someField" : 123,
"rootId" : 1
}
But for CSV we need to create extra configuration:
CsvMapper csvMapper = CsvMapper.builder().build();
CsvSchema pojoExtraScheme = CsvSchema.builder()
.addColumn("someField")
.build();
CsvSchema rootExtraScheme = CsvSchema.builder()
.addColumn("rootId")
.build();
CsvSchema compatibleSchema = CsvSchema.emptySchema()
.withHeader()
.withColumnsFrom(csvMapper.schemaFor(RootPojo.class))
.withColumnsFrom(rootExtraScheme)
.withColumnsFrom(csvMapper.schemaFor(SomePojo.class))
.withColumnsFrom(pojoExtraScheme);
SomePojo tom = new SomePojo(123, "Tom");
SomePojo jerry = new SomePojo(124, "Jerry");
List<RootPojo> pojos = Arrays.asList(new RootPojo(1, tom), new RootPojo(2, jerry));
ObjectWriter writer = csvMapper.writer(compatibleSchema);
System.out.println(writer.writeValueAsString(pojos));
Above code prints:
some_field,some_name,root_id,rootId,someField
123,Tom,1,1,123
124,Jerry,2,2,124
If you do not want to specify extra columns two times you can implement builder method based on our interface:
CsvSchema createSchemaFor(CompatibleToVer1 entity) {
CsvSchema.Builder builder = CsvSchema.builder();
entity.getCompatibilityView().keySet().forEach(builder::addColumn);
return builder.build();
}
and use as below:
CsvSchema compatibleSchema = CsvSchema.emptySchema()
.withHeader()
.withColumnsFrom(csvMapper.schemaFor(RootPojo.class))
.withColumnsFrom(createSchemaFor(new RootPojo()))
.withColumnsFrom(csvMapper.schemaFor(SomePojo.class))
.withColumnsFrom(createSchemaFor(new SomePojo()));
Using JsonAnyGetter with CSV is really tricky and could be problematic mixing it with other annotations, take a look at: Could please add JsonAnyGetter and JsonAnySetter annotations support?
I have Jackson annotated class like this :
public class MyClass {
String field1;
#JsonIgnore
String field2;
String field3;
#JsonIgnore
String field4;
}
Assume that I cannot change MyClass code. Then, how can I make ObjectMapper override the JsonIgnore for field2 only and serialize it to json ? I want it to ignore field4 though. Is this easy and few lines of code ?
My code for regular serialization :
public String toJson(SomeObject obj){
ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter();
String json = null;
try {
json = ow.writeValueAsString(obj);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return json;
}
You can use MixIn feature:
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
public class JsonApp {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
mapper.addMixIn(MyClass.class, MyClassMixIn.class);
System.out.println(mapper.writeValueAsString(new MyClass()));
}
}
interface MyClassMixIn {
#JsonProperty
String getField2();
}
Above code prints:
{
"field1" : "F1",
"field2" : "F2",
"field3" : "F3"
}
You could use a custom serializer, like so (I leave the refactoring up to you):
private String getJson(final MyClass obj) {
final ObjectMapper om = new ObjectMapper();
om.registerModule(new SimpleModule(
"CustomModule",
Version.unknownVersion(),
Collections.emptyMap(),
Collections.singletonList(new StdSerializer<MyClass>(MyClass.class) {
#Override
public void serialize(final MyClass value, final JsonGenerator jgen, final SerializerProvider provider) throws IOException {
jgen.writeStartObject();
jgen.writeStringField("field1", value.field1);
jgen.writeStringField("field2", value.field2);
jgen.writeStringField("field3", value.field3);
jgen.writeEndObject();
}
})));
try {
return om.writeValueAsString(obj);
} catch (final JsonProcessingException e) {
throw new RuntimeException(e);
}
}
You can find more information about custom serializers on google/stackoverflow, I think I answered something similar here
My lib is calling an API which can return either of the following JSON structure -
{
"key_is_same" : {
"inner" : "val"
}
}
-or-
{
"key_is_same" : [{
"inner" : "val1"
},
{
"inner" : "val2"
}
]
}
Is there any annotation in jakson which can handle this and deserializ it into respective type
Looks like you are looking for the ACCEPT_SINGLE_VALUE_AS_ARRAY deserialization feature.
Feature that determines whether it is acceptable to coerce non-array (in JSON) values to work with Java collection (arrays, java.util.Collection) types. If enabled, collection deserializers will try to handle non-array values as if they had "implicit" surrounding JSON array. This feature is meant to be used for compatibility/interoperability reasons, to work with packages (such as XML-to-JSON converters) that leave out JSON array in cases where there is just a single element in array.
Feature is disabled by default.
It could be enabled either in ObjectMapper:
ObjectMapper mapper = new ObjectMapper();
mapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
Or via the #JsonFormat annotation:
#JsonFormat(with = Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
private List<Foo> oneOrMany;
For illustration purposes, consider the following JSON documents:
{
"oneOrMany": [
{
"value": "one"
},
{
"value": "two"
}
]
}
{
"oneOrMany": {
"value": "one"
}
}
It could be the deserialized to the following classes:
#Data
public class Foo {
private List<Bar> oneOrMany;
}
#Data
public class Bar {
private String value;
}
Just ensure the feature is enabled in your ObjectMapper or your field is annotated with #JsonFormat(with = Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY).
And in case you are looking for the equivalent feature for serialization, refer to WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED.
I would recommend using Object as your data type for the property which is dynamic. So Here is my sample.
import java.util.Arrays;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class MainObject {
private Object key_is_same;
public Object getKey_is_same() {
return key_is_same;
}
public void setKey_is_same(Object key) {
this.key_is_same = key;
}
public static class KeyObject {
private String inner;
public String getInner() {
return inner;
}
public void setInner(String inner) {
this.inner = inner;
}
}
public static void main(String...s) throws JsonProcessingException {
MainObject main = new MainObject();
KeyObject k = new KeyObject();
k.setInner("val1");
main.setKey_is_same(k);
ObjectMapper om = new ObjectMapper();
System.out.println(om.writeValueAsString(main));
main.setKey_is_same(Arrays.asList(k, k));
System.out.println(om.writeValueAsString(main));
public static void main(String...s) throws IOException {
MainObject main = new MainObject();
KeyObject k = new KeyObject();
k.setInner("val1");
main.setKey_is_same(k);
ObjectMapper om = new ObjectMapper();
System.out.println(om.writeValueAsString(main));
main.setKey_is_same(Arrays.asList(k, k));
System.out.println(om.writeValueAsString(main));
// Deserialize
MainObject mainWithObject = om.readValue("{\"key_is_same\":{\"inner\":\"val1\"}}", MainObject.class);
MainObject mainWithList = om.readValue("{\"key_is_same\":[{\"inner\":\"val1\"},{\"inner\":\"val1\"}]}", MainObject.class);
if(mainWithList.getKey_is_same() instanceof java.util.List) {
((java.util.List) mainWithList.getKey_is_same()).forEach(System.out::println);
}
}
}
}
Output
{"key_is_same":{"inner":"val1"}}
{"key_is_same":[{"inner":"val1"},{"inner":"val1"}]}
{
"key1": {
"parameter1": "String1",
"parameter2": "String2"
},
"key2": {
"parameter1": "String3",
"parameter2": "String4"
},
"key3": {
"parameter1": "String5",
"parameter2": "String6"
}
}
I have the above JSON (/Users/user1/Desktop/responseMap.json) which is basically a Map<String, MockResponse> where MockResponse is the below POJO:
public class MockResponse {
public String parameter1;
public String parameter2;
}
Now, I have another POJO - TestCase, and another JSON - testCase.json as below:
public class TestCase {
public String responseMapFileLocation;
public String mockResponseKey;
public MockResponse mockResponse;
}
testCase.json
{
"responseMapFileLocation": "/Users/user1/Desktop/responseMap.json",
"mockResponseKey": "key1",
"mockResponse": null
}
What I am able to do is first map testCase.json to TestCase using Jackson, then map responseMap.json to Map<String, MockResponse>, then in my code search for mockResponseKey in the map.
But what I want to do is when I map testCase.json to TestCase using Jackson, I want the value of variable mockResponse to set automatically based on the value of variable mockResponseKey using the first JSON map.
You need to write custom deserialiser for TestCase class. In custom deserialiser you can parse basic properties: responseMapFileLocation, mockResponseKey and load mockResponse from other file. To deserialiser MockResponse you can use new ObjectMapper instance. Below code shows how this concept could be implemented:
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.TreeNode;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.type.MapType;
import java.io.File;
import java.io.IOException;
import java.util.Map;
public class JsonApp {
public static void main(String[] args) throws Exception {
File jsonFile = new File("./resource/test.json").getAbsoluteFile();
ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.readValue(jsonFile, TestCase.class));
}
}
class MockResponse {
public String parameter1;
public String parameter2;
}
#JsonDeserialize(using = TestCaseFromExternalFileDeserializer.class)
class TestCase {
public String responseMapFileLocation;
public String mockResponseKey;
public MockResponse mockResponse;
}
class TestCaseFromExternalFileDeserializer extends JsonDeserializer<TestCase> {
private final ObjectMapper mapper;
private final MapType mapType;
public TestCaseFromExternalFileDeserializer() {
mapper = new ObjectMapper();
mapType = mapper.getTypeFactory().constructMapType(Map.class, String.class, MockResponse.class);
}
#Override
public TestCase deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
TreeNode treeNode = p.readValueAsTree();
TestCase testCase = new TestCase();
testCase.responseMapFileLocation = ((JsonNode) treeNode.get("responseMapFileLocation")).asText();
testCase.mockResponseKey = ((JsonNode) treeNode.get("mockResponseKey")).asText();
parseMockResponse(testCase);
return testCase;
}
private void parseMockResponse(TestCase testCase) throws IOException {
Map<String, MockResponse> map = mapper.readValue(new File(testCase.responseMapFileLocation), mapType);
testCase.mockResponse = map.get(testCase.mockResponseKey);
}
}
You need to implement only toString method for each POJO class. Above code prints:
TestCase{responseMapFileLocation='./resource/responseMap.json', mockResponseKey='key1', mockResponse=MockResponse{parameter1='String1', parameter2='String2'}}
Both JSON files are in resource folder.
See also:
How use jackson ObjectMapper inside custom deserializer?
Jackson Streaming API - if you want to implement MockResponse deserialisation in faster way.
Tweaking the getter setter in your Test class and marking the field as private I was able to make it dynamic (Imports are from org.codehaus.jackson package)
class TestCase {
private String responseMapFileLocation;
private String mockResponseKey;
#JsonIgnore
private MockResponse mockResponse; //else value will be override in json value
public String getResponseMapFileLocation() {
return responseMapFileLocation;
}
public void setResponseMapFileLocation(String responseMapFileLocation) {
this.responseMapFileLocation = responseMapFileLocation;
}
public String getMockResponseKey() {
return mockResponseKey;
}
public void setMockResponseKey(String mockResponseKey1) throws IOException {
ObjectMapper mapper = new ObjectMapper();
Map<String, MockResponse> map = mapper.readValue(new File("C:\\Users\\Json1.json"), TypeFactory.mapType(HashMap.class, String.class, MockResponse.class));
this.mockResponse = map.get(mockResponseKey1);
this.mockResponseKey = mockResponseKey1;
}
public MockResponse getMockResponse() {
return mockResponse;
}
#Override
public String toString() {
return "TestCase [responseMapFileLocation=" + responseMapFileLocation + ", mockResponseKey=" + mockResponseKey
+ ", mockResponse=" + mockResponse + "]";
}
}
class MockResponse {
public String parameter1;
public String parameter2;
#Override
public String toString() {
return "MockResponse [parameter1=" + parameter1 + ", parameter2=" + parameter2 + "]";
}
}
and Running below code
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
TestCase testCase = mapper.readValue(new File("C:\\UsersJson2.json"), TestCase.class);
System.out.println(testCase);
}
output will be
TestCase [responseMapFileLocation=/Users/user1/Desktop/responseMap.json, mockResponseKey=key1, mockResponse=MockResponse [parameter1=String1, parameter2=String2]]
What you are asking for is not possible with just Jackson. Jackson is primarily a marshalling/unmarshalling tool, converting JSONs to Objects and vice versa. In other words, the value of the object must be known at the time of unmarshalling.
However you can unmarshal your json as a HashMap using the code:
new JSONObject(map);
search for the MockResponse-as-a-string using the mockResponseKey and then unmarshal that code into a new MockResponse.