Jackson maps objects in [ ] but not in { } - java

I have a rest application and I'm using Jackson to convert objects to Jsons, but I have a problem:
public class Stats {
public int id;
public String name;
public int stat1;
public float stat2;
}
This method produces a following json:
[[8769,"TEST_PRODUCT#2#0",327,8.0],[8809,"TEST_PRODUCT#4#0",345,9.0],[8749,"TEST_PRODUCT#1#0",349,9.0],[8729,"TEST_PRODUCT#0#0",418,10.0],[8789,"TEST_PRODUCT#3#0",430,11.0]]
But [ and ] is start_array and end_array tokens, and so it is not correct as I think, because my objects are not arrays, so I think something like this would be correct:
[{id: 8769,name:"TEST_PRODUCT#2#0",stat1: 327,stat2: 8.0}, ......]
How can I map my List like this?

Related

Unable to map API response to pojo

I have a json response
"data": {
"students": [
{
"id": 100,
"name": "ABC"
},
{
"id": 101,
"name": "XYZ"
}
I need to map it to my pojo, something like -
public class TempClass {
List<Temp> list_students;
}
class Temp {
Long id;
String name;
}
Direct reading API response into my pojo gives me a class cast exception. I've tried converting response to a list of map and the collect as Temp class but that also doesn't work.
Exception -
java.util.LinkedHashMap cannot be cast to java object
Any suggestions please?
Code snippet for conversion -
new TempClass(((LinkedHashMap<String, Object>) response.getData()).entrySet())
.stream().map(map -> mapper.convertValue(map, Temp.class))
.collect(Collectors.toList()))
public class Data{
public ArrayList<Student> students;
}
public class Root{
public Data data;
}
public class Student{
public int id;
public String name;
}
Your POJO class will look like this

Deserialization of different objects Android

I have a problem with deserialization list of different objects. Help me please to resolve this issue. This JSON is required by the customer side.
{"result":[
{
"id": 5,
"op":[
0,
{ "description": "hello world" }
]}]
}
I have:
public class Transaction {
public int id;
public List<Object> op;
}
public class ResponseTransactions {
public List<Transaction> result;
}
Gson gson = new Gson();
List< List<Transaction>> list= gson.fromJson(json,
ResponseTransactions.class))
After that I must call LinkedTreeMap:
String description = (LinkedTreeMap)Transaction.op.get(1).get("description");
But I want to use like this:
public class Operation{
public String description;
}
public class Transaction {
public String id;
public List<Operation> op;
}
I am not sure why you would have a dissimilar collection of objects cast into a list of concrete objects , but if thats what is required, you might want to look at a custom Deserializer. Here's a very informative link on how to create a custom deserializer for gson lib.
https://futurestud.io/tutorials/gson-advanced-custom-deserialization-basics
In your deserializer, you'll need to skip any JsonElement which is not of type "Operation"

Using GSON to parse an array of objects that contains an object that contains a needed String

To start, here is the item I am trying to parse. Right now, I am trying to obtain the value of the "name" key from this JSON. I haven't had trouble using GSON to obtain other necessary variables, but this one is much trickier than those.
"types": [
{
"slot": 2,
"type": {
"url": "https://www.pokeapi.co/api/v2/type/4/",
"name": "poison"
}
},
{
"slot": 1,
"type": {
"url": "https://www.pokeapi.co/api/v2/type/12/",
"name": "grass"
}
}
]
Here is my code that allowed me to successfully create the treecko object from all of the desired variables besides the array of Types.
Gson gson = new Gson();
PokedexMemberJava treecko = gson.fromJson(jsonPokemon, PokedexMemberJava.class);
The classes I used to attempt to create the object from the JSON. When I attempted to create the object from the JSON, all variables were successfully loaded besides the array of Types, which was created as null. These other variables were loaded from a different section of JSON, but I included a link to this at the bottom of this post if looking at it is necessary.
public class PokedexMemberJava {
int id;
String name;
int height;
int weight;
Types[] type;
public PokedexMemberJava(int id, String name, int height, int weight){
this.id = id;
this.name = name;
this.height = height;
this.weight = weight;
}
}
public class Types {
public Type typeObject;
public int slot;
public Types (Type typeObject, int slot){
this.typeObject = typeObject;
this.slot = slot;
}
}
public class Type {
public String url;
public String name;
public Type (String url, String name){
this.url = url;
this.name = name;
}
}
I've spent a couple hours trying to figure this out and trying to get the name variable with other libraries like org.json to no avail. I only included the JSON of the part I was trying to obtain above. If for some reason you want to see what the entire JSON object would look like that I'm trying to parse, you can find it here: https://pokeapi.co/api/v2/pokemon/252/ . Also, I apologize for any mistakes or poor formatting of this post. It is my first time posting a question on StackOverflow.
You have json field name mismatch:
Instead of Types[] types;, you have Types[] type; which does not matchtypes property in json
Instead of Type type;, you have Type typeObject; which does not match type property in json
So you have 2 options:
Rename java field to match the json property OR
Use #SerializedName to override the property name:
public class PokedexMemberJava {
#SerializedName("types")
Types[] type;
...
public class Types {
#SerializedName("type")
public Type typeObject;

Deserialization of JSON array

I'm not sure how to deserialize array containing plain strings.I'm trying to parse the following JSON
{
"state":"RT",
"testMethod":"electronic",
"testElements":[
{
"testId":[
"UT_ITXref",
"Fed_ITXref"
]
},
"testStartDate",
"testEndDate",
"testDueDate"
]
}
I'm getting the following error:
com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of com.test.rules.model.TestElements: no String-argument constructor/factory method to deserialize from String value ('testStartDate')
at [Source: {"state":"RT","testMethod":"electronic","testElements":[{"testId":["UT_ITXref","Fed_ITXref"]},"testStartDate","testEndDate","testDueDate"}]}; line: 1, column: 247] (through reference chain: com.test.rules.model.TestRules["testElements"]->java.lang.Object[][1])
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:270)
at com.fasterxml.jackson.databind.DeserializationContext.instantiationException(DeserializationContext.java:1456)
at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1012)
at com.fasterxml.jackson.databind.deser.ValueInstantiator._createFromStringFallbacks(ValueInstantiator.java:370)
at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.createFromString(StdValueInstantiator.java:315)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromString(BeanDeserializerBase.java:1282)
at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:159)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:150)
at com.fasterxml.jackson.databind.deser.std.ObjectArrayDeserializer.deserialize(ObjectArrayDeserializer.java:196)
at com.fasterxml.jackson.databind.deser.std.ObjectArrayDeserializer.deserialize(ObjectArrayDeserializer.java:20)
at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:499)
at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeWithErrorWrapping(BeanDeserializer.java:511)
at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeUsingPropertyBased(BeanDeserializer.java:396)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1198)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:314)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:148)
at com.fasterxml.jackson.databind.ObjectReader._bindAndClose(ObjectReader.java:1626)
at com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:1220)
Here is what I did , I used #JsonCreator annotation to deserialize
public class TestRules {
private String state;
private String testMethod;
private TestElements[] testElements;
#JsonCreator
public TaxRules(
#JsonProperty("state") String state,
#JsonProperty("testMethod") String testMethod,
#JsonProperty("testElements") TestElements[] testElements
) {
this.state = state;
this.testMethod = testMethod;
this.testElements = testElements;
}
}
public class TestElements {
private List<String> testId;
private List<String> elements;
public List<String> getElements() {
return elements;
}
public void setElements(List<String> elements) {
this.elements = elements;
}
public List<String> getTestId() {
return testId;
}
public void setTestId(List<String> testId) {
this.testId = testId;
}
}
Should I write custom deserializer or Is there any way that I can use the jackson API for this. Any suggestions would be appreciated.
Actually errors tells something.
JSON parser found that for testElements property there is an Array of Objects, but your Json file has mixed content.
first element is an object (I assume it is TestElement class). Then parser creates that object with empty constructor and calls appropriate setters for its properties.
but...
second,third and forth elements are String, so error says that parser tries to find constrictor with String as argument.
So, you may try to make that constructor in TestElement class and see will it work or not...
Do not forget to keep empty constructor as well.
I cannot guarantee it will work but, at least error says that.
BTW are you sure your Json object is correct? but not something like that?
{
"state":"RT",
"testMethod":"electronic",
"testElements":[
{
"testId":[
"UT_ITXref",
"Fed_ITXref"
]
}],
"testStartDate":"01-01-2017",
"testEndDate":"01-02-2017",
"testDueDate":"01-03-2017"
}
I'm a little confused because StartDate, EndDate, DueDate semantically look more like test attributes, not as elements in testElements array
{
"state": "RT",
"testMethod": "electronic",
"testElements": [
{
"testId": [
"UT_ITXref", // <-- this object is deserialized just fine
"Fed_ITXref"
]
},
"testStartDate", // <-- this is where the error is happening
"testEndDate",
"testDueDate"
]
}
Did you intend the json to be interpreted as if it looked like the following?
{
"state": "RT",
"testMethod": "electronic",
"testElements": [
{
"testId": [
"UT_ITXref",
"Fed_ITXref"
]
},
{
testId: [
"testStartDate"
]
},
{
testId: [
"testEndDate"
]
},
{
testId: [
"testDueDate"
]
}
]
}
If so, you'll need to make a custom deserializer to detect whether the element in the array is an object or a string. If it's a string, you'll probably want to construct the TestElement yourself.

Convert JSON with integers to Java POJO objects

I have this JSON data, and I was wondering how I might convert this data to a Java POJO object:
"progression": {
"64693": [
{
"1": 1
}
],
"64717": [
{
"1": 4
}
]
},
I was thinking it can't be:
public class Progression{
private List<64693> 64693;
private List<64717> 64717;
public List<64693> get64693(){
return this.64693;
}
public void set64693(List<64693> 64693){
this.64693 = 64693;
}
public List<64717> get64717(){
return this.64717;
}
public void set64717(List<64717> 64717){
this.64717 = 64717;
}
}
I'm very familiar with Java, so I know I can do a #JsonProperty instead of the actual numbers, but just wondering if there were any other choices.
Thanks!
_ug had the right suggestion:
... object consider naming 64693 to like DataType64693 and adding the
#JsonProperty("64693") annotation
That worked fine. And BTW, I am using the Jackson 2.0 JSON processor.

Categories

Resources