How to model JSON response with Jackson in Java? - java

I am try to model an Api response using Jackson. The id will be the same type in all but the body will be different types.
An example response would be:
{
"responses": [
{
"id": "jobTitle",
"body": {
"jobTitle": "Software Engineer"
}
},
{
"id": "thumbnailPhoto",
"body": "base 64 bit string"
}
]
}
I have the following implementation. Is this the correct approach? If the type for body returns as a string, would the JobTitle be ignored/ null?
#JsonIgnoreProperties(ignoreUnknown = true)
public class Response
{
#JsonProperty("id")
private String id;
#JsonProperty("body")
private String photo;
#JsonProperty("body")
private JobTitle jobTitle;
// getters and setters
}

I'm no expert in this area, but I would like to share my answer here.
I don't know why you design the JSON string as an array of responses for your original question. I would suggest a better design to be a single instance of "Response" object as below:
{
"id":"response id",
"jobTitle":"title",
"img":"img b64 string"
}
Just leave the field null if not exists.
But if you insist on using the origin design, below code below coding can be achieved, but the JSON string need small changes to add "type" info Tutorial from Baeldung.
[ {
"id" : "1",
"body" : {
"type" : "jobTitle",
"jobTitle" : "job title"
}
}, {
"id" : "2",
"body" : {
"type" : "img",
"data" : "xxxxx"
}
} ]
Java coding as below:
package org.example.test4;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import java.util.ArrayList;
public class TestApp {
public static class Response<X extends Body> {
private String id;
private X body;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public X getBody() {
return body;
}
public void setBody(X body) {
this.body = body;
}
}
#JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "type"
)
#JsonSubTypes({
#JsonSubTypes.Type(value = JobTitle.class, name = "jobTitle"),
#JsonSubTypes.Type(value = IMG.class, name = "img")
})
public static abstract class Body{}
public static class JobTitle extends Body{
private String jobTitle;
public String getJobTitle() {
return jobTitle;
}
public void setJobTitle(String jobTitle) {
this.jobTitle = jobTitle;
}
}
public static class IMG extends Body{
private String data;
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
}
public static void main(String[] args) throws JsonProcessingException {
ObjectMapper om = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT);;
JobTitle jt = new JobTitle();
jt.setJobTitle("job title");
System.out.println(om.writeValueAsString(jt));
IMG img = new IMG();
img.setData("xxxxx");
System.out.println(om.writeValueAsString(img));
ArrayList<Response<?>> rs = new ArrayList<Response<?>>();
Response<JobTitle> r1 = new Response<JobTitle>();
r1.setId("1");
r1.setBody(jt);
rs.add(r1);
Response<IMG> r2 = new Response<IMG>();
r2.setId("2");
r2.setBody(img);
rs.add(r2);
System.out.println(om.writeValueAsString(rs));
}
}

Related

Mapping JSON response to different types

I'm using Spring 2.6 and we make a GET request via
restTemplate.exchange(url, HttpMethod.GET, httpEntity, ResponseType.class).getBody();
The JSON response can be of two kinds:
1st:
public class ResponseType {
private String data;
}
2nd:
public class ResponseType {
private Subclass data;
}
public class Subclass {
private String classId;
private String detail;
}
In the first version I only get a reference link to the subclass resource.
If the URL contains a 'resolve' flag, than the reference link get expanded already in the first request.
The classId then also specifies what kind of class it is ( 'a.b.c' or 'x.y.z' )
No problem for JSON, but how can I get a mapping in Java?
When having more fields being dynamic (link or instance based on classId) a manual way would be difficult to implement if the combination could be 2 links and 3 objects.
It also could be that a object has the same feature - a filed with a link or a instance of a class specified by classId.
The JSON response would be this:
{
"data": "abskasdkjhkjsahfkajdf-linkToResource"
}
or this:
{
"data": {
"classId": "a.b.subclass",
"detail": "some data"
}
}
or this:
{
"data": {
"classId": "a.b.subclass",
"detail": "some data"
"data2": "some-link-id",
"data3": {
"detailB": "foo",
"detailC": "some-link-id"
}
}
}
Here I do have a possible solution for my problem. The logic to print the address only or the POJO relies soley in the CustomItemSerializer. So it is possible to use this without using duplicate code in controllers.
package com.allianz.clana.datamodel.http.epc.test;
import java.io.IOException;
import java.text.ParseException;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import lombok.Data;
import lombok.NoArgsConstructor;
public class JacksonTester2 {
public static void main(String args[]) throws ParseException, JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
Item item2 = new Item("link");
Stuff stuff = new Stuff();
stuff.setItem(item2);
stuff.setFoo("foo");
String jsonStringStuff = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(stuff);
System.out.println(jsonStringStuff);
Item item3 = new Item("{ \"name\":\"ID3\", \"creationDate\":\"1984-12-30\", \"rollNo\": 1 }");
stuff.setItem(item3);
stuff.setFoo("bar");
jsonStringStuff = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(stuff);
System.out.println(jsonStringStuff);
}
}
class CustomItemSerializer extends StdSerializer<Item> {
private static final long serialVersionUID = 1L;
public CustomItemSerializer() {
this(null);
}
public CustomItemSerializer(Class<Item> t) {
super(t);
}
#Override
public void serialize(Item item, JsonGenerator generator, SerializerProvider arg2) throws IOException {
if (item != null) {
if (item.getItem() != null) {
System.out.println("ItemA POJO data");
generator.writePOJO(item.getItem());
} else {
System.out.println("raw data with link");
generator.writeString(item.getRawdata());
}
}
}
}
#Data
class Stuff {
Item item;
String foo;
}
#JsonSerialize(using = CustomItemSerializer.class)
#Data
#NoArgsConstructor
class Item {
private String rawdata;
#JsonIgnore
private ItemA item;
public Item(String rawdata) {
this.rawdata = rawdata;
if (rawdata.contains("{")) {
try {
this.item = new ObjectMapper().readerFor(ItemA.class).readValue(rawdata);
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
}
}
#Data
#NoArgsConstructor
class ItemA{
private String name;
private int rollNo;
private String creationDate;
public ItemA(String name, int rollNo, String dob) {
this.name = name;
this.rollNo = rollNo;
this.creationDate = dob;
}
}
The output looks like this:
raw data with link
{
"item" : "link",
"foo" : "foo"
}
ItemA POJO data
{
"item" : {
"name" : "ID3",
"rollNo" : 1,
"creationDate" : "1984-12-30"
},
"foo" : "bar"
}
The CustomItemSerializer decides if the link is printed or the POJO.

How to parse complex nested JSON in java?

I have a complex nested Json
It has a body similar to this:
{
staus: "Success",
id: 1,
data: [{'Movie':'kung fu panda','% viewed': 50.5},{'Movie':'kung fu panda 2','% viewed':1.5}],
metadata: {'filters':['Movie', 'Percentage Viewed'], 'params':{'content':'Comedy', 'type': 'Movie'}}
}
The only field I care about is data, and metadata is usually an even more complex/nested field. I was trying to map this to:
#JsonIgnoreProperties(ignoreUnknown = true)
class ResponseData{
public Data[] data;
#JsonIgnoreProperties(ignoreUnknown = true)
class Data{
public String Movie;
public double viewed;
}
}
I was looking at Jackson as an option and writing my own serializer and use JsonIgnore to discard the metadata but can't get around it.
Any suggestion on how this could be done?
You can use jackson-utils
public class Foo {
public static void main(String... args) {
ResponseData responseData1 = new ResponseData(
1,
"Success",
new ResponseData.Data[] {
new ResponseData.Data("kung fu panda", 50.5),
new ResponseData.Data("kung fu panda 2", 1.5) },
new ResponseData.Metadata(
new HashSet<>(Arrays.asList("Movie", "Percentage Viewed")),
new ResponseData.Metadata.Params("Comedy", "Movie"))
);
String json = JacksonUtils.prettyPrint().writeValue(responseData1);
System.out.println(json);
ResponseData responseData2 = JacksonUtils.readValue(json, ResponseData.class);
}
}
class ResponseData {
private int id;
private String status;
private Data[] data;
private Metadata metadata;
public ResponseData() {
}
public ResponseData(int id, String status, Data[] data, Metadata metadata) {
this.id = id;
this.status = status;
this.data = data;
this.metadata = metadata;
}
public static class Data {
#JsonProperty("Movie")
private String movie;
#JsonProperty("% viewed")
private double viewedPercents;
public Data() {
}
public Data(String movie, double viewedPercents) {
this.movie = movie;
this.viewedPercents = viewedPercents;
}
}
public static class Metadata {
private Set<String> filters;
private Params params;
public Metadata() {
}
public Metadata(Set<String> filters, Params params) {
this.filters = filters;
this.params = params;
}
public static class Params {
private String content;
private String type;
public Params() {
}
public Params(String content, String type) {
this.content = content;
this.type = type;
}
}
}
}
Console output:
{
"id" : 1,
"status" : "Success",
"data" : [ {
"Movie" : "kung fu panda",
"% viewed" : 50.5
}, {
"Movie" : "kung fu panda 2",
"% viewed" : 1.5
} ],
"metadata" : {
"filters" : [ "Movie", "Percentage Viewed" ],
"params" : {
"content" : "Comedy",
"type" : "Movie"
}
}
}
P.S. As an alternative, there is another util gson-utils with the same syntax.

Get the value of items of a Json with Java Spring Boot

I'm trying to extract API data from the Json file below.
I want to retrieve the "name" of each "item".
Once the "name" is retrieved, I want to create a new Json that will contain :
{name: "toto", name: "titi"....}
The goal is then to create an API on my side which on a call from http://localhost/getitems will return the result of the Json created.
I'm new to Java and Spring Boot, so if you think there is a code that is easier, let me know, i hope you can help me to create that new Json file easily. Thanks !
// Json File (it has been reduced, more than 700 name are present)
{
"kind": "Space",
"apiVersion": "v1",
"metadata": {
"selfLink": "something",
"resourceVersion": "something"
},
"items": [
{
"metadata": {
"name": "projet1"
}
},
{
"metadata": {
"name": "com-cicd"
}
}
]
}
// TestGet.java Class
public static NameSpaceJson getPostWithCustomHeaders(String DebutUrl, String MilieuUrl, String ParamUrl) {
String url = DebutUrl.concat(MilieuUrl).concat(ParamUrl);
String Bearer = "...";
// create headers & template
HttpHeaders headers = new HttpHeaders();
RestTemplate restTemplate = new RestTemplate();
// set `accept` header for the type of response
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
// set custom header, bearer here too
headers.set("x-request-source", "desktop");
headers.set("Authorization", "Bearer "+Bearer);
// build the request
#SuppressWarnings({ "rawtypes", "unchecked" })
HttpEntity request = new HttpEntity(headers);
// use `exchange` method for HTTP call, this one permits us to use bearer for auth
ResponseEntity<NameSpaceJson> response = restTemplate.exchange(url, HttpMethod.GET, request, NameSpaceJson.class, 1);
if(response.getStatusCode() == HttpStatus.OK) {
return response.getBody();
} else {
return null;
}
}
// The name in the same file
public static void main(String[] args) {
TestGet.disableSSLCertificateChecking();
NameSpaceJson resultresponse = getPostWithCustomHeaders("https...","api","names");
// Long response = resultresponse.getValue().getId();
List<Item> response = resultresponse.getItems();
String test = GenerateNewJsonNameSpace.createJsonContent(response);
System.out.println(test);
}
//NameSpaceJson.java File
package com.example.consumingrest;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
#JsonIgnoreProperties(ignoreUnknown = true)
public class NameSpaceJson {
private String kind;
private String apiVersion;
private List<Item> items;
public String getKind() {
return kind;
}
public void setKind(String kind) {
this.kind = kind;
}
public String getApiVersion() {
return apiVersion;
}
public void setApiVersion(String apiVersion) {
this.apiVersion = apiVersion;
}
public List<Item> getItems() {
return items;
}
public void setItems(List<Item> items) {
this.items = items;
}
}
//Metadata.java
package com.example.consumingrest;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
#JsonIgnoreProperties(ignoreUnknown = true)
public class Metadata {
private String name;
private String creationTimestamp;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCreationTimestamp() {
return creationTimestamp;
}
public void setCreationTimestamp(String creationTimestamp) {
this.creationTimestamp = creationTimestamp;
}
}
//Item.java
package com.example.consumingrest;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
#JsonIgnoreProperties(ignoreUnknown = true)
public class Item {
Metadata metadata;
public Metadata getMetadata() {
return metadata;
}
public void setMetadata(Metadata metadata) {
this.metadata = metadata;
}
}
// GenerateNewJsonNameSpace ( this is what i have tried.. but i'm sure we can do really better.. )
package com.example.consumingrest;
import java.util.List;
public class GenerateNewJsonNameSpace {
public static String createJsonContent(List<Item> ListOfNameSpace) {
if(ListOfNameSpace.isEmpty()) {
return null;
}else {
String LeJson;
LeJson = "{";
for(int i = 0; i < ListOfNameSpace.size(); i++) {
LeJson.concat(ListOfNameSpace.get(i).getMetadata().getName());
LeJson.concat(", \n");
}
LeJson.concat("}");
return LeJson;
}
}
}
you can use a library named Gson, which is created by google specifically for handling the JSON data.
All you need to do is create a new Gson object and parse the JSON with it.
You can do in just couple of lines
String jsonString = "{ \"kind\": \"Space\", \"apiVersion\": \"v1\", \"metadata\": { \"selfLink\": \"something\", \"resourceVersion\": \"something\" }, \"items\": [ { \"metadata\": { \"name\": \"projet1\" } }, { \"metadata\": { \"name\": \"affeccom-cicd\" } } ] }";
JsonObject data = new Gson().fromJson(jsonString, JsonObject.class);
JsonArray names = data .get("items").getAsJsonArray();
for(JsonElement element : names){
JsonObject object = element.getAsJsonObject();
System.out.println(object.get("metadata").getAsJsonObject().get("name").getAsString());
}

Polymorphic deserialization in jackson sets value null for specific fields

Problem statement
Is that the JSON which is to be deserialize into the below given POJO's
is setting value of credentialType as null when i send the below JSON through postman
{
"credential": [
{
"#type": "mobile",
"credentialName": "cred-2",
"email": "s#s.com"
},
{
"#type": "card",
"credentialNumber": "1"
}
]
}
Expected outcome
What i want to achieve is that with the above JSON the credential type should be set as either MOBILE for MobileCredentialDto or CARD for CardCredentialDto
#Getter
public class SecureDto {
private List<CredentialDto> credential;
#JsonCreator
public HandoutDto(#JsonProperty("credential") final List<CredentialDto> credential) {
this.credential = Collections.unmodifiableList(credential);
}
}
#Getter
public class SecureDto {
private List<CredentialDto> credential;
#JsonCreator
public HandoutDto(#JsonProperty("credential") final List<CredentialDto> credential) {
this.credential = Collections.unmodifiableList(credential);
}
}
#JsonIgnoreProperties(ignoreUnknown = true)
#JsonTypeInfo(use = JsonTypeInfo.Id.NAME)
#JsonSubTypes({
#JsonSubTypes.Type(value = CardCredentialDto.class, name = "card"),
#JsonSubTypes.Type(value = MobileCredentialDto.class, name = "mobile"),
})
#Getter
#Setter
public class CredentialDto {
private CredentialType credentialType;
#JsonCreator
public CredentialDto(#JsonProperty("credentialType") final String credentialType) {
this.credentialType = CredentialType.valueOf(credentialType);
}
public CredentialDto() {
}
public void setCredentialType(final CredentialType credentialType) {
this.credentialType = CredentialType.MOBILE;
}
}
#Getter
#Setter
public class MobileCredentialDto extends CredentialDto {
private String credentialName;
private String email;
public MobileCredentialDto(final String credentialId,
final String state,
final String credentialNumber,
final String credentialName,
final String email) {
super(credentialId, state, credentialNumber, CredentialType.MOBILE.name());
this.credentialName = credentialName;
this.email = email;
}
public MobileCredentialDto() {
}
public String getCredentialName() {
return credentialName;
}
public String getEmail() {
return email;
}
}
#Getter
#Setter
public class CardCredentialDto extends CredentialDto {
public CardCredentialDto(final String credentialId,
final String state,
final String credentialNumber) {
super(credentialId, state, credentialNumber,CredentialType.CARD.name());
}
public CardCredentialDto() {
}
}
public enum CredentialType {
MOBILE("MOBILE"),
CARD("CARD");
private final String name;
CredentialType(final String name) {
this.name = name;
}
}
I Found the answer.
what i did was set the visible = true in JsonTypeInfo.
In short by setting the visible = true allowed the jackson to do the following
Note on visibility of type identifier: by default, deserialization (use during reading of JSON) of type identifier is completely handled by Jackson, and is not passed to deserializers. However, if so desired, it is possible to define property visible = true in which case property will be passed as-is to deserializers (and set via setter or field) on deserialization.
Refer the doc here for more understanding.
https://fasterxml.github.io/jackson-annotations/javadoc/2.4/com/fasterxml/jackson/annotation/JsonTypeInfo.html
Below is the code
#JsonTypeInfo(use = JsonTypeInfo.Id.NAME ,
visible = true,
property = "credentialType")
#JsonSubTypes({
#JsonSubTypes.Type(value = CardCredentialDto.class, name = "card"),
#JsonSubTypes.Type(value = MobileCredentialDto.class, name = "mobile"),
})
#Getter
#Setter
public class CredentialDto {
#JsonProperty(value = "credentialType")
private CredentialType credentialType;
#JsonCreator
public CredentialDto(#JsonProperty("credentialType") final String credentialType) {
this.credentialType = CredentialType.valueOf(credentialType);
}
public CredentialDto() {
}
public void setCredentialType(final CredentialType credentialType) {
this.credentialType = CredentialType.MOBILE;
}
}
and the json will look like this
{
"credential": [
{
"credentialType": "mobile",
"credentialName": "cred-2",
"email": "s#s.com"
},
{
"credentialType": "card",
"credentialNumber": "1"
}
]
}

Json - Java Object to Json

I am very new to Json and my goal to create the Json output below from Java bean. How should I structure my Java object? Should I have MyResult class and User and Result as subclasses? What Json library can I use for this?
“MyResult” {
“AccountID”: “12345”,
"User" {
"Name": "blah blah",
"Email": “blah#blah.com”,
},
"Result" {
"Course": “blah”,
"Score": “10.0”
}
}
Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB (JSR-222) expert group.
How should I structure my Java object?
Below is what your object model could look like. MOXy's JSON binding leverages JAXB annotations for mapping the domain model to JSON, so I have included those as well. JAXB implementations have default rules for mapping field/property names, but since your document differs from the default each field had to be annotated.
MyResult
package forum11001458;
import javax.xml.bind.annotation.*;
#XmlRootElement(name="MyResult")
public class MyResult {
#XmlElement(name="AccountID")
private String accountID;
#XmlElement(name="User")
private User user;
#XmlElement(name="Result")
private Result result;
}
User
package forum11001458;
import javax.xml.bind.annotation.XmlElement;
public class User {
#XmlElement(name="Name")
private String name;
#XmlElement(name="Email")
private String email;
}
Result
package forum11001458;
import javax.xml.bind.annotation.XmlElement;
public class Result {
#XmlElement(name="Course")
private String course;
#XmlElement(name="Score")
private String score;
}
What Json library can I use for this?
Below is how you can use MOXy to do the JSON binding:
jaxb.properties
To use MOXy as your JAXB provider you need to include a file called jaxb.properties with the following entry in the same package as your domain model:
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
Demo
Note how MOXy's JSON binding does not require any compile time dependencies. All the necessary APIs are available in Java SE 6. You can add the necessary supporting APIs if you are using Java SE 5.
package forum11001458;
import java.io.File;
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(MyResult.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
unmarshaller.setProperty("eclipselink.media-type", "application/json");
File json = new File("src/forum11001458/input.json");
Object myResult = unmarshaller.unmarshal(json);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty("eclipselink.media-type", "application/json");
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(myResult, System.out);
}
}
input.json/Output
{
"MyResult" : {
"AccountID" : "12345",
"User" : {
"Name" : "blah blah",
"Email" : "blah#blah.com"
},
"Result" : {
"Course" : "blah",
"Score" : "10.0"
}
}
}
Googles GSON is a really nice json lib. This is from the previous link and it basically outlines some of its functionality.
jackson is also pretty fast and easy to use
Although closed, this SO post can help you understand the differences between Jackson and GSON. Which one is "best" depends on what is important for you.
EDIT: Specifically for Jackson, your example looks a lot like the example they give for what they call Full Data Binding, you can read it here. Btw, although the announced 5 minutes needed to read that document is maybe a bit short, it gives a complete overview of the different ways Jackson can be used. You'll also notice that the examples given do not use annotations.
Or GSON
Super easy (no getters/settres, no annotations or configurations needed).
class BagOfPrimitives {
private int value1 = 1;
private String value2 = "abc";
private transient int value3 = 3;
}
BagOfPrimitives obj = new BagOfPrimitives();
Gson gson = new Gson();
String json = gson.toJson(obj);
==> json is {"value1":1,"value2":"abc"}
What Json library can I use for this? Jackson Library is used to serialize Java objects into JSON and deserialize JSON string into Java objects. Add the following dependencies to pom.xml.
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.4</version>
</dependency>
This dependency will transitively add the following libraries to the classpath:
jackson-annotations-2.9.4.jar
jackson-core-2.9.4.jar
jackson-databind-2.9.4.jar
**Note: Please always go with the latest jars.
How should I structure my Java object? Please see the full working code.
**MainClass.java:**
import java.io.IOException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
public class MainClass {
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
Result result = new Result();
result.setCourse("blah");
result.setScore("10.0");
User user = new User();
user.setName("blah blah");
user.setEmail("blah#blah.com");
MyResult myResult = new MyResult();
myResult.setAccountID("12345");
myResult.setResult(result);
myResult.setUser(user);
MyPojo myPojo = new MyPojo();
myPojo.setMyResult(myResult);
String jsonStr = mapper.writeValueAsString(myPojo);
System.out.println(jsonStr);
} }
**MyPojo.java:-**
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
#JsonPropertyOrder({ "AccountID", "User", "Result" })
public class MyPojo {
private MyResult MyResult;
public MyResult getMyResult() {
return MyResult;
}
#JsonProperty("MyResult")
public void setMyResult(MyResult MyResult) {
this.MyResult = MyResult;
} }
**MyResult.java:**
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
#JsonPropertyOrder({ "AccountID", "User", "Result" })
public class MyResult {
private User User;
private Result Result;
private String AccountID;
public User getUser() {
return User;
}
#JsonProperty("User")
public void setUser(User User) {
this.User = User;
}
public Result getResult() {
return Result;
}
#JsonProperty("Result")
public void setResult(Result Result) {
this.Result = Result;
}
public String getAccountID() {
return AccountID;
}
#JsonProperty("AccountID")
public void setAccountID(String AccountID) {
this.AccountID = AccountID;
} }
**Result.java:**
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
#JsonPropertyOrder({ "Course", "Score" })
public class Result {
private String Course;
private String Score;
public String getCourse() {
return Course;
}
#JsonProperty("Course")
public void setCourse(String Course) {
this.Course = Course;
}
public String getScore() {
return Score;
}
#JsonProperty("Score")
public void setScore(String Score) {
this.Score = Score;
} }
**User.java:**
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
#JsonPropertyOrder({ "Name", "Email" })
public class User {
private String Name;
private String Email;
public String getName() {
return Name;
}
#JsonProperty("Name")
public void setName(String Name) {
this.Name = Name;
}
public String getEmail() {
return Email;
}
#JsonProperty("Email")
public void setEmail(String Email) {
this.Email = Email;
}
#Override
public String toString() {
return "ClassPojo [Name = " + Name + ", Email = " + Email + "]";
} }
**Result:**
{
"MyResult" : {
"AccountID" : "12345",
"User" : {
"Name" : "blah blah",
"Email" : "blah#blah.com"
},
"Result" : {
"Course" : "blah",
"Score" : "10.0"
}
}
}
Note: Please note the use of Json Annotations like #JsonProperty("Email") to make json property names as same in the expected output & #JsonPropertyOrder({ "Name", "Email" } to maintain the sequence as in expected output. Refer: https://www.baeldung.com/jackson-annotations.

Categories