Reputation: 1336
Just wondering if there was a way to do this - I have a class, something like
class MyClass {
private String name;
private String address;
private String number;
}
When I serialise it to Json, using Jackson, I want to wrap the String variables together, so it would look something like
{
"Strings": {
"name" : "value",
"address" : "value"
}
}
Without wrapping those variables in a List or Map class inside the MyClass... is this possible?
Upvotes: 1
Views: 10629
Reputation: 161
@Configuration
public class JacksonConfiguration {
@Bean
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
mapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true);
//mapper.setSerializationInclusion(Include.NON_DEFAULT);
return mapper;
}
}
Upvotes: 0
Reputation: 3036
A little bit old question, but while searching for a solution for the same problem i came across this answer.
Basicly create an ObjectWriter
from ObjectMapper
by using writer()
function and then set the rootName
for the mapping i.e
MyClass myclass = new MyClass()
myclass.setName("a");
myclass.setAddress("b");
ObjectMapper mapper = new ObjectMapper();
ObjectWriter writer = mapper.writer().withRootName("Strings");
String json = writer.writeValueAsString(myclass);
The output will be
{
"Strings": {
"name" : "a",
"address" : "b"
}
}
ObjectMapper is a threadsafe and the doc says it should be reuse when possible.
Upvotes: 0
Reputation: 68715
Jackson utilizes your class structure to decide about the json structure. If you need to wrap your class attributes in another attribute then you need to consider the wrapping. You don't need to create a collection if you don't need it. Simply put name and address in a different class and name that class as you desire the name for their wrapper. And then add instance of your wrapper class in your MyClass.
Upvotes: 1
Reputation: 11289
I use JsonSerializer
to do this for me with Spring, it is very simple.
you create a class that extends JsonSerializer
like this one:
public class ServerResposeSerializer extends JsonSerializer<ServerResponse> { @Override public void serialize(ServerResponse objectWrapper, JsonGenerator generator, SerializerProvider provider) throws IOException, JsonProcessingException { generator.writeStartObject(); generator.writeNumberField("http_status", objectWrapper.getStatus().value()); generator.writeStringField("message",objectWrapper.getMessage()); generator.writeArrayFieldStart("objects"); List<?> objects = objectWrapper.getObjects(); for (Object object: objects) { generator.writeObject(object); } generator.writeEndArray(); generator.writeEndObject(); }
}
Annotate ServerResponse
with the
@JsonSerialize (using = ServerResposeSerializer.class)
Now you can format any class you want to produce any kind of JSON String
Upvotes: 0
Reputation: 38645
You can also add into your POJO class additional getters for "Strings", "Intigers", etc. Those methods should return Map
's as a result. Consider below code:
import java.util.LinkedHashMap;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JacksonProgram {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
MyClass myClass = new MyClass();
myClass.setAddress("New York, Golden St. 1");
myClass.setName("James Java");
myClass.setNumber("444");
System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(myClass));
}
}
class MyClass {
private String name;
private String address;
private String number;
@JsonIgnore
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@JsonIgnore
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@JsonIgnore
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
@JsonProperty(value = "Strings")
public Map<String, String> getStrings() {
Map<String, String> map = new LinkedHashMap<String, String>();
map.put("name", getName());
map.put("address", getAddress());
map.put("number", getNumber());
return map;
}
}
Result:
{
"Strings" : {
"name" : "James Java",
"address" : "New York, Golden St. 1",
"number" : "444"
}
}
This is not, probably, the most elegant solution which you can use, but it is simple.
Upvotes: 2