GSON Convert Array of Different type - java

Consider the following JSON:
{"test":[["abc",12],["fgs",23],...]}
How can I map it to java object using GSON or spring RestTemplate?
I can't use List<> since it is of different type.
I tried Hashmap, Map all throws exception.
public class Json implements Serializable{
#Getter #Setter List<Map<String,Integer>> test;
}
...
Json json = new GSON().fromJson(response.getBody(),Json.class);
Thanks in advance.

Related

Jackson not properly mapping properties to POJO

Been trying to map a certain JSON string that I'm receiving from an REST API call, but so far I only got the following message.
Unrecognized field "my_first_field" (class MyClass), not marked as ignorable
I've been parsing the contents with IOUtils class, the following way (maybe the encoding is the root cause).
String json = IOUtils.toString(responseEntity.getContent(), UTF_8);
Once this has been done, I try to map the payload String to my POJO class using ObjectMapper.
new ObjectMapper().readValue(json, new TypeReference<MyClass>(){ })
However, while performing that step the exception mentioned in the beginning is prompt. The POJO class is the following.
public static class MyClass {
#JsonProperty("my_first_field")
private List<Map<String, String>> myFirstField;
#JsonProperty("my_second_field")
private String mySecondField;
public MyClass() { }
public MyClass(List<Map<String, String>> myFirstField, String mySecondField) {
this.myFirstField = myFirstField;
this.mySecondField = mySecondField;
}
(...)
}
Ignoring those unknown fields result in all POJO fields being null. What could be the problem in here?
EDIT: Sample JSON
{"my_second_field":"samplevalue", "my_first_field":[{"inner":"value"}]}
Make sure you import #JsonProperty annotation from fasterxml package, not from anywhere else.

serialize and deserialize without map name

I have the following Object:
public class Class_a{
private List<class_b> someList;
}
public class Class_b{
private Map<String,String> someMap;
}
My json will look like this:
"someList":[{"someMap":{"strKey1":"strValue1"}},{"someMap":{"strKey2":"strValue2"}}]
Is it possible to serialize a Json that will look like this, without changing my Objects (and I will have the option to deserialize the Object):
"someList":[{"strKey1":"strValue1"},{"strKey2":"strValue2"}]
*I know that if will defined my object like this:
public class Class_a{
private List<Map<Strung,String>> someList;
}
i will get a Json like I want - but I am trying to find more elegant solution then 'list' that contain a 'map'
My project use spring framework and Jackson.
This worked for me I only had to add getters and setters to your classes and I was able to parse with jackson:
#Test
public void t() throws IOException {
String json = "{\"someList\":[{\"someMap\":{\"strKey1\":\"strValue1\"}},{\"someMap\":{\"strKey2\":\"strValue2\"}}]}";
Class_a a = new ObjectMapper().readValue(json, Class_a.class);
System.out.println(a);
}
#Getter
#Setter
public class Class_a{
private List<Class_b> someList;
}
#Getter
#Setter
public class Class_b{
private Map<String,String> someMap;
}
I'm using lombok but that's nothing special, you can create the getters/setters manually too and will work

Jackson converting Map<CustomEntity, Integer> to JSON creates toString() from CustomEntity

I have custom Entity that i want to put as Json to my view page
But when i serialize it in map using ObjectMapper from Jackson i receive String created from toString() method
#Test
public void test() throws JsonProcessingException {
Map<ProductEntity, Integer> map = new HashMap<ProductEntity, Integer>();
ProductEntity prod = new ProductEntity();
prod.setIdProduct(1);
map.put(prod, 1);
ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.writeValueAsString(map));
}
Received: {"com.onlineshop.entity.ProductEntity#2":1}
where "com.onlineshop.entity.ProductEntity#2" is a String, not an object.
So how can i make it to be an Object?
I need exactly Map, not another type of Collection
You either need to annotate your ProductEntity object so Jackson knows how to serialize it or use a Mix In annotation if you are not able to modify the ProductEntity class. IIRC there are also global Jackson options you can set that tell it how to handle POJOs.
Since you didn't specify which version of Jackson you're using I can't link to the correct documents but there is a ton of information available on the Jackson sites on how to use annotations and mix ins.
Thanks to all for your answers.
I solved it by creating new DTO which contains :
private ProductEntity
private Integer
fields.

Wrap certain values when serializing JSON with Gson

How can I wrap certain values when serializing an object model to JSON with GSON? Example model:
class Order {
Customer cust;
}
class Customer {
String name;
int age;
}
Serializing a Customer would normally yield something like:
{cust:{name:joe, age:21}}
What I would like to do is wrap the Order and Customer values in an additional element with the class name. So the expected JSON would be:
{Order:{cust:Customer:{name:joe, age:21}}}
The actual classes that I'll be serializing could be anything, so I can't hardcode specific properties in a serializer. But I will want to wrap certain properties with their class name.
How can I do this?
This is not a valid json string though:
{Order:{cust:Customer:{name:joe, age:21}}}
In you application, you have to model/implement your domain class properly before it can be used for serializing/deserializing json string, in another word, the domain class should be known before calling toJson/fromJson method. However the actual domain class type can be determined dynamically at runtime, By using Java Generic Type.
Check out the section Serializing and Deserializing Generic Types from Gson User Guide:
public class Foo<T> {
public T value;
}
To serialize it:
Gson gson = new Gson();
Type fooType = new TypeToken<Foo<Bar>>() {}.getType();
gson.toJson(foo, fooType);
To deserialize it:
Gson gson = new Gson();
Type fooType = new TypeToken<Foo<Bar>>() {}.getType();
gson.fromJson(json, fooType);

Jackson: deserialization to a collection

I have this specific problem with JSON deserialization. Let's have this JSON structure:
{
"header":{
"objects":[
{"field":"value1"},
{"field":"value2"}
]
}
}
The JSON structure can't be altered as it comes from a 3rd party system.
Now let's have this simple POJO:
#JsonDeserialize(using=PojoDeserializer.class)
public class Pojo {
private string field;
//...getter, setter
}
The mentioned PojoDeserializer takes {"field": "value"} json string and deserializes it to the Pojo instance. So I can simply do the deserialization like this
Pojo instance = new
ObjectMapper().readValue("{\"field\":
\"value\"}", Pojo.class);
And here's my problem. Let's have another deserializer PojosCollectionDeserializer which takes the mentioned structure and deserializes it to a Collection of Pojo instances. I'd like to use it in a similar fashion as in the previous example:
Collection<Pojo> pojos = new ObjectMapper().readValue("{...}", Collection.class);
But this doesn't work as there is not defined that Collection should be created using the PojosCollectionDeserializer. Is there any way to achieve it?
I am not sure why are trying to explicitly specify deserializers, as it would all work just fine with something like:
public class Message {
public Header header; // or, if you prefer, getter and setter
}
public class Header {
public List<Pojo> objects;
}
public class Pojo {
public String field;
}
Message msg = objectMapper.readValue(json, Message.class);
without any additional configuration or annotations. There is no need to construct custom serializers or deserializers for simple cases like this.

Categories

Resources