Parse json arrays with ValidatableResponseOptions.body - java

As ValidatableResponseOptions.body documentation shows you can "parse" a JSON to check whether a value exists (or similar).
Now my JSON liiks like this:
[
{
"from_name": "Peter",
},
{
"from_name": "Max"
}
]
I want to check if there are arrays with the from_name Peter. I tried:
.body("[].from_email", equalTo("Peter"))
This throws the error Invalid JSON expression:Script1.groovy: 1: unexpected token: [ # line 1, column 27. [].from_email ^1 error.
Trying following also not works:
.body("$..from_email", equalTo(shopEmailAddress))
or
.body(".from_email", equalTo(shopEmailAddress))
How is the correct syntax for this?

You've tried to parse an array of json instead of a json. That's what the error is telling you. You should iterate on the array and parse each json independently.
You can also stream the array and look for the first case which verifies your predicate.

Related

How do I remove all control characters in a string in Java?

My REST API, which is build with Spring in Java, produces an invalid JSON object, because it contains multiple breaks in a string, which lead to the problem, that the string has an unexpected end and the rest doesn't count as part of the string anymore, example:
{
"status": "Success",
"message": "Lorem ipsum",
"data": {
"correct": [
{
"record": "ULTRA LONG
XML STRING
WITH BREAKS",
"code": 0,
"errors": []
}
]
}
}
The error arises in the data -> correct -> record string field, because it contains breaks which splits the original string.
My API endpoint serializes the above JSON like this:
#PostMapping(value="/check-records",
consumes=MediaType.APPLICATION_JSON_VALUE,
produces=MediaType.APPLICATION_JSON_VALUE)
public Response checkRecords(#RequestBody(required=true) Records records) {
// Check records
return new Response("Success", "Lorem ipsum", data);
}
Response is a class, which automatically gets serialized into a JSON object after returning. data is a map in order to create the above JSON structure.
I couldn't find any suitable solution for my problem yet. Does anybody has an idea how I could remove all breaks, spaces or control characters before I serialize the JSON object?
I appreciate any kind of help, sheers! :)
Thanks to #pringi. He suggested to use a regex to remove all control characters in Java before I serialize the JSON object.
String record = orginalRecord.replaceAll("[\\\\p{Cntrl}^\\r\\n\\t]+", "")
You can find more informations about regex in the original question: How to remove control characters from java string?

FreeMarker template error: JSONArray wrapped into f.e.b.StringModel

i'm trying to send JSON object to my free marker, but i getting error while testing JUnit
here is my object
{
"filename": "test",
"orderId": "123435",
"orderDate": "23.09.2020г.",
"itemsCount": "4",
"items": [
{
"itemName": "ТВ Приставка 400",
"itemCount": "2 шт Х 400₽",
"itemSum": "800.00"
}
],
"totalSumm": "3000.00"
}
here is my error:
FreeMarker template error:
The value you try to list is an extended_hash+string (org.camunda.bpm.engine.impl.util.json.JSONArray wrapped into f.e.b.StringModel), thus you must specify two loop variables after the "as"; one for the key, and another for the value, like <#... as k, v>).
how could i resolve it?
items is a arrays of JSON objects
FreeMarker knows nothing about org.camunda.bpm.engine.impl.util.json.JSONArray, so it doesn't see it as a list-like thing (as a sequence, as it's called in FTL). So you can do one of these:
Using the objectWrapper Configuration setting, you teach FreeMarker how to treat JSONArray as a list. (You can find more about custom ObjectWrapper-s elsewhere.) Then you can just #list such objects, and use all the other operations applicable to sequences.
Or, you call the Java API-s of JSONArray from the template. That will be less convenient of course, but requires no prior investment.

Filter JSON string from String having json string and normal string in java

I am stuck in a problem where I have to filter json data from a String which is a combination of json string and normal text.
sample: This message has all your required detail { "name" : "xyz","age": "21","place" :"sdf", "number": "7689"} check in this page you will get the details.
I need to extract the json object from given string.
Result expected is only : { "name" : "xyz","age": "21","place" :"sdf", "number": "7689"}.
Is there any clean way of doing this in Java.
One way to solve this is to remove non-json string and extract json object.
But that is a bad approach in my view.
If there are no other JSON-like parts, you can just extract the part between the first { and last }, including both ends:
int start=str.indexOf('{');
int end=str.lastIndexOf('}');
String json=str.substring(start,end+1);
Then of course you may want to check if both start and end are non-negative (so the characters are actually present), if there is a possibility that the string does not contain anything for you.
Also note that JSON can be an array too, so you can try checking if a pair of first [ and last ] lies outside of the {...}, but then at the end single values are valid JSON too (like true, false, 1, etc.). This is not really a happy task to write properly, thinking of everything.

What is the correct way to handle large json strings in vert.x?

I have a large (Currently 2MB in size, might grow up to 10MB) JSON object (containing an array of objects) from an HTTP API I need to work with:
client.get(...)
.send(ar -> {
JsonObject jsonObject = new JsonObject(ar.result().bodyAsBuffer());
});
This results in an error:
Jan 09, 2020 2:11:14 PM io.vertx.core.impl.ContextImpl
SEVERE: Unhandled exception
io.vertx.core.json.DecodeException: Failed to decode:Unexpected character (',' (code 44)): expected a value
at [Source: (io.netty.buffer.ByteBufInputStream); line: 70674, column: 27]
at io.vertx.core.json.Json.decodeValue(Json.java:222)
at io.vertx.core.json.JsonObject.fromBuffer(JsonObject.java:975)
at io.vertx.core.json.JsonObject.<init>(JsonObject.java:85)
I think this error occurs because of how large the JSON string is as the Json string appears to be valid. Is there a way in vert.x to handle large Json Strings/files? Or is there something else going on here?
The JSON was invalid but the tool being used to validate the JSON manually did not catch this.
The error was with the third party api, when a double field was blank it would leave the value for the key blank instead of null.
This:
{
"String": "string",
"Double": ,
"AnotherDouble": 0.1
}
should be this:
{
"String": "string",
"Double": null,
"AnotherDouble": 0.1
}
Fix was to report the invalid JSON to the developers who patched the issue making blank values null instead of blank.
10 MB json file might be large on a mobile device.
You should be using JsonArray instead of JsonObject in your code:
JsonArray jsonArray = new JsonArray(ar.result().bodyAsBuffer())

Jersey rest server - Return different structure for list as json

I'm experiencing a different json structure of a returned list when running on Tomcat.
{
"apartment": [
{
"apartmentName": "ABC",
"id": "1"
},
{
"apartmentName": "DEF",
"id": "2"
}
]
}
Since the controller is returning List of apartments; ideally it should start with square braces [] instead of curly braces. This results into JSON parser on client side think that it's a JSONObject instead of JSONArray. I am not sure how to fix this. Below are the various POM dependency and their version.
Tomcat version I am using is 7.0.67
jersey-server-1.19
jersey-servlet-1.19
jersey-json-1.19
jersey-spring-1.19
jersey-core-1.19
This is because you're returning a List of Apartments from your servlet. You can fix this by returning an array like this
return new Apartment[]; // Collect all apartment objects and return it as an array
and Jackson will convert it accordingly. In your case I think you have Java object that has a parameter called apartments of type List. I assume you're using Jackson as the provider.

Categories

Resources