change field name to lowercase while deserializing POJO to JSON using GSON? - java

I have a POJO class like this. I am deserializing my JSON to below POJO first..
public class Segment implements Serializable {
#SerializedName("Segment_ID")
#Expose
private String segmentID;
#SerializedName("Status")
#Expose
private String status;
#SerializedName("DateTime")
#Expose
private String dateTime;
private final static long serialVersionUID = -1607283459113364249L;
...
...
...
// constructors
// setters
// getters
// toString method
}
Now I am serializing my POJO to a JSON like this using Gson and it works fine:
Gson gson = new GsonBuilder().create();
String json = gson.toJson(user.getSegments());
System.out.println(json);
I get my json printed like this which is good:
[{"Segment_ID":"543211","Status":"1","DateTime":"TueDec2618:47:09UTC2017"},{"Segment_ID":"9998877","Status":"1","DateTime":"TueDec2618:47:09UTC2017"},{"Segment_ID":"121332121","Status":"1","DateTime":"TueDec2618:47:09UTC2017"}]
Now is there any way I can convert "Segment_ID" to all lowercase while deserializing? I mean "Segment_ID" should be "segment_id" and "Status" should be "status". Is this possible to do using gson? So it should print like this instead.
[{"segment_id":"543211","status":"1","datetime":"TueDec2618:47:09UTC2017"},{"segment_id":"9998877","status":"1","datetime":"TueDec2618:47:09UTC2017"},{"segment_id":"121332121","status":"1","datetime":"TueDec2618:47:09UTC2017"}]
if I change the "SerializedName" then while deserializing my JSON to POJO, it doesn't work so not sure if there is any other way.

You need to provide alternative names for deserialisation process and primary (value property) for serialisation.
class Segment {
#SerializedName(value = "segment_id", alternate = {"Segment_ID"})
#Expose
private String segmentID;
#SerializedName(value = "status", alternate = {"Status"})
#Expose
private String status;
#SerializedName(value = "datetime", alternate = {"DateTime"})
#Expose
private String dateTime;
}
Now, you can deserialise fields: Segment_ID, DateTime, Status and still be able to serialise as desired.

Related

Why is gson changing my Base64 encodeing and how to prevent it

I have the following data
String text = "ZG9udCB0b3VjaCBtZQ==";
MqttMessageDTO data = new MqttMessageDTO("topic", text, "id", 1L);
String a = gson.toJson(data);
Where MqttMessageDTO looks like
public class MqttMessageDTO {
private String topic;
private String base64EncodedMessage;
private String externalVehicleIdentifier;
private Long timestamp;
}
(excluding getters and constructor)
This generates the following output:
{"topic":"topic","base64EncodedMessage":"ZG9udCB0b3VjaCBtZQ\u003d\u003d","externalVehicleIdentifier":"id","timestamp":1}
Where the base64EncodedMessage field has been changed and == has been replaced with \u003d\u003d.
Why is this happening and how can I prevent this from happening. I dont want gson to make any changes while serializing and deserializing the base64EncodedMessage field.
Gson version:
2.8.5

reading the value of an array of json and putting it into set through java

I am using Jackson library with java 11 so basically I am able to read the below JSON into a string format
{
"schemas":[
"urn:params:core:2.0:User",
"urn:params:core:3.0:User"
],
},
}
here below is the set in which I have to fill the values of schemas from above json
private Set<String> setschemas = null;
right now I am able to read the above json into a string named finaljson , now please advise how can I read the differnt value of schemas from above json string named finaljson and set it to set named setschemas
if (node.has("schemas")) {
// *** here I want to read the differernt value of schemas and set it to a set
// named setschemas
// *****
}
you can create the following classes that represent the json structure
class MyJsonObject {
private AppIdentity appIdentity;
private Set<String> schemas;
private String userName;
}
class AppIdentity {
private String clientId;
private String username;
}
than you can use
final MyJsonObject myJsonObject = new ObjectMapper().readValue(finaljson, MyJsonObject.class); to read the json to JAVA object
so it can manipulated like myJsonObject.schemas.size() > 0 and such...
there are a lot of examples in the internet
*keep in mind, this solution only works when the json structure and fields name are known in advanced
With your approach, this would be simplest one:
if(node.has("schemas")) {
JsonNode schemaNode = node.get("schemas");
Set<String> schemaSet = objectMapper.convertValue(schemaNode, Set.class);
System.out.println("schemaSet" + schemaSet);
}
There are various ways to deal with JSON one is described here
1) You can create a class of JSON structure as follows with help online JSON to POJO convertor (Note:: Add Setters and Getters with help of IDE)
class AppJson {
private Set<AppIdentity> appIdentity;
private Set<String> schemas;
private String userName;
private Manager ManagerObject;
private String division;
private String organization;
private String costCenter;
private String employeeNumber;
}
class AppIdentity {
private String clientId;
private String username;
}
class Manager {
private String value;
private String $ref;
private String displayName;
private String $Ref;
}
2) Use above for object conversion.
ObjectMapper objectMapper = new ObjectMapper();
String jsonString = "{\"appIdentity\":[{\"clientId\":\"9a41763c642\",\"username\":\"XXX\"}],\"schemas\":[\"urn:params:core:2.0:User\",\"urn:params:core:3.0:User\"],\"userName\":\"ajklmnop_699100\",\"manager\":{\"value\":\"string\",\"$ref\":\"sdkoirk\",\"displayName\":\"string\",\"$Ref\":\"sdkweoirk\"},\"division\":\"string\",\"organization\":\"string\",\"costCenter\":\"string\",\"employeeNumber\":\"string\"}\n"
+ "";
AppJson appJson = objectMapper.readValue(jsonString, AppJson.class);
System.out.println("json " + appJson.getSchemas());
Here you will get the schemas.

json serialization with a variable field as a string

I have a pojo that I am unmarshalling a REST response to. One of the fields ("variable value") is just a Json variable element (can be any form).
Is there a way to tell it to treat the field as a plain string for all cases instead of trying to deserialize to an object?
Here's a json obiect ("variable value" can be any form):
{"id":1, "variable value": {"name":"one", "age": 22, "data":{"key":"value"}}}
I would like to save this json as a class object using gson
public class SomeCommand {
private Long id;
private String data;
}
It sounds that you would like to parse the given JSON string to transform variable value into String object. You can achieve this by creating 2 classes - SomeCommandOriginal and SomeCommand as follows:
First, convert the JSON string to SomeCommandOriginal to map the value of variable value to JsonNode.
class SomeCommandOriginal {
private Long id;
#JsonProperty("variable value")
private JsonNode variableValue;
//general getters and setters
}
class SomeCommand {
private Long id;
private String data;
public SomeCommand(SomeCommandOriginal someCommandOriginal) {
super();
this.id = someCommandOriginal.id;
this.data = someCommandOriginal.variableValue.toString();
}
//general getters and setters
}
Second, initialize an instance of SomeCommand and pass someCommandOriginal as the argument of customized constructor:
ObjectMapper mapper = new ObjectMapper();
SomeCommandOriginal someCommandOriginal = mapper.readValue(jsonStr, SomeCommandOriginal.class);
SomeCommand someCommand = new SomeCommand(someCommandOriginal);
System.out.println(someCommand.getData());
Console output:
{"name":"one", "age": 22, "data":{"key":"value"}}
UPDATED
If you are using Gson, just modify the datatype of variableValue to be JsonObject and switch to #SerializedName annotation as follows:
class SomeCommandOriginal {
private Long id;
#SerializedName("variable value")
private JsonObject variableValue;
//general getters and setters
}
And then you can get the same result as well:
Gson gson = new Gson();
SomeCommandOriginal someCommandOriginal = gson.fromJson(jsonStr, SomeCommandOriginal.class);
SomeCommand someCommand = new SomeCommand(someCommandOriginal);
System.out.println(someCommand.getData());

Java object not populated from json request for inner class

Have searched in different sites but couldn't find correct answer, hence posting this request though it could possible duplicates.sorry for that.
I am sending the below json request to my back-end service and converting to java object for processing. I can see the request body passed to my service but when i convert from json to java object , values are not populating
{
"data":{
"username":"martin",
"customerId":1234567890,
"firstName":"john",
"lastName":"smith",
"password":"p#ssrr0rd##12",
"email":"john.smith#gmail.com",
"contactNumber":"0342323443",
"department":"sports",
"location":"texas",
"status":"unlocked",
"OrderConfigs":[
{
"vpnId":"N4234554R",
"serviceId":"connectNow",
"serviceType":"WRLIP",
"ipAddress":"10.101.10.3",
"fRoute":[
"10.255.253.0/30",
" 10.255.254.0/30"
],
"timeout":1800,
"mapId":"test_map"
}
]
}
}
My Parser class have something like,
JSONObject requestJSON = new JSONObject(requestBody).getJSONObject("data");
ObjectMapper mapper = new ObjectMapper();
final String jsonData = requestJSON.toString();
OrderDTO mappedObject= mapper.readValue(jsonData , OrderDTO .class);
// I can see value coming from front-end but not populating in the mappedObject
My OrderDTO.java
#JsonInclude(value = Include.NON_NULL)
#JsonIgnoreProperties(ignoreUnknown = true,value = {"hibernateLazyInitializer", "handler", "created"})
public class OrderDTO {
private String username;
private long customerId;
private String source;
private String firstName;
private String lastName;
private String email;
private String contactNumber;
private String password;
private String department;
private String location;
private String status;
private List<OrderConfig> OrderConfigs;
#JsonInclude(value = Include.NON_NULL)
public class OrderConfig {
private String vpnId;
private String serviceId;
private String serviceType;
private String ipAddress;
private String mapId;
private String[] fRoutes;
private Map<String, Object> attributes;
private SubConfig subConfig;
private String routeFlag;
getter/setters
.....
}
all setter/getter
}
Not sure what I'm missing here. Is this right way to do?
If your are trying to use inner class, correct way to use is to declare it static for Jackson to work with inner classes.
For reference check this
code changes made are
#JsonInclude(value = Include.NON_NULL)
#JsonIgnoreProperties(ignoreUnknown = true)
static class OrderConfig {
Make sure that your json tag names match with variable names of java object
Ex : "fRoute":[
"10.255.253.0/30",
" 10.255.254.0/30"
],
private String[] fRoutes;
OrderConfigs fields will not be initialized, just modify your bean as
#JsonProperty("OrderConfigs")
private List<OrderConfig> orderConfigs;
// setter and getter as setOrderConfigs / getOrderConfigs
See my answer here. (same issue)

Json not converting to object in spring integration

I'm having
.transform(Transformers.fromJson(SNSMessage.class))
not return a value transformed from my JSON. The JSON input is
{
"Type": "Notification",
"MessageId": "b5c64f3f-59e3-5fce-9ad6-1e98973c9537",
"TopicArn": "arn:aws:sns:us-east-1:194477963434:local-hera-update",
"Subject": "com.accuity.hera.model.HeraNotification",
"Message": "{\"id\":\"65e60559-cab5-4027-88a2-46185fbd50b9\",\"resourceType\":\"listItem\",\"action\":\"I\",\"timeOfAction\":\"2017-05-30T19:48:46Z\",\"source\":\"gwl\"}",
"Timestamp": "2017-05-30T19:48:47.593Z",
"SignatureVersion": "1",
"Signature": "Xz0qg0byLMA1fwIRbi7aWcEzhtcLBOmzyUluL1W5URu4WaiEO3G\/+hPSpsFXGxcSYNYRgpKhL9QAP2qLkuMlSEMqiEOHaSr88UaB8QRV2lUEjdBAWpuFYVBPdb+jpo6n3m89vVHoYfFWk8yBkc0zuoRl4OYcUXfTZiWWQkkrT8r9OzWU8LxQwgf0jgr1xEoqbl7uMHIp7nHp3cKstQ0mbK6yxMQ8faxfDm+IwH3k8BBH2\/CXmRg9WME6JK77jvagMUHNhUahWKIjm4iz+TCQCdnmHQR21hmgxlkhdrSxZ1FBbk6BjxfX7gorEwwfY1gYNoZCXxsN63+4vSiFMlOAAQ==",
"SigningCertURL": "https:\/\/sns.us-east-1.amazonaws.com\/SimpleNotificationService-b95095beb82e8f6a046b3aafc7f4149a.pem",
"UnsubscribeURL": "https:\/\/sns.us-east-1.amazonaws.com\/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-1:194477963434:local-hera-update:7de3da56-9e6c-43ca-9abc-d46fff379380"
}
and the class definition is:
public class SNSMessage {
private String Type;
private String MessageId;
private String TopicArn;
private String Subject;
private String Message;
private String Timestamp;
private String SignatureVersion;
private String Signature;
private String SigningCertURL;
private String UnsubscribeURL;
}
any ideas why the SNSMessage is coming back with all its fields set to null?
The problem you have is that your json attributes are using a different capitalization than your pojo properties.
It means you have Type as json attribute and type detected for your getter.
You need to use #JsonProperty annotation like this:
#JsonProperty("Type")
private String type;
...
// getters / setters for type
Btw, if you don't want to follow the java naming standard and have Type as well as the pojo property, then just add the #JsonProperty to the property with no args

Categories