I have a pretty standard use-case here:
{
"title": "my awesome title",
"description": "all the awesome things",
"theThings": [
{
"thing": "coolThing1",
"association-type": "thing"
},
{
"thing": "coolThing2",
"association-type": "thing"
}
]
}
I'm utilizing the following class structure to use with GSON:
package things;
import java.io.Serializable;
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class ThingsPOJO implements Serializable
{
#SerializedName("title")
#Expose
public String title = "";
#SerializedName("description")
#Expose
public String description = "";
#SerializedName("theThings")
#Expose
public List<TheThing> theThings = null;
private class TheThing implements Serializable
{
#SerializedName("thing")
#Expose
public String thing = "";
#SerializedName("association-type")
#Expose
public String associationType = "";
}
}
title and description are good to go, but the collection of objects is null. I'm testing using that example payload from above. I'm using the fromJson call provided by GSON.
Related
I want to generate Java Classes using a given JSON schema
Using the WikiMedia API, I receive the page info from a search
JSON schema:
(The small part that gives me problems)
"pages": {
"352214": {
"pageid": 352214,
"ns": 0,
"title": "Montellano",
"extract": "Montellano es un municipio español..."
}
}
As you can see the field 352214 is unique to this search which gives a problem using the POJO.
I'm using jsonschema2pojo with Jackson2 as Annotation Style
POJO
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonPropertyOrder({
"pageid",
"ns",
"title",
"extract"
})
public class _352214 {
#JsonProperty("pageid")
private Integer pageid;
#JsonProperty("ns")
private Integer ns;
#JsonProperty("title")
private String title;
#JsonProperty("extract")
private String extract;
#JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
#JsonProperty("pageid")
public Integer getPageid() {
return pageid;
}
#JsonProperty("pageid")
public void setPageid(Integer pageid) {
this.pageid = pageid;
}
#JsonProperty("ns")
public Integer getNs() {
return ns;
}
#JsonProperty("ns")
public void setNs(Integer ns) {
this.ns = ns;
}
#JsonProperty("title")
public String getTitle() {
return title;
}
#JsonProperty("title")
public void setTitle(String title) {
this.title = title;
}
#JsonProperty("extract")
public String getExtract() {
return extract;
}
#JsonProperty("extract")
public void setExtract(String extract) {
this.extract = extract;
}
#JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
#JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
}
_352214 class will suit only for the wiki search with the same field name, whenever I make another search and this field changes, it crashes. How do I solve this?
There is no standard way to parse situations like this(situations when you don't know field name). As an option you can manually parse your file using Jackson:
public void parseWikiResponse(String wikiResponse) {
JsonFactory jsonFactory = new JsonFactory();
ObjectMapper mapper = new ObjectMapper(jsonFactory);
JsonNode jsonNodes = mapper.readTree(wikiResponse);
Iterator<Map.Entry<String,JsonNode>> fieldsIterator = jsonNodes.fields();
while (fieldsIterator.hasNext()) {
Map.Entry<String,JsonNode> field = fieldsIterator.next();
/* Here you can find your field with unknown name using regExp eg */
field.getKey();
}
}
If you want only for parsing this approach should solve the problem.
There is a similar question on this topic:
Parsing JSON in Java without knowing JSON format
Hope something helped (:
I try to deserialize Jira issues from the REST API into an object. Thats quite straight forward. Where I struggle is mapping a custom field in Jira onto a property. I've tried using a custom deserializer but it does not "kick in".
This is how the Json from the REST call looks like:
(some parts stripped)
{
"expand": "renderedFields,names,schema,...",
"id": "53899",
"key": "DPT-12",
"fields": {
"issuetype": {
"id": "10001",
"name": "Story",
"subtask": false
},
"timespent": null,
"project": {
"id": "10823",
"key": "DPT"
},
"fixVersions": [],
"customfield_10111": null,
"aggregatetimespent": null,
"resolution": null,
"customfield_10112": null,
"customfield_10700": [
"entwicklung-w"
],
"customfield_10304": null,
"resolutiondate": null,
"lastViewed": "2017-04-04T14:34:19.868+0200",
"created": "2017-02-02T12:01:31.443+0100",
"priority": {
"name": "Schwer",
"id": "10001"
},
"assignee": {
"displayName": "me :-)"
},
"updated": "2017-04-04T14:34:19.710+0200",
"status": {
"iconUrl": "https://jira.mobi.ch/",
"name": "Backlog",
"statusCategory": {
"name": "Aufgaben"
}
},
"summary": "Ereignisse in rocket Chat schreiben",
"creator": {
"displayName": "me :-)"
},
"reporter": {
"displayName": "me :-)"
}
}
}
The custom field name is configured in my application ("customfield_10700") and I want to map it on the property:
private Set<String> deploymentEnvironments;
So here are the relevant Dto's and the test class (getters and setter stripped here).
Test:
import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
import static org.hamcrest.collection.IsEmptyCollection.empty;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsNot.not;
import static org.hamcrest.core.IsNull.nullValue;
import static org.junit.Assert.assertThat;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Set;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.junit.Test;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
public class IssueFieldsWithDeserializerTest {
#Test
public void testJiraResponseDeserializer() throws IOException, URISyntaxException {
// arrange
String deploymentEnvsKey = "customfield_10700";
String json = new String(Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("jira-example-issue-with-customfield-poc.json").toURI())));
ObjectMapper mapper = new ObjectMapper();
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
SimpleModule module = new SimpleModule();
module.addDeserializer(Set.class, new CustomFieldDeserializer(deploymentEnvsKey));
mapper.registerModule(module);
// act
IssueResponsePoc issue = mapper.readValue(json, IssueResponsePoc.class);
// assert
assertThat("issue is not null", issue, is(not(nullValue())));
assertThat("fields are not null", issue.getFields(), is(not(nullValue())));
assertThat("custom field is not null", issue.getFields().getDeploymentEnvironments(), is(not(nullValue())));
assertThat("custom field is not empty", issue.getFields().getDeploymentEnvironments(), is(not(empty())));
assertThat("custom field has one value", issue.getFields().getDeploymentEnvironments(), hasSize(1));
}
}
IssueResponsePoc class:
import java.io.Serializable;
import com.fasterxml.jackson.annotation.JsonProperty;
public class IssueResponsePoc implements Serializable {
#JsonProperty private String id;
#JsonProperty private String key;
#JsonProperty private IssueFieldsPoc fields;
}
Interesting class: IssueFieldsPoc
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.Set;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.annotation.JsonProperty;
public class IssueFieldsPoc implements Serializable {
#JsonProperty private String summary;
#JsonProperty private IssueType issuetype;
#JsonProperty private IssueUser creator;
#JsonProperty private Date created;
#JsonProperty private IssueUser reporter;
#JsonProperty private IssuePriority priority;
#JsonProperty private IssueResolution resolution;
#JsonProperty private List<String> labels;
#JsonProperty private Date resolutiondate;
#JsonProperty private IssueUser assignee;
#JsonProperty private Date updated;
#JsonProperty private IssueStatus status;
#JsonDeserialize private Set<String> deploymentEnvironments;
// #JsonDeserialize(using = CustomFieldDeserializer.class) private Set<String> deploymentEnvironments;
public Set<String> getDeploymentEnvironments() {
return deploymentEnvironments;
}
public void setDeploymentEnvironments(Set<String> deploymentEnvironments) {
this.deploymentEnvironments = deploymentEnvironments;
}
}
My deserializer:
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
public class CustomFieldDeserializer extends StdDeserializer<Set<String>> {
private final String customFieldName;
public CustomFieldDeserializer(String customFieldName) {
super((Class<?>) null);
this.customFieldName = customFieldName;
}
#Override
public Set<String> deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
System.out.println("deserializer started!");
return null;
}
#Override
public Collection<Object> getKnownPropertyNames() {
return Collections.singletonList(customFieldName);
}
}
I tried registering a custom deserializer but it does not start, I suspect its ignored because jackson cannot identify the field name. Adding the "getKnownPropertyNames" method did not help. Since I need to put the jira custom field name (I read it from a configuration) somewhere I tried to put it into the deserializer. Using the jackson annotation #JsonDeserialize.
I also tried wrapping it into another class and not using Set directly to have a stronger typing. No luck either.
I also tried configuring the deserializer within the annotation but that requires a default constructor and I can no longer configure the jira custom field name.
The current solution uses the #JsonAnySetter annotation:
#JsonAnySetter
public void setCustomProperty(String name, Object value) {
if(StringUtils.startsWith(name, "customfield_")) {
this.customFields.put(name, value);
}
}
But I would prefer having that logic within the deserializer.
Is there a way to help jackson when to start the deserializer (since it knows the property name) for this dynamic property name?
Update:
Registered the module to the mapper.
As suggested in the answers adding the exact property name to the field:
#JsonProperty("customfield_10700")
#JsonDeserialize
private Set<String> deploymentEnvironments;
will allow the deserializer to start. But as mentioned above that is a configurable value I cannot put (or I dont want to) directly in the mapping code.
I think your issue can be resolved by setting #JsonProperty("customfield_10700") to the field deploymentEnvironments as shown below. You don't need a custom deserializer in this case.
public class IssueFieldsPoc implements Serializable {
#JsonProperty private String summary;
#JsonProperty private Date created;
#JsonProperty private List<String> labels;
#JsonProperty private Date resolutiondate;
#JsonProperty private Date updated;
#JsonProperty("customfield_10700")
private Set<String> deploymentEnvironments;
Well, if I understand right, you need to transform json to java object.
If you want that class ignore unknown properties you need add #JsonIgnoreProperties(ignoreUnknown = true) to your classes which must ignore (IssueResponsePoc only or IssueFieldsPoc too).
In #JsonProperty(value = <name_of_property_in_json>) will allow you to use any name for your field in java class.
If you repeat nested levels of json by java classes with corresponding annotations (#JsonProperty, #JsonIgnore and so on) you don't need to use deserializer an whole.
And if you want to process unknown fields in your classes, you can use #JsonAnySetter for this purposes
i have a String returned by a service, in this JSON format:
String message = {
"Tickets":
[{
"Type": "type1",
"Author": "author1",
"Rows":
[
{
"Price": "100.0",
"Date": "24/06/2016",
"Amount": "10"
},
{
"Type": "Comment",
"Value": "some comment goes here"
}
],
"ID": "165"
}],
"Desk": "desk1",
"User": "user1"
}
I need to parse it and convert into a Java object.
I tried to create a dom like this:
public class TicketWrapper{
private Ticket ticket;
private String desk;
private String user;
}
public class Ticket {
private String type;
private String author;
private List<Row> rows;
private String id;
}
public class Row1{
private float price;
private Date date;
private int amount;
}
public class Row2{
private String type;
private float value;
}
Then I try to parse it with Google Gson, this way:
TicketWrapper ticket = gson.fromJson(message, TicketWrapper.class)
but if I print it System.out.println(gson.toJson(ticket)), it prints:
{"desk" : 0, "user" : 0}
I don't know how to parse that Json into a Java Object, and how to tell him that a row into "Rows" can be of the Row1 type or Row2 type.
I think there is a few issues, such names of properties in lower case and dateformat and mix types of rows. I just changed like this and worked for me:
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.annotations.SerializedName;
import org.junit.Test;
import java.util.Date;
import java.util.List;
public class CheckTest {
#Test
public void thisTest() {
Gson gson = new GsonBuilder()
.setDateFormat("dd-MM-yyyy")
.setPrettyPrinting()
.create();
String message = "{\"Tickets\":" +
"[{\"Type\":\"type1\"," +
"\"Author\":\"author1\"," +
"\"Rows\":[{\"Price\":\"100.0\"," +
"\"Date\":\"24-06-2016\"," +
"\"Amount\":\"10\"}," +
"{\"Type\":\"Comment\"," +
"\"Value\":\"some comment goes here\"}]," +
"\"ID\":\"165\"}]," +
"\"Desk\":\"desk1\"," +
"\"User\":\"user1\"}";
TicketWrapper ticket = gson.fromJson(message, TicketWrapper.class);
System.out.println(ticket.toString());
}
public class TicketWrapper {
#SerializedName("Tickets")
private List<Ticket> tickets;
#SerializedName("Desk")
private String desk;
#SerializedName("User")
private String user;
public TicketWrapper() {
}
}
public class Ticket {
#SerializedName("Type")
private String type;
#SerializedName("Author")
private String author;
#SerializedName("Rows")
private List<Row> rows;
#SerializedName("ID")
private String id;
public Ticket() {
}
}
public class Row {
#SerializedName("Type")
private String type;
#SerializedName("Value")
private String value;
#SerializedName("Price")
private float price;
#SerializedName("Date")
private Date date;
#SerializedName("Amount")
private int amount;
public Row() {
}
}
}
As others have already mentioned in the comment, you need to make sure the mapping directly reflects the file names. It needs to be 'User' and 'Desk' instead of 'user' and 'desk'. Also, you have a list of tickets, which would map to List Tickets.
I have the following JSON which I'm trying to deserialize using the Jackson API
"attachments": {
"file1": {
"content": "",
"name": "sample.json",
"type": "application/json"
},
"file2": {
"content": ""
"name": "myspreadsheet.xlsx",
"type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
}
},
I basically need an Attachment class which has a list of AttachmentFile objects which would look like this:
public static AttachmentFile {
String content;
String name;
String type;
}
How can I achieve this using a custom deserializer?
Thanks!
I use jackson 1.9.12 and there are no problems serialize and deserialize HashMap.
Attachments:
import java.util.Map;
public class Attachments
{
//#JsonDeserialize(as=HashMap.class) // use this if you want a HashMap
public Map<String, AttachmentFile> attachments;
public Attachments() {
}
public Attachments(
final Map<String, AttachmentFile> attachments
) {
this.attachments = attachments;
}
}
AttachmentFile:
public class AttachmentFile
{
public String content;
public String name;
public String type;
public AttachmentFile() {
}
public AttachmentFile(
final String content,
final String name,
final String type
) {
this.content = content;
this.name = name;
this.type = type;
}
}
Test:
import java.util.HashMap;
import java.util.Map;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;
import org.junit.Assert;
import org.junit.Test;
public class AttachmentsTest
{
#Test
public void test()
{
try {
final Map<String, AttachmentFile> attachments = new HashMap<String, AttachmentFile>();
attachments.put(
"file1",
new AttachmentFile(
"",
"sample.json",
"application/json"
)
);
attachments.put(
"file2",
new AttachmentFile(
"",
"myspreadsheet.xlsx",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
)
);
final Attachments inputData = new Attachments();
inputData.attachments = attachments;
final ObjectMapper jsonMapper = new ObjectMapper();
jsonMapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, true);
final String jsonString = jsonMapper.writeValueAsString(inputData);
//System.out.println(jsonString);
final Attachments outputData = jsonMapper.readValue(jsonString, inputData.getClass());
Assert.assertNotNull(outputData);
Assert.assertEquals(inputData.attachments.size(), outputData.attachments.size());
Assert.assertEquals(inputData.attachments.get("file1").name, outputData.attachments.get("file1").name);
Assert.assertEquals(inputData.attachments.get("file2").name, outputData.attachments.get("file2").name);
} catch (final Exception e) {
Assert.fail(e.getMessage());
}
}
}
You do not need a custom deserializer.
Using jacksons #JsonAnySetter annotation, you can write a method in your attachment class that looks like this
class Attachment
{
ArrayList files = new ArrayList();
#JsonAnySetter
public void setFile(String name, Object value)
{
files.add(value);
}
}
You may have to tweak that code (using more annotations), to make sure that value is deserialized as AttachmentFile. But I think you get the basic idea.
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.