JSON assign Java String - java

My json structure is
{
"GAME_CUSTOMIZE": {
"GAME_CODE": "MOCK12V2.0",
"RESULT": {
"response": [
{
"id": "PLAYER1",
"value": "WERYT"
},
{
"id": "PLAYER2",
"value": "QEWRET"
},
{
"id": "PLYAER3",
"value": "765422"
}
]
}
}
}'
My Pojo object using for mapping is,
import com.fasterxml.jackson.annotation.JsonProperty;
#JsonProperty("GAME_CODE")
private String gameCode;
#JsonProperty("RESULT")
private String responseJson;
When trying to assign the "RESULT" complete json to string, getting empty after conversion from json to Java object. Have tried JsonRawValue annotation also. And tried with responseJson as Object type instead of string. I want to get the RESULT Json to Java string or Object property.

The default mapping for a JSON object is a LinkedHashMap<String, Object>. The simple solution would be to change the type of responseJson to that.
Mapping to a String (containing the original JSON serialization of the object) might make sense, but I don't know if it is implementable. Mapping to java.lang.Object makes no sense.
UPDATE - the following Q&A explains how to deserialize an object as a string:
Jackson Deserialize Variable as Json String

Related

Java Jackson deserialize to object from multiple json formats

Let's assume there are those 2 different json structures - both contain the same values, but the key hierarchy differs - one is flat, the other is nested:
Flat:
{
"documentId": "7ef1229c-301a-40d9-8c0c-faf5da54785d",
"first_name": "Xbyvuve",
"last_name": "Abmhlakwd"
}
Nested:
{
"_meta": {
"_more_nested" {
"documentId": "7ef1229c-301a-40d9-8c0c-faf5da54785d",
}
},
"first_name": "Xbyvuve",
"last_name": "Abmhlakwd"
}
Resulting in Object:
#JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class PersonDocument {
String documentId;
String firstName;
String lastName;
}
Is there a way in Jackson to instantiate the same object from both json strings without providing a custom deserializer? For instance with a special annotation? In addition, I also want the resulting json string on serialization to be like the "flat" json string.
Thank you in advance!
Tried different annotations without any positive result :<

Java Jackson Json Array Serialization

I have a special case that I have been trying to serialize with Jackson. Here is a sample.
{
"key1": [
[
10,
11
],
[
12,
13
]
],
"key2": [
[
14,
15
],
[
16,
17
]
]
}
How can I make a model with decorators that will serialize this payload?
EDIT:
Assume there is a JSON file with the above contents. How can I make a POJO that can be used to serialize the above JSON like so with Jackson:
MyPOJO pojo = objectMapper.readValue(new File("above_json.json"), MyPOJO.class);
Here is a very simple example of what I am looking for:
JSON Input:
"Parameter":{
"Name":"Parameter-Name",
"Value":"Parameter-Value"
}
POJO to serialize above simple JSON:
public class Parameter {
#JsonProperty("Name")
public String name;
#JsonProperty("Value")
public String value;
}
I am looking for a class, just like Parameter above that will serialize the example JSON that I provided originally above, rather than the simplified JSON.
Assume there is a JSON file with the above contents. How can I make a POJO that can be used to serialize the above JSON like so with Jackson
This is very simple, you need to understand the data of your JSON. You have key-value and each value is Array of another Array. That is similar to
class POJO
{
List<List<Integer>> key1;
List<List<Integer>> key2;
}

Parsing JSON String Array of Arrays in Spring

I am trying to parse json string in spring using pojo classes. I've a json string as:
{
"values": [
[
1509836400000,
670042.375,
2
],
[
1509836400000,
670042.375,
2
]
]
}
Can somebody help me how do I parse this string to object of the form
class Value{
long timeStamp;
double value;
int flag;
// getters and setters
}
class Values{
Value[] values;
// getters and setters
}
use Gson library to parse Json to Java like this.
Gson gson = new Gson();
Values values = gson.fromJson(yourJsonString , Values.class);
you can convert Json to Java POJOs using this tool Json to Java
You can use jackson 2
Reference
you can use the jackson library which is able of converting the string object to the desired pojo class
so please check this example
https://www.mkyong.com/java/how-to-convert-java-object-to-from-json-jackson/
If you are able the change the json to meet your model/pojo
just convert it from array to object like this Json:
{
"values": [ {
"timeStamp" : 1509836400000,
"value" : 670042.375,
"flag" : 2
},
{
"timeStamp" : 1509836400000,
"value" : 670042.375,
"flag" : 2
} ]
}
If you aren't able to change the json, you can map the values as List<List<Double>>, and then get every one by index: 0 for timeStamp and so on. Your model/pojo should be:
class Values {
List<List<Double>> values;
// getters and setters
}

Gson Deserialization json which contains parameter that can be string or object

I have a Json like below.
{
"myItemArray": [
{
"id": "c8c1",
"price": 18,
"display": {
"inneritemName1": "innerItemValue1",
"inneritemName2": "innerItemValue2",
"inneritemName3": "innerItemValue3"
}
},
{
"id": "cac1",
"price": 2,
"display": "Lemonate"
}
]
}
As you can see that the item in my array has a parameter called "display" which can be String or Object. How can I deserialize this json using Gson?
I don't want to deserialize this string manually is there any other way to to this?
You can use Gson, but have to build a class, get each Json attribute into the relevent attribute in the Java class.
I highly recomand Jackson library, you only need to setup the Java class, and it takes care of the mapping and parsing.

Configure XStream to dynamically map to different objects

I am hitting a RESTful 3rd party API that always sends JSON in the following format:
{
"response": {
...
}
}
Where ... is the response object that needs to be mapped back to a Java POJO. For instance, sometimes the JSON will contain data that should be mapped back to a Fruit POJO:
{
"response": {
"type": "orange",
"shape": "round"
}
}
...and sometimes the JSON will contain data that should be mapped back to an Employee POJO:
{
"response": {
"name": "John Smith",
"employee_ID": "12345",
"isSupervisor": "true",
"jobTitle": "Chief Burninator"
}
}
So depending on the RESTful API call, we need these two JSON results mapped back to one of the two:
public class Fruit {
private String type;
private String shape;
// Getters & setters for all properties
}
public class Employee {
private String name;
private Integer employeeId;
private Boolean isSupervisor;
private String jobTitle;
// Getters & setters for all properties
}
Unfortunately, I cannot change the fact that this 3rd party REST service always sends back a { "response": { ... } } JSON result. But I still need a way to configure a mapper to dynamically map such a response back to either a Fruit or an Employee.
First, I tried Jackson with limited success, but it wasn't as configurable as I wanted it to be. So now I am trying to use XStream with its JettisonMappedXmlDriver for mapping JSON back to POJOs. Here's the prototype code I have:
public static void main(String[] args) {
XStream xs = new XStream(new JettisonMappedXmlDriver());
xs.alias("response", Fruit.class);
xs.alias("response", Employee.class);
// When XStream sees "employee_ID" in the JSON, replace it with
// "employeeID" to match the field on the POJO.
xs.aliasField("employeeID", Employee.class, "employee_ID");
// Hits 3rd party RESTful API and returns the "*fruit version*" of the JSON.
String json = externalService.getFruit();
Fruit fruit = (Fruit)xs.fromXML(json);
}
Unfortunately when I run this I get an exception, because I have xs.alias("response", ...) mapping response to 2 different Java objects:
Caused by: com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$UnknownFieldException: No such field me.myorg.myapp.domain.Employee.type
---- Debugging information ----
field : type
class : me.myorg.myapp.domain.Employee
required-type : me.myorg.myapp.domain.Employee
converter-type : com.thoughtworks.xstream.converters.reflection.ReflectionConverter
path : /response/type
line number : -1
version : null
-------------------------------
So I ask: what can I do to circumvent the fact that the API will always send back the same "wrapper" response JSON object? The only thing I can think of is first doing a String-replace like so:
String json = externalService.getFruit();
json = json.replaceAll("response", "fruit");
...
But this seems like an ugly hack. Does XStream (or another mapping framework) provide anything that would help me out in this particular case? Thansk in advance.
There are two ways with Jackson:
test manually that the wanted keys are there (JsonNode has the necessary methods);
use JSON Schema; there is one API in Java: json-schema-validator (yes, that is mine), which uses Jackson.
Write a schema matching your first object type:
{
"type": "object",
"properties": {
"type": {
"type": "string",
"required": true
},
"shape": {
"type": "string",
"required": true
}
},
"additionalProperties": false
}
Load this as a schema, validate your input against it: if it validates, you know you need to deserialize against your fruit class. Otherwise, make the schema for the second item type, validate against it as a security measure, and deserialize using the other class.
There are code examples for the API, too (version 1.4.x)
If you do know the actual type, it should be relatively straight-forward with Jackson.
You need to use a generic wrapper type like:
public class Wrapper<T> {
public T response;
}
and then the only trick is to construct type object to let Jackson know what T there is.
If it is statically available, you just do:
Wrapper<Fruit> wrapped = mapper.readValue(input, new TypeReference<Wrapper<Fruit>>() { });
Fruit fruit = wrapped.response;
but if it is more dynamically generated, something like:
Class<?> rawType = ... ; // determined using whatever logic is needed
JavaType actualType = mapper.getTypeFactory().constructGenericType(Wrapper.class, rawType);
Wrapper<?> wrapper = mapper.readValue(input, actualType);
Object value = wrapper.response;
but either way it "should just work". Note that in latter case you may be able to use base types ("? extends MyBaseType"), but in general dynamic type can't be specified.

Categories

Resources