I've tried so many ways, but without success to parse this Json to a Java Object using Gson library:
"return":{
"48388":{
"status":"canceled",
"operations":{
},
"created":"138232386",
"price":"12.50000",
"volume":"50.00000000",
"pair":"btc_brl",
"type":"buy"
},
"51714":{
"status":"canceled",
"operations":{
},
"created":"1365465421706",
"price":"1500.00000",
"volume":"0.10000000",
"pair":"btc_brl",
"type":"buy"
},
"48754":{
"status":"canceled",
"operations":{
},
"created":"1383237058",
"price":"600.00000",
"volume":"0.50000000",
"pair":"btc_brl",
"type":"buy"
}
"success":1
}
There is a lot of topics about this, but none of them cover this type of json mapping.
I'm convinced that there is a simple way to do that, any ideas? Thanks!
EDIT:
I'm trying this:
public class Test {
#SerializedName("return")
public Return1 _return;
}
public class Return {
public List<Map<String, Order>> order;
}
EDIT:
public class Order {
#SerializedName("id")
private int idOrder;
private String status;
private String created;
private String price;
private String volume;
private String pair;
private String type;
private List<Operations> operations;
// All the gets and sets here..
}
Gson doesn't initialize my order object. The order object is always null. I can't find the correct way to implement this mapping.
After a long battle I was able to solve using this solution:
public void deserialize() {
Gson gson = new Gson();
// For isr read InputStreamReader
Map<String, Object> map = gson.fromJson(isr, Map.class);
System.out.println(map.get("success"));
Map<String, Object> map2 = (Map<String, Object>) map.get("return");
// Show the contents of return
System.out.println(map2);
}
After that I used an Entry object to iterate and set the values of Order.
Thanks!
Related
stucked at accessing nested json. similar stuff:
[
{
key-value,
key-value
},
{
key-value,
key-value
},
{
key-value,
key-value
}
]
works nicely but when i try:
{
"alfa":{
"id":"foo",
"product":{
"id":"foo1",
"price":"foo2"
}
},
"beta":{
"id":"foo",
"product":{
"id":"foo1",
"price":"foo2"
}
}
}
i get error:
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type `java.util.ArrayList<...
i of course did change structure of classes:
public class Alphabet{
private Purchase purchase;
...
public class Purchase{
private String id;
private Product product;
...
public class Product {
private String id;
private String price;
...
to read it:
ObjectMapper mapper = new ObjectMapper();
InputStream inputStream = new FileInputStream(new File("src/main/json/file.json"));
TypeReference<List<Alphabet>> typeReference = new TypeReference<List<Alphabet>>() {};
List<Alphabet> alphabet= mapper.readValue(inputStream, typeReference);
System.out.println(alphabet);
whats wrong, please?
It seems like the JSON structure you try to read is not a List<Alphabet>, but a Map<String, Purchase>.
Your second json not like list of object. The second json look lik have 2 main objects if so you need class like below.
public class Alphabet{
private Purchase purchase;
private Purchase purchase1;
}
But it not good practice. Use as first josn like list of objects.
I am trying to convert following JSON to Java object and ending up with UnrecognizedPropertyException.
{
"5214": [{
"name": "sdsds",
"age": "25",
"address": null
},
{
"name": "sdfds",
"age": "26",
"address": null
}]
}
Here "5214" is the random key that I get. I can covert it by modifying JSON little bit. But I want to know whether any possible way to convert the mentioned JSON. I even tried with following snippet taking some reference.
public class SampleTest {
private Map<String, List<EmployeeDetails>> employeeDetails = new HashMap<String, List<EmployeeDetails>>();
public Map<String, List<EmployeeDetails>> getEmployeeDetails() {
return employeeDetails;
}
public void setEmployeeDetails(Map<String, List<EmployeeDetails>> employeeDetails) {
this.employeeDetails = employeeDetails;
}
}
public class EmployeeDetails {
private String name;
private String age;
private String address;
//Getters and Setters
}
Can someone guide me on this?
Use Type Reference (Import Jackson Package for Java)
TypeReference<Map<String, List<EmployeeDetails>>> typeReference = new TypeReference<Map<String, List<EmployeeDetails>>>()
{
};
Map<String, List<EmployeeDetails>> employeeDetails = new ObjectMapper().readValue(jsonString, typeReference);
Check something from that
Maybe:
public class Data {
// String contain the Key, for example: 5214
Map<String, List<EmployeeDetails>> employeeDetails =
new HashMap<String,List<EmployeeDetails>>();
public Data() {
}
#JsonAnyGetter
public Map<String, List<EmployeeDetails>> getEmployeeDetails() {
return employeeDetails;
}
}
I would use custom deserializer with few helper classes. To make the code (matter of opinion I guess) clearer, create the list object:
#SuppressWarnings("serial")
#Getter #Setter
public class EmployeeDetailsList extends ArrayList<EmployeeDetails> {
// this will hold the arbitrary name of list. like 5214
private String name;
}
Then this list seems to be inside an object, say Wrapper:
#Getter
#RequiredArgsConstructor
#JsonDeserialize(using = WrapperDeserializer.class)
public class Wrapper {
private final EmployeeDetailsList employeeDetailsList;
}
So there is annotation #JsonDeserializer that handles deserializing Wrapper. It is not possible to directly deserialize unknown field names to some defined type so we need to use mechanism like this custom deserializer that inspects what is inside Wrapper and determines what to deserialize and how.
And here is how the deserializer works:
public class WrapperDeserializer extends JsonDeserializer<Wrapper> {
private final ObjectMapper om = new ObjectMapper();
#Override
public Wrapper deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
TreeNode node = p.readValueAsTree();
// This is the place for caution. You should somehow know what is the correct node
// Here I happily assume there is just the one and first
String fName = node.fieldNames().next();
EmployeeDetailsList edl = om.readValue(node.get(fName).toString(),
EmployeeDetailsList.class);
edl.setName(fName);
return new Wrapper(edl);
}
}
Please check it carefully it is not perfect in sense finding alwasy the correct node and maybe the instantiation can be done in other ways better. But it shoudl give you a hunch how it could be done.
I am very new to java and just started with json...
I have the following json file:
"step1": {
"version": 1,
"items": {
"run": false,
"jump": true
}
},
"step2": {
"version": "None",
"items": {
"happy": true,
"sad": false
}
}
I am using Gson in my main like this:
Gson gs = new Gson();
Content tmp = gs.fromJson(<json string>, Content.class);
my class:
public class Content {
#SerializedName("step1")
private Step step1;
#SerializedName("step2")
private Step step2;
}
each step class:
public class Step{
#SerializedName("version")
private String version;
#SerializedName("items")
???????
}
as you can see the "?????" part is what I am trying to understand - How can I convert the items without needing to know the field name..? meaning to a HashMap/another iterable object..? can I initialize using a method..?
I have tried creating an Item class with a constructor but I do not understand how to use it in this case..
The solution that worked for me is:
public class Step{
#SerializedName("version")
private String version;
#SerializedName("items")
private HashMap<String,Boolean> items;
}
You can use a Map<String, Boolean> to store your items. You Step class can be something, like this:
public class Step {
private String version;
private Map<String, Boolean> items;
}
Then you can add your values to the Map:
Step step = new Step();
step.setVersion("None");
Map<String, Boolean> items = new HashMap<>();
items.put("happy", Boolean.TRUE);
items.put("sad", Boolean.FALSE);
step.setItems(items);
Hope that helps you.
How can I convert the JSON string like this:
{ "summary": {
"totalMR":4.599000000000903E12,
"totalMA":1.9174920000386694E11,
"totalQA":5.1111111181E9,
"totalQR":1.000020666115264E11
},
"result": [{},{}],
"success":"true",
"total":49
}
to a Java object. I went through many similar posts and implemented constructors but couldn't find the proper explanation of why I'm unable to De-serialize the JSON.
Am I doing anything wrong?
My Class:
public class expResponse {
private String success;
private String total;
private ArrayList<LinkedHashMap<String,Object>> result;
private LinkedHashMap<String,SummaryResponse> summary;
// Constructor: public expResponse(){}
// Getter and Setter
}
public class SummaryResponse {
private Float totalQR;
private Float totalQA;
private Float totalMR;
private Float totalMA;
public SummaryResponse(){}
// Setter and Getter
}
My Code:
private expResponse processResult(String result) throws IOException{
ObjectMapper objectMapper = new ObjectMapper();
expResponse expResponseObj =
objectMapper.readValue(result, expResponse.class);
return expResponseObj;
The json you posted would not deserialize into a map of SummaryResponse objects, but rather an individual SummaryResponse object. To make your binding work, you would have to have json that looked something like this:
{
...
'summary': {
'summary1': {"totalMR":4.599000000000903E12,"totalMA":1.9174920000386694E11,"totalQA":5.1111111181E9,"totalQR":1.000020666115264E11}
'summary2': {"totalMR":4.599000000000903E12,"totalMA":1.9174920000386694E11,"totalQA":5.1111111181E9,"totalQR":1.000020666115264E11}
}
...
}
Alternatively, if you need to make your Java class conform to the json you provided, you simply need to change the declaration of summary:
private SummaryResponse summary;
Field summary in your json is an object of type SummaryResponse and not a LinkedHashMap.
public class ExpResponse {
private String success;
private String total;
private ArrayList<LinkedHashMap<String,Object>> result;
private Summary summary;
}
I don't think you have a problem in the code. Your input fails because it is not in the correct format. If you try to write the same values from an object with the same values to string you get something like:
{
"success":"true",
"total":"49",
"result":null,
"summary":{
"one_summary":{
"totalQR":2000.0,
"totalQA":1500.0,
"totalMR":1000.0,
"totalMA":500.0
}
}
}
And the major difference is the one summary. This is because summary is a map and maps need a key for each entryset. That means that summary is your map which has a one_summary key.
Is it the SummaryResponse that can't be deserialised?
I guess your attributes should have the same name "totalMR", "totalMA"....
or you should use an annotation JsonProperty(value="totalMR") and so on.
I have a JSON array like as shown below which I need to serialize it to my class. I am using Jackson in my project.
[
{
"clientId": "111",
"clientName": "mask",
"clientKey": "abc1",
"clientValue": {}
},
{
"clientId": "111",
"clientName": "mask",
"clientKey": "abc2",
"clientValue": {}
}
]
In above JSON array, clientValue will have another JSON object in it. How can I serialize my above JSON array into my java class using Jackson?
public class DataRequest {
#JsonProperty("clientId")
private String clientId;
#JsonProperty("clientName")
private int clientName;
#JsonProperty("clientKey")
private String clientKey;
#JsonProperty("clientValue")
private Map<String, Object> clientValue;
//getters and setters
}
I have not used jackson before so I am not sure how can I use it to serialize my JSON array into Java objects? I am using jackson annotation here to serialize stuff but not sure what will be my next step?
You can create a utility function shown below. You may want to change the Deserialization feature based on your business needs. In my case, I did not want to fail on unknown properties => (FAIL_ON_UNKNOWN_PROPERTIES, false)
static <T> T mapJson(String body,
com.fasterxml.jackson.core.type.TypeReference<T> reference) {
T model = null;
if(body == null) {
return model;
}
com.fasterxml.jackson.databind.ObjectMapper mapper =
new com.fasterxml.jackson.databind.ObjectMapper();
mapper.configure(com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,
false);
try {
model = mapper.readValue(body, reference);
} catch (IOException e) {
//TODO: log error and handle accordingly
}
return model;
}
You can call it using similar approach as shown below:
mapJson(clientValueJsonString,
new com.fasterxml.jackson.core.type.TypeReference<List<DataRequest>>(){});
You can try #JsonAnyGetter and #JsonAnySetter annotations with an inner class object. Also clientName should have type String, not int.
public class DataRequest {
private String clientId;
private String clientName;
private String clientKey;
private ClientValue clientValue;
//getters and setters
}
public class ClientValue {
private Map<String, String> properties;
#JsonAnySetter
public void add(String key, String value) {
properties.put(key, value);
}
#JsonAnyGetter
public Map<String,String> getProperties() {
return properties;
}
}