I am having a problem when I want to be able to map a single Object but also an Array of those object with com.fasterxml.jackson.annotation
Please see below example keep in mind that this is a response payload and it is not under my control:
{
"GetSomeUserInfoDetails": {
"ItemListOfUser": {
"itemList": {
"item": [
{
"name": "Stack overflow",
"adress": "ola"
},
{
"name": "Google",
"adress": "man"
}
]
}
}
}
}
The jsontopojo is generating the classes that I can use for this response. The problem occurs when there is only one item int itemList user i get the following response:
{
"GetSomeUserInfoDetails": {
"WorkItem": {
"itemList": {
"item": {
"name": "Stack overflow",
"adress": "ola"
}
}
}
}
}
When you generate the classes now you will see a different class structure. Is there a way how we can solve this with Jackson?
Related
I'm having difficulty implementing a JSON to send as a POST call in Spring.
Which is the fastest and most effective way to turn this json into a java object or a map and make the call?
below is an example of a json to send:
{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"name": "edge-ws"
},
"spec": {
"selector": {
"matchLabels": {
"run": "edge-ws"
}
},
"replicas": 1,
"template": {
"metadata": {
"labels": {
"run": "edge-ws"
}
},
"spec": {
"containers": [
{
"name": "edge-ws",
"image": "server-tim:latest",
"imagePullPolicy": "Never",
"ports": [
{
"containerPort": 80
}
]
}
]
}
}
}
}
this and the second body that has a value (nodeport) that must be taken from a field entered by the user front end side.(page created in html)
{
"apiVersion": "v1",
"kind": "Service",
"metadata": {
"name": "edge-ws",
"labels": {
"run": "edge-ws"
}
},
"spec": {
"type": "NodePort",
"ports": [
{
"port": 8080,
"targetPort": 80,
"nodePort": 30200,
"protocol": "TCP",
"name": "http"
}
],
"selector": {
"run": "edge-ws"
}
}
}
Both files must be sent with a single click on a button on the front end side.the first call with the first body starts and if everything is ok the second body starts
What should the class that maps objects look like? What should the controller look like instead?
They also gave me an address to call that can only be used on the machine, how can I test this call locally?
Thanks in advance!
You can use google's Gson library to convert the JsonString to Object and then use below code:
Gson gson = new Gson();
Object requestObject = gson.fromJson(jsonString, Object.class);
ResponseObject responseObject = restTemplate.postForObject(url, requestObject, ResponseObject.class);
I am trying to find a generic solution in GSON for my project. This JSON has been problematic for me...
I have a class System
public class System{
String systemid;
String systemname;
//getter and setter
}
Rest service sends data in one of two below format, now for the second format I am handling it in a generic way as shown in last, can someone please help me to handle both the formats in a generic way in one piece of code, I am stuck on this from past two days now...
[
{
"atypes": [
{
"systemid": "123",
"systemname": "abc"
},
{
"systemid": "456",
"systemname": "def"
},
{
"systemid": "789",
"systemname": "ghi"
},
{
"id": "0123",
"name": "klm"
},
{
"systemid": "4567",
"systemname": "nop"
}
]
}
]
Or the second format
[
{
"systemid": "123",
"systemname": "abc"
},
{
"systemid": "456",
"systemname": "def"
},
{
"systemid": "789",
"systemname": "ghi"
},
{
"id": "0123",
"name": "klm"
},
{
"systemid": "4567",
"systemname": "nop"
}
]
Now I am handling the last JSON array in the below method, I want to handle both the code in one piece of generic code.
String data = client.executeCommand(Command.GET, new GenericUrl(URL), null);
System[] tList1 = JsonUtil.jsonArrayToObjectArray(data, System[].class);
which calls a generic piece of code
public static <T> T[] jsonArrayToObjectArray(String data, Class<T[]> tClass) throws Exception {
return new Gson().fromJson(data, tClass);
}
Please if someone can help me...
Edit:
This is different from identifying Json object and json array as here both are json array.
I have dynamic json format from rest API like this :
{
"data": {
"response_code": "success",
"value": {
"Table": [
{
"id": 5,
"username": "blahblah",
"password": "blahblah",
"role": 2,
"email": "blah#tes.com",
"tanggal_buat": "2019-01-01T00:00:00"
}
]
}
},
"meta": {
"http_status": 200
}
}
Object "value" has an object array name "Table". Table can contain value from my database dynamically depend on my query. So, Sometimes the json format will change for example :
{
"data": {
"response_code": "success",
"value": {
"Table": [
{
"id_product": 44,
"product": "blahblah",
"lot": "blahblah",
"qty": 2,
}
]
}
},
"meta": {
"http_status": 200
}
}
How to accept the json value and assign to gson directly with different subclass of "Table"
I try it in retrofit and using kotlin
override fun onResponse(call: Call<MainResp>, response: Response<MainResp>) {
mainResponse : MainResp = response.body()
}
Assuming that you have the following class among others (using sth like http://www.jsonschema2pojo.org/):
class Value {
List<Table> tables;
}
The "Table" class here cannot be completely random!
You'll need to define the possible types of "Table" e.g. Table1, Table2... TableN.
Now you can update Value class with a generic type T instead of Table and write your custom type adapter:
class Value {
List<T> tables;
}
One of the tutorials on how to write your own type adapter is here.
how to access districtID(key) value and name(key) value using retrofit ?
this is json file...
{
"error": false,
"message": "District successfully fetched.",
"districts": [
{
"districtID": "DIS260920181",
"name": "Raipur"
},
{
"districtID": "DIS260920182",
"name": "Bilaspur"
},
{
"districtID": "DIS011020186",
"name": "korba"
},
{
"districtID": "DIS011020187",
"name": "jagdalpur"
},
{
"districtID": "DIS021020188",
"name": "surguja"
},
{
"districtID": "DIS021020189",
"name": "Mungeli"
}
]
}
Please help :(
Convert JSON Array into POJO classes and then call api using retrofit network call.
Use this link
copy your json and it gives you two model class you should put the parent class which contains error , message and districts as your output in your request. something like this
#GET("your_url")
Call<ModelExample> nameOfMethod();
And then you have list of districts. you can access to the items and districtID and name
I hope it helps you :)
for onResponse:
--------------------------
Call<ModalClass> daoCall = api.getconnectdata();
modelclass.enqueue(new Callback<ModalClass>() {
#Override
public void onResponse(Call<ModalClass> call, Response<ModalClass>
response) {
if(response.isSuccessful()){
modelclass= response.body();
List<Districts> list = modelclass.getAddData().getData();
adapter = new CustomListAdapter(getApplicationContext(),list);
listView.setAdapter(adapter);
}
}
The ImageUrl is:
The JsonObject:
{
"type":"table",
"subtype":"attribute_list",
"doc":"https://api-v2.swissunihockey.ch/api/doc/attribute_list",
"data":{
"context":null,
"headers":[
{
"text":"Name",
"key":"teamname",
"long":"Name",
"short":"Name",
"prefer":"fit"
},
{
"text":"Logo",
"key":"logo_url",
"long":"Logo",
"short":"Logo",
"prefer":"fit"
},
{
"text":"Webseite",
"key":"website_url",
"long":"Webseite",
"short":"Webseite",
"prefer":"fit"
},
{
"text":"Teamportrait",
"key":"portrait",
"long":"Teamportrait",
"short":"Teamportrait",
"prefer":"fit"
},
{
"text":"Liga",
"key":"liga",
"long":"Liga",
"short":"Liga",
"prefer":"fit"
},
{
"text":"Anschrift",
"key":"address",
"long":"Anschrift",
"short":"Anschrift",
"prefer":"fit"
}
],
"title":"MR Krauchthal II",
"subtitle":null,
"tabs":[
],
"slider":null,
"regions":[
{
"text":null,
"rows":[
{
"highlight":false,
"cells":[
{
"text":[
"MR Krauchthal II"
]
},
{
"image":{
"alt":"",
"url":"https://res.cloudinary.com/swiss-unihockey/image/upload/t_club_logo/gin0rst7ocrcuioryacs.png"
}
},
{
"url":{
"href":null,
"text":"Webseite"
}
},
{
"image":{
"alt":"",
"url":null
}
},
{
"text":[
"4. Liga"
]
},
{
"text":[
"MR Krauchthal",
"Thomas"
]
}
]
}
]
}
]
}
}
What you need is a JSON parser. There are several libraries you can use for that like Jackson or Gson.
Here some basic Json handling with Gson:
JsonObject json = new JsonParser().parse(myJsonString).getAsJsonObject(); // will parse your string to json and return it as a JsonObject
JsonObject data = json.get("data").getAsJsonObject(); // returns the jsonObject that contains everything in "data":{...}
JsonArray regions = data.get("regions").getAsJsonArray(); // to get an array like "regions"
for(int i=0;i<regions.size();i++){ // loop through the array
JsonObject region = regions.get(i).getAsJsonObject(); // get any element in the array (as JsonObject)
String text= region.get("text").getAsString(); // get a JsonElement from your JsonObject and read it as a String (like "text")
}
it does not seem very "clean" or "easy" and other Json libraries will do this differently, but I would recommend this way if you don't want the whole "data" object to be parsed in a POJO. All you have to do now is, use the methods I showed you to walk through your json until you get the "url" or any other element you want.