I have a simple class in java like below:
class Simple {
private String name;
private String email;
}
I want to have behaviour of java.util.List<Simple>
and Simple
both according to input data that my program receives.
i.e.
Case 1:: if my program receives below kind of json-array input
{"simple" : [ {"name":"a", "email" : "a@z.com"}, {"name":"b", "email" : "b@z.com"} ]}
I need to parse it using List<Simple>
Case 2:: if my program receives below kind of json-object input
{"simple" : {"name":"c", "email" : "c@z.com"} }
I need to parse it using Simple
Note: I have tried using JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY
, but the problem is it is basically converting single value also into json-array at the time of writing json.
I need to persist json as it is, is there any other way to achieve this?
To avoid any Jackson
customisation I would create wrapper class with an Object simple
property. We can add two extra checking methods and two extra casting methods. It will allow Jackson
to do it's logic and in runtime we can check what actually we have:
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.json.JsonMapper;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Collections;
import java.util.List;
public class DateApp {
private final static JsonMapper JSON_MAPPER = JsonMapper.builder().enable(SerializationFeature.INDENT_OUTPUT).build();
public static void main(String[] args) throws Exception {
Simple object = new Simple("John", "john@doe.com");
SimpleWrapper wrapper = new SimpleWrapper();
wrapper.setSimple(object);
serializeAndDeserialize(wrapper);
wrapper.setSimple(Collections.singletonList(object));
serializeAndDeserialize(wrapper);
}
private static void serializeAndDeserialize(SimpleWrapper wrapper) throws JsonProcessingException {
String json = JSON_MAPPER.writeValueAsString(wrapper);
System.out.println("JSON:");
System.out.println(json);
wrapper = JSON_MAPPER.readValue(json, SimpleWrapper.class);
System.out.println("Wrapper:");
System.out.println(wrapper);
}
}
@Data
class SimpleWrapper {
private Object simple;
@JsonIgnore
public boolean isSimpleObject() {
return simple instanceof Simple;
}
@JsonIgnore
public boolean isSimpleList() {
return simple instanceof List;
}
@JsonIgnore
public Simple getSimpleAsObject() {
return (Simple) simple;
}
@JsonIgnore
public List<Simple> getSimpleAsList() {
return (List<Simple>) simple;
}
}
@Data
@NoArgsConstructor
@AllArgsConstructor
class Simple {
private String name;
private String email;
}
Above code prints:
JSON:
{
"simple" : {
"name" : "John",
"email" : "john@doe.com"
}
}
Wrapper:
SimpleWrapper(simple={name=John, email=john@doe.com})
JSON:
{
"simple" : [ {
"name" : "John",
"email" : "john@doe.com"
} ]
}
Wrapper:
SimpleWrapper(simple=[{name=John, email=john@doe.com}])