Can JsonPath be used to validate multiple paths? - java

I need to verify that JSON contains values in two fields.
Can I verify that some JSON contains two values, for example ...
$.field1.field2 = test && $.field3[*].field4 = test2
...using JsonPath?
I can successfully validate one field but I don't know how to validate multiple fields

You can use a JsonPath Filter for each condition and you can combine filters with and.
For example:
Filter combinedFilter = Filter.filter(
Criteria.where("$.field1.field2").is("test").and("$.field3[*].field4").is("test2")
);
JsonPath.parse(json).read("$", combinedFilter);
More details in the docs.

Related

How to set defined key as example in generated documentation of a hashmap in springdoc?

I am documenting a java API but the keys for properties that are maps or associative arrays are represented as property1, property2, property3 ... etc.
this is an example of that
#Schema(
description = " This object contains the plans selected by the user.",
name = "plans")
var plans: Map<Int, Plan> = ConcurrentHashMap()
the representation of the generated example in the UI is good in terms of content but I would like to replace just the generated keys by the real ones.
ie property1 by 258.
can someone helpme on how can I get this done using springdoc and its annotations ?

How to remove the json key value with JSonPath in java

I know it could be a duplicate, but still posting my question as i could not find the exact answer what i am looking for. I am having an json object (or string) like below.
String str = "{
"status" : {
"timestamp" : "2020-04-30T01:00:00 000Z"
"error" : 0,
"error_message" : null,
"execution" : "completed"
}
}
";
I will get the a same kind of response from my REST API testing, but after each call the 'timestamp' key will be having a dynamic date and time value with the time respect to the call made. And here i compare my expect json with the actual json as a whole sting comparison using JSONAssert. As the timestamp value is different it always fails for me.
So my question is before i do any comparison, i would like to remove the 'timestamp' key and its value from json to compare and so it will pass my case. I tried by using JsonPath also, but did not works. Any help on this please?
JSONAssert allow you to make a customized comparator while doing asserts [1].
In your case it's easy as:
JSONAssert.assertEquals(expectedJson,
actualJson,
new CustomComparator(JSONCompareMode.LENIENT,
skips("status.timestamp","another.json.path", ...)));
private static Customization[] skips(String... jsonPaths) {
return Arrays.stream(jsonPaths)
.map(jsonPath -> Customization.customization(jsonPath, (o1, o2) -> true))
.toArray(Customization[]::new);
}
Here we are defining CustomComparator, with customization which takes JSONPath (status.timestamp) and takes a ValueMatcher (lambda) which compares two values for that specific JSONPath.
In our case we will always return true, which will effectively skips the value (no matter with what we are comparing that value it's always true).
Edit: As you can see CustomComparator's constructor takes varargs of Customizations, hence you can provide more than one field to be ignore from comparison.
[1] http://jsonassert.skyscreamer.org/apidocs/org/skyscreamer/jsonassert/Customization.html
[2] http://jsonassert.skyscreamer.org/apidocs/org/skyscreamer/jsonassert/comparator/CustomComparator.html

How to write a http get request when a key's value is an array?

I have written a java servlet to deal with http get request.I know ,the common format of get request is like this:http://IP_ADDRESS:8080/test?name="jack"&value="shit.
But now ,I have a list of values to transfer,such as an user id list[1,2,3,4].So ,my question is ,how should I write my http get request to express this?And in java servets doGet(),can I use request.getParameterValues to get such an array?
if you are using GET method your url should be looking like that :
http://IP_ADDRESS:8080/test?list=1&list=2&list=3
for retrieving it:
String[] arrlist=request.getParameterValues('list');
your array will be filled with separated values:
//["1","2","3"]
UPDATE : if to write it list[] or list?
when you retrieving your list parameters it wouldn't be parsed as array but as a series of String which will be grouped later on into an array.
Which means even if you write it list[]=1&list[]=2&list[]=3, list[=1&list[=2&list[=3, list*=1&list*=2&list*=3 or list=1&list=2&list=3 it would always be giving you the same answer whether you retrieve it as
request.getParameterValues('list[]') //["1","2","3"]
request.getParameterValues('list[') //["1","2","3"]
request.getParameterValues('list*') //["1","2","3"]
request.getParameterValues('list') //["1","2","3"]
While ,the http request format should be like this:localhost:8080/test?list[]=1&list[]=2&list[]=3
Maybe too simple, but what about repeat parameters name?
http://IP_ADDRESS:8080/test?userId=1&userId=2&userId=3

Easiest way to extract fields from JSON

Update: I should have mentioned this right off the bat: I first considered a Java/JSON mapping framework, but my manager does not want me adding any more dependencies to the project, so that is out as an option. The JSON-Java jar is already on our classpath, so I could use that, but still not seeing the forest through the trees on how it could be used.
My Java program is being handed JSON of the following form (althought the values will change all the time):
{"order":{"booze":"1","handled":"0","credits":"0.6",
"execute":0,"available":["299258"],"approved":[],
"blizzard":"143030","reviewable":["930932","283982","782821"],
"units":"6","pending":["298233","329449"],"hobbit":"blasphemy"}}
I'm looking for the easiest, efficient, surefire way of cherry-picking specific values out of this JSON string and aggregating them into a List<Long>.
Specifically, I'm looking to extract-and-aggregate all of the "ids", that is, all the numeric values that you see for the available, approved, reviewable and pending fields. Each of these fields is an array of 0+ "ids". So, in the example above, we see the following breakdown of ids:
available: has 1 id (299258)
approved: has 0 ids
reviewable: has 3 ids (930932, 283982, 782821)
pending: has 2 ids (298233, 329449)
I need some Java code to run and produce a List<Long> with all 6 of these extracted ids, in no particular order. The ids just need to make it into the list.
This feels like an incredibly complex, convoluded regex, and I'm not even sure where too begin. Any help at all is enormously appreciated. Thanks in advance.
The easiest way IMO is use a json library such as gson, jackson, json.org, etc, parse de JSON into an object and create a new List<Long> with the values of the properties you need.
Pseudocode with gson:
class Order {
long[] available;
long[] approved;
...
}
Order order = gson.fromJson("{ your json goes here }", Order.class);
List<Long> result = new ArrayList<Long>();
result.add(order.getAvailable());
result.add(order.getApproved());
...
Pseudocode with json.org/java:
JSONObject myobject = new JSONObject("{ your json goes here"});
JSONObject order = myobject.getJSONObject("order");
List<Long> result = new ArrayList<Long>();
for (int i=0; i<order.getJSONArray("approved").length(); i++) {
Long value = order.getJSONArray("approved").getLong(i);
result.add(value);
}
...

Fetching two attributes of a xml file using xpath

I have a xml file which has a tag as below:
<locator xlink:type="locator" xlink:href="https://www.google.co.in/" xlink:title="Google" xlink:show="replace" xlink:actuate="onRequest" xlink:role="website" rank="1"> </locator>
There are many locator tag in the xml file with different roles and rank .
I am able to get the role of the above tag using #*[local-name()='role'.
Now I need to get the rank attribute based on the role.
Is there any way to fetch two attributes and there values together?
I am new to Xpath . Please help me with this.
Well //locator[#xlink:role = 'website']/#rank (with a suitable binding of the prefix xlink to the namespace http://www.w3.org/1999/xlink) is an example of selecting the rank attributes of locator elements where the role is website.
I am able to get the role of the above tag using
#*[local-name()='role'.
Now I need to get the rank attribute based on the role. Is there any
way to fetch two attributes and there values together?
Use:
ExprStartYouDidntShow/#*[local-name()='role' or name()='rank']
where ExprStartYouDidntShow is the expression selecting the elemen(s) whose two attributes should be selected.
Or, if you need to get these two attributes only when the role attribute has a particular value -- say "wantedValue", use:
ExprStartYouDidntShow/locator[#*[local-name() = 'role'] = 'website']
/#*[local-name()='role' or name()='rank']

Categories