I can't converter this response api "[ "a", [ "adidas", "acb", "amazon" ] ] to object java or kotlin
The format of your JSON data is not very suitable to convert to a java object directly,try to make your JSON data like this:
{"a": ["adidas", "acb", "amazon"] }
or
{"keyA" : "a", "keyB" : ["adidas", "acb", "amazon"] }
But it's still depends on what is your actual demand
You can test your JSON data here:
JSON to JAVA Converter live
May be this example can help you.
public class Test {
public static void main(String... args) throws Exception {
String json = "[ "a", [ "adidas", "acb", "amazon" ] ];
// Now do the magic.
Data data = new json().fromJson(json, Data.class);
// Show it.
System.out.println(data);
}
}
class Data {
private String data;
private List<String> groups;
public String getData() { return data; }
public void setData(String data) { this.data= data; }
public List<String> getGroups() { return groups; }
public void setGroups(List<String> groups) { this.groups = groups; }
}
Related
I am creating a crud form in which I am producing and consuming Json data.
Problem:
Json data I am producing is very dynamic. So I don't know how to map it to my pojo class.
What I have tried
1) Using jackson library, I created structure of my json data and
tried mapping with it. It failed as in data "**Keys**" are dynamic so mapping failed.
2) I searched and found JsonNode provided by Jackson, problem with
this is my json structure has key:[{},{}] structure like this
**key-->array of objects**, so I tried parsing it with json node but failed.
My Json Data
Type 1
{
"city_master": [
{
"citycode": [
"100",
"1130385"
]
},
{
"cityname": [
"London",
"1130383"
]
},
{
"statecode": [
"512",
"1130382"
]
}
]
}
Problem with structure is that key = "city_master" or any key in this format eg("citycode", "cityname" etc) is dynamic so can't create mapping pojo for this class.
Then I tried fixing the outer key as root and parse is as Json Node as
Type 2
{
"root": [
{
"citycode": [
"100",
"1130385"
]
},
{
"cityname": [
"London",
"1130383"
]
},
{
"statecode": [
"512",
"1130382"
]
}
]
}
In this structure I loose my key value, but I can store it else where.
With JsonNode (Type-2) I tried this
String jsonString = tdObj.getTempData(); // return's Json String
TempDataTblPojo obj = new ObjectMapper().readValue(jsonString, TempDataTblPojo.class);
JsonNode jsonNode = obj.getRoot();
System.out.println("Name = " + jsonNode);
This class TempDataTblPojo
public class TempDataTblPojo {
private JsonNode root;
public JsonNode getRoot() {
return root;
}
public void setRoot(JsonNode root) {
this.root = root;
}
}
It prints this
Name = [{"citycode":["100","1130385"]},{"cityname":["London","1130383"]},{"statecode":["512","1130382"]}]
Now how to parse this JsonNode, to get all this key-value's? Or is there is efficient or much more cleaner solution, I will be happy to accept.
Maybe this will help you.
class Pojo {
private List<PojoItem> root;
public List<PojoItem> getRoot() {
return root;
}
public void setRoot(List<PojoItem> root) {
this.root = root;
}
}
class PojoItem {
private Map<String, List<String>> items = new HashMap<>();
public Map<String, List<String>> getItems() {
return items;
}
#JsonAnySetter
public void setItem(String key, List<String> values) {
this.items.put(key, values);
}
}
And then you can get it from json using this:
Pojo result = objectMapper.readValue(json, Pojo.class);
When I call my API with a request body I deserialize it with the variable name in my POJO. I modify the same list and return back but it duplicates the list
#JsonSerialize
#JsonIgnoreProperties(ignoreUnknown = true)
public class UASchema {
#JsonProperty("metric_id")
private ArrayList<String> fMetricId;
#JsonProperty("schema")
private ArrayList<String> fSchema;
#JsonProperty("hash")
private String fHash;
...
...
//getter and setters
}
Request body is
{
"data" : [
{
"metric_id": ["k1", "ak2", "d90"],
"schema": ["s1", "s2"]
},
{
"metric_id": ["k21", "k22"],
"schema": ["a11", "s22"]
}
]
}
Response I get is (added hash)
{
"result": [
{
"fmetricId": [
"k1",
"ak2",
"d90"
],
"fschema": [
"s1",
"s2"
],
"metric_id": [
"k1",
"ak2",
"d90"
],
"schema": [
"s1",
"s2"
],
"hash": "389abc9093442cfd2aee1f20807ba467"
},
{
"fmetricId": [
"k21",
"k22"
],
"fschema": [
"a11",
"s22"
],
"metric_id": [
"k21",
"k22"
],
"schema": [
"a11",
"s22"
],
"hash": "5f366dde65b69fa679f95a81f3115b7f"
}
]
}
It duplicates the list and not correctly serializing it. I want the response to just have the same list as request body and I added hash back.
It looks like your algorithm duplicates entries or you manually generated getters and setters which duplicate output. By default Jackson does not add extra entries. See below example how you can do that, I generated getters and setters in IDE. f-fieldName pattern for fields is outdated and you should use regular names. See, for example, Google's Java Guide:
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import java.io.File;
import java.util.List;
import java.util.UUID;
public class JsonApp {
public static void main(String[] args) throws Exception {
File jsonFile = new File("./resource/test.json").getAbsoluteFile();
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
Root root = mapper.readValue(jsonFile, Root.class);
root.getData().forEach(s -> s.setfHash(UUID.randomUUID().toString()));
System.out.println(mapper.writeValueAsString(root));
}
}
class Root {
private List<UASchema> data;
public List<UASchema> getData() {
return data;
}
public void setData(List<UASchema> data) {
this.data = data;
}
#Override
public String toString() {
return "Root{" +
"data=" + data +
'}';
}
}
class UASchema {
#JsonProperty("metric_id")
private List<String> fMetricId;
#JsonProperty("schema")
private List<String> fSchema;
#JsonProperty("hash")
private String fHash;
public List<String> getfMetricId() {
return fMetricId;
}
public void setfMetricId(List<String> fMetricId) {
this.fMetricId = fMetricId;
}
public List<String> getfSchema() {
return fSchema;
}
public void setfSchema(List<String> fSchema) {
this.fSchema = fSchema;
}
public String getfHash() {
return fHash;
}
public void setfHash(String fHash) {
this.fHash = fHash;
}
#Override
public String toString() {
return "UASchema{" +
"fMetricId=" + fMetricId +
", fSchema=" + fSchema +
", fHash='" + fHash + '\'' +
'}';
}
}
Above code prints:
{
"data" : [ {
"metric_id" : [ "k1", "ak2", "d90" ],
"schema" : [ "s1", "s2" ],
"hash" : "80dcf06d-1d83-463c-afb8-edef8efdc71f"
}, {
"metric_id" : [ "k21", "k22" ],
"schema" : [ "a11", "s22" ],
"hash" : "a83d7981-4b80-4318-a632-f3c91d14379b"
} ]
}
I am currently common api client util using spring rest template.
Our api result like following..
single result :
{
"data" : {
"id" : "...",
"name" : "..."
...
}
}
multiple result :
{
"data" : {
"cnt" : 30,
"list" : [
{
"id" : "...",
"name" : "..."
...
},
{
"id" : "...",
"name" : "..."
...
},
{
"id" : "...",
"name" : "..."
...
}
...
]
}
}
And I made two common response class like following
public class Response<T> {
private T data;
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
and
public class ListResponse<T> {
private long cnt;
private List<T> list;
public long getCnt() {
return cnt;
}
public void setCnt(long cnt) {
this.cnt = cnt;
}
public List<T> getList() {
return list;
}
public void setList(List<T> list) {
this.list = list;
}
}
and example of using RestTemplate is
public <T> T apiCaller(String api){
T result= restTemplate.exchange(api,
HttpMethod.GET,
new HttpEntity<>(headers),
new ParameterizedTypeReference<Response<T>>(){}).getBody().getData();
return result;
}
and then I used,
when the result is single,
UserResponse user = apiRequest.<UserResponse>apiCaller("/users/1");
when the result is multiple,
ListResponse<UserResposne> users = apiRequest.<ListResponse<UserResponse>>apiCaller("/users");
But it also doesn't work.
it occur java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.joont.Response.ListResponse.
So I searched so much in google, but I didn't search how...
How can I solve this problem?
and I did it wrong? is it impossible?
So, I'm quite new to this Json world and well I'm trying to parse this Json below into a class in java using Gson, but I'm not sure if this is the correct way, because I want this to be a list of maps where the nomeArquivo would be the key in this map, can you guys help me to achive this? Or this way I posted is fine?
Test class
public class JsonTeste {
public static void main(String[] args) {
Gson gson = new Gson();
try (Reader reader = new FileReader("foobar.json")) {
List<FastqcJson[]> list = gson.fromJson(reader, new TypeToken<List<FastqcJson[]>>(){}.getType());
for (FastqcJson[] fastqcJsons : list) {
for (FastqcJson fastqcJson : fastqcJsons) {
System.out.println(fastqcJson);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Bean class
public class FastqcJson {
#SerializedName("name")
private String nomeArquivo;
#SerializedName("data")
private HashMap<Integer, Double> mediaBaseNumeros;
....
}
Printed Objects
FastqcJson [nomeArquivo=SRR3192396, mediaBaseNumeros={1=31.939449600540865, 2=32.05829640249262}]
FastqcJson [nomeArquivo=SRR3192397, mediaBaseNumeros={1=32.01549563582736, 2=32.13918804626231}]
Json File
[ [
{
"color": "#5cb85c",
"data": [
[
1,
31.939449600540865
],
[
2,
32.05829640249262
]
],
"name": "SRR3192396"
},
{
"color": "#5cb85c",
"data": [
[
1,
32.01549563582736
],
[
2,
32.13918804626231
]
],
"name": "SRR3192397"
}
]
]
There is no built-in way to do this since "data" is an array of arrays in its native JSON representation.
To do what you want to do you will need to create a wrapper type and write a custom deserializer:
public class MediaBase {
private HashMap<Integer, Double> numeros;
public MediaBase(HashMap<Integer, Double> numeros) {
this.numeros = numeros;
}
}
public class FastqcJson {
#SerializedName("name")
private String nomeArquivo;
#SerializedName("data")
private MediaBase mediaBaseNumeros;
....
}
public class MediaBaseAdapter extends TypeAdapter<MediaBase> {
#Override
public MediaBase read(JsonReader reader) throws IOException {
if (reader.peek() == JsonToken.NULL) {
reader.nextNull();
return null;
}
HashMap<Integer, Double> output = new HashMap<>();
reader.beginArray(); //Read "data" as array
while (reader.hasNext()) {
reader.beginArray(); //Read data array
int key = reader.nextInt();
double value = reader.nextDouble();
output.put(key, value);
reader.endArray();
}
reader.endArray();
return new MediaBase(output);
}
#Override
public void write(JsonWriter writer, MediaBase value) throws IOException {
if (value == null) {
writer.nullValue();
return;
}
// Inverse of reader
HashMap<Integer, Double> output = value.numeros;
writer.beginArray();
for (Map.Entry<Integer, Double> e : output.entries()) {
writer.beginArray();
writer.value(e.getKey());
writer.value(e.getValue());
writer.endArray();
}
writer.endArray();
}
}
Add this adapter during the creation of your GSON instance with GsonBuilder.registerTypeAdapter(MediaBase.class, new MediaBaseAdapter()) and the adaptor will correctly pack and unpack your datatype.
Do note that this is written from memory and I've not been able to verify that it compiles.
I have a JsonNode which contains the following JSON. Inside that JsonNode object is an array. In that array there are three fields, one of which, slaid, is a list. The other two are strings. Here is the JSON.
{
"SLA": [
{
"slaid": [
"53637cc144ae8b607e089701"
],
"ragindicator": "Red",
"name": "r1"
},
{
"slaid": [
"53637d1844ae8b607e089704"
],
"ragindicator": "Amber",
"name": "a1"
},
{
"slaid": [
"53637eac44ae8b607e089706"
],
"ragindicator": "Green",
"name": "g1"
}
]
}
I want to parse this value. How can I parse it , where slaid's type is List<String>? I have tried some ways but I am still unable to find the solution.
The easiest way I can see is creating POJO classes which fit to your JSON:
class Slaids {
#JsonProperty("SLA")
private List<Slaid> slaids;
public List<Slaid> getSlaids() {
return slaids;
}
public void setSlaids(List<Slaid> slaids) {
this.slaids = slaids;
}
#Override
public String toString() {
return slaids.toString();
}
}
class Slaid {
private List<String> slaid;
private String ragindicator;
private String name;
public List<String> getSlaid() {
return slaid;
}
public void setSlaid(List<String> slaid) {
this.slaid = slaid;
}
public String getRagindicator() {
return ragindicator;
}
public void setRagindicator(String ragindicator) {
this.ragindicator = ragindicator;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public String toString() {
return "Slaid [slaid=" + slaid + ", ragindicator=" + ragindicator + ", name=" + name + "]";
}
}
Simple usage:
ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.readValue(json, Slaids.class));
Above program prints:
[Slaid [slaid=[53637cc144ae8b607e089701], ragindicator=Red, name=r1], Slaid [slaid=[53637d1844ae8b607e089704], ragindicator=Amber, name=a1], Slaid [slaid=[53637eac44ae8b607e089706], ragindicator=Green, name=g1]]
If you want to use JsonNode you can do it in this way:
ObjectMapper mapper = new ObjectMapper();
JsonNode rootNode = mapper.readTree(json);
ArrayNode slaidsNode = (ArrayNode) rootNode.get("SLA");
Iterator<JsonNode> slaidsIterator = slaidsNode.elements();
while (slaidsIterator.hasNext()) {
JsonNode slaidNode = slaidsIterator.next();
System.out.println(slaidNode.get("slaid"));
System.out.println(slaidNode.get("ragindicator"));
System.out.println(slaidNode.get("name"));
}
Above program prints:
["53637cc144ae8b607e089701"]
"Red"
"r1"
["53637d1844ae8b607e089704"]
"Amber"
"a1"
["53637eac44ae8b607e089706"]
"Green"
"g1"