Parsing a JSON component whose structure is always changing in JAVA - java

I want to extract all the keys and value from a JSON component. The issue is the structure of this is unknown. I want to parse it in JAVA such that I can retrieve any element using the key/field name.
For example:
In this CustomError object is in this format.
"CustomError": "{\"errors\": [{ \"type\": \"INVALID_HTTP_VERB\", \"description\": \"Invalid HTTP verb for the requested resource\" }]}"
In this its in this format.
"CustomError": "{\"status\":{\"code\":104050,\"user_message\":\"Method Not Allowed\",\"developer_message\":\"Invalid http method or method not allowed\"}}"
My goal is to get all the keys and its value.
For 1st example :-
type : INVALID_HTTP_VERB
description : Invalid HTTP verb for the requested resource
For 2nd example :-
code : 104050
user_message : Method Not Allowed
developer_message : Invalid http method or method not allowed

Are you using the Google gson library? If so you can use the JsonParser object like;
JsonElement j_element = new JsonParser().parse(YOUR_STRING);
Then you can step through the element in whatever form it's in, you can check types like element.IsJsonObject() or element.IsJsonArray() or whatever.
You can also turn the element into an object if is one, and do object.has("value") then if it is a JsonObject you can loop through the fields like;
for (Map.Entry<String, JsonElement> entry : YOUR_OBJECT.entrySet())
{
//do further bits
}

Related

Input a JSONArray into swagger API for a springboot controller

I am new to using springboot and swagger, so not very familiar with this stuff. But what I want to do is to input a JSONArray into a swagger API and get the input into a controller. So, I have the following controller code:
#RestController
public class NameRegisterController{
#Autowired
private NameRegisterService service;
#Postmapping(path="/control")
public void NameRegisterAdd(#RequestParam JSONArray NameList)
{
service.addNames(NameList);
}
}
Here, addNames is a function which takes JSONArray as input. When I go to the swagger API, I add the input as:
["name1","name2","name3"]
Unfortunately, when I execute, I get the error
"ConversionFailedException: Failed to convert from type[java.lang.String] to type [#org.springframework.web.bind.RequestParam org.json.JSONArray] for value 'name1'; nested exception is org.json.JSONException: JSONArray test must start with '[' at 1 [character 2 line 1"
I don't get it because the first character of my input is "[" as put in the swagger API. Would be very grateful if someone can provide some help.
My swagger is in my work environment, so am inserting similar pictures from the internet.
The first pic is what I get. The second pic is what I want
String Array
Frontend Pass with HTTP request
[“a”,”b”,”c”]
Backend receive in controller methods
#RequestParam String[] ids
#RequestParam List<String> ids
And I dont see you defining which request parameter name it should be looking at?
Example:
public String inputControllerMethod(#RequestParam(value="myParam") List<String> myParam){
}
=== Edited ===
You can't.
Using the [Add String Item] button you must insert 1 String at a time.
However if they are not Strings, but rather an Array of Objects, then swagger allows you to write the array:
Use this https://editor.swagger.io/#/ to see an example.
Documentation: https://swagger.io/docs/specification/2-0/describing-parameters/
Your other option also if you really dont want the user to enter and you are limited by specific options is an enum:
parameters:
- name: "status"
in: "query"
description: "Status values that need to be considered for filter"
required: true
type: "array"
items:
type: "string"
enum:
- "placed"
- "approved"
Then the user simply selects multiple/all options:

How to convert Complex JSON string in to MAP in scala

I have a text file which contains a line like
players={"Messi":{"Details":{"Goals":500},"Country":"Argentina"},"Neymar":{"Clubs":["Santos", "FC barcelona", "Paris saint German"], "Country":"Brazil"}}
Now I am used a regex for extract the
{"Messi":{"Details":{"Goals":500},"Country":"Argentina"},"Neymar":{"Clubs":["Santos", "FC barcelona", "Paris saint German"],"Country":"Brazil"}}
from the text file and pass it in to a case class which accepts the value as a String.
and I am making a Dataframe using this case class.
In my case every line may be different in the contents with in the JSON String.So I am looking for a general solution to Convert any complex Json string to Map values.
When checking dataframe.printSchema, I am getting the players column as a String type.
But I need it to be as a Map type which holds a Key and value as a Struct type.
I tried method referred in this link
How can I convert a json string to a scala map?
when I used this way,I got error
"org.json4s.package$MappingException: Do not know how to convert JObject(List((Details,JObject(List((Goals,JString(500))))), (Country,JString(Argentina)))) into class java.lang.String "
and I used following solutions
Converting JSON string to a JSON object in Scala
But these too won't worked for me.
This is my case class
case class caseClass (
Players :String = ""
)
I am Extracting the json string using a user defined function.
Simply my requirement is that I have a complex Json String which contains keys and values as struct,list etc..
so I want to make the string to its corresponding JSON which holds a proper schema with respect to its contents.
Kindly expecting Valuable solutions.
If you also can live with JsValue as value instead of String it looks a bit simpler:
import play.api.libs.json._
case class CaseClass (
Players :Option[JsValue]
)
object CaseClass {
implicit val jsonFormat = Json.format[CaseClass ]
}
I saw some problems with your Json - so you would need to have something like:
val json = Json.parse("""{
"Players":{
"Messi":{"Details":{"Goals":500},"Country":"Argentina"},
"Neymar":{"Clubs":["Santos", "FC barcelona", "Paris saint German"], "Country":"Brazil"}
}
}"""
)
To get a String out of this you can use:
json.validate[CaseClass] match {
case JsSuccess(cc, _) => cc.Players.toString
case JsError(errors) => // handle errors
}
I got another solution which I think More easier.
I Made an own schema for the JSON and Used from_json method with the schema,and it worked well.
from_json(col("Players"),ownschema).as("new_Json")
and my ownschema contains the structure of the Json String.
For any doubts, Comment.
Happy Coding.

REST services PATCH API example

I am trying to call the REST Webservices PATCH API, here is My JSON payload
[
{ "op":"replace", "path":"/values/Timestamp","value":"2016-10-28T15:25:43.511Z"},
{ "op":"replace", "path":"/values/Flag", "value":true },
{ "op":"replace", "path":"/values/Flow", "value":"Flow A"},
{"op":"replace", "path":"/values/Interests", "value":[ "Sports", "Book Reading" ] }
]
JSON Value attribute has different values with different data types. and I want to prepare Entity object(Java) and convert it into JSON and call REST end point.
now
I am not very sure
which is the best suitable data type I can choose for values attribute
I have referred following links but I didn't get enough details
Android REST API using PATCH method
https://www.rfc-editor.org/rfc/rfc5789#section-2.1
http://blog.earaya.com/blog/2013/05/30/the-right-way-to-do-rest-updates/
http://williamdurand.fr/2014/02/14/please-do-not-patch-like-an-idiot/
but I didn't get enough details.
any suggestion on this is really appriciated
Got the java object from the client and created another Java class with below properties and set the values
opn - string
path - String
value - Object
added above java objects to array list then used the GSON library to convert it into the array of JSON objects which will be accepted by patch api.
and please note the content type is application/json-patch+json

How to write my own JSON parser?

I want to write a JSON parser that parses input JSON of depth n for college assignment.
As far as I have understood, I will have to convert this JSON into <String, Object> map and then create classes out of it.
Is this correct? also How would I come to know exact datatypes of the values in JSON?
for ex my sample JSON sis.
{
“name”: “user”,
“address”: {
"city":"abc",
"zip":12345
}
}
Then I am supposed to create a class named say User that has to fields
1. name: String 2. Adderss : Object
and Address class having city : string and zip :int with getters and setters.
Is this correct? How to dynamically create a class?
How should I start ?
see this for that (not recommended): Creating classes dynamically with Java.
Advice of #T.J.Crowder is a good one: some collection.
public class json_java{
Map<String,Object> values=new HashMap<String,Object>;
To get the type:
JSONObject one_object=...
Object one_value = one_object.get("city");
one_value.getClass().getName(); // => String

JSON Parsing problem

Hey,
Im trying to parse the following JSON data:
{"chat":
{"link":
[{"#rel":"next","#ref":"http"}],
"events":
{"link2":
[{"#rel":"next","#ref":"http"}]}
}}
The code that reads the data is (where 'a' is the JSON as String):
JSONObject jsonObject1 = new JSONObject(a);
JSONObject jsonObject = jsonObject1.getJSONObject("chat");
So the structure (at least the way I intended) is:
<chat>
<link>
<events>
<link2>
</events>
</chat<
But, after getJsonObject("chat"), jsonObject equals to:
{"chat":{"events":{"link2":[{"#ref":"http","#rel":"next"}]},"link":[{"#ref":"http","#rel":"next"}]}}
What am I missing? Why does the data flips and the structure changes?
The properties in a JSON object are not sorted. From the JSON site:
An object is an unordered set of name/value pairs...
(My emphasis) Therefore the position of link and event are irrelevant for the parser. Bottom line, link and event are at the same level therefore they can be shifted and wherever order matters use arrays in JSON ... [].

Categories

Resources