Get size or length of json array response (restAssured Response interface) - rest-assured

We have REST API automation scripts using RestAssured. In this declared response object as public static Response response; and retrieving the response data using response.jsonPath().get("id"), during this trying to even get the size or length of the id, even need to get details about tags array.
JSON Response:
[
{
"id": 1,
"name": "test1",
"tags": [
{
"tagType": "details1",
"tag": {
"description": null
}
}
]
},
{
"id": 2,
"name": "test2",
"tags": [
{
"tagType": "details2",
"tag": {
"description": null
}
}
]
}
]
Tried below ways:
public static Response response;
List<String> resIDs = response.jsonPath().get("id");
System.err.println("Retrieved IDs from Response: " + resIDs);
O/P: is [1,2,3,4,5,6,7]
Tried as resIDs.size(), that also no response printed.
List<Object> size = response.jsonPath().getList("$");
System.err.println("ArraySize for IDs from Response: " + size);
or
int size = response.jsonPath().getList("$").size();
O/P: Not printed/nothing shown
Please guide how to get the size/length.

I don't seem to find any issue in your code, I just changed a bit to run locally and its working fine. Here's my code
public class S_62591968 {
public static Response postCallWithJsonBodyParam(String URL) {
return RestAssured.given().relaxedHTTPSValidation().contentType(ContentType.JSON).request().when().get(URL);
}
public static void main(String[] args) {
String url_endPoint = "http://localhost:8089/def/abc";
Response response = postCallWithJsonBodyParam(url_endPoint);
List<String> resIDs = response.jsonPath().get("id");
System.out.println("Retrieved IDs from Response : " + resIDs);
System.out.println("ArraySize for IDs from Response : " + resIDs.size());
}
}
Console :
Retrieved IDs from Response : [1, 2]
ArraySize for IDs from Response : 2

Related

index percolate queries using spring data jpa

Here is my Dto for percolator query class.
#Data
#Document(indexName = "#{#es.indexName}")
#Builder(builderClassName = "RuleBuilder")
public class Rule {
#Id
private String id = UUID.randomUUID().toString();
private QueryBuilder query;
private RuleDataDto data;
public static class RuleBuilder {
private String id = UUID.randomUUID().toString();
}
}
Index Mapping
{
"mappings": {
"properties": {
"query": {
"type": "percolator"
},
"data": {
"properties": {
"subType": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"type": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
},
"content": {
"type": "text"
}
}
}
}
based on criteria I am generating queries and trying to index those to percolator. but getting below exception
query malformed, no start_object after query name
what should be the query field Type? can someone help me on this
You are trying to store an Elasticsearch object (QueryBuilder) in Elasticsearch without specifying the mapping type.
You will need to annotate your query property as percolator type and might change the type of your property to a String:
#Document(indexName = "#{#es.indexName}")
public class Rule {
#Id
private String _id;
#Field(type = FieldType.Percolator)
private String query;
// ...
}
Or, if you want to have some other class for the query property you'll need a custom converter that will convert your object into a valid JSON query - see the documentation for the percolator mapping.

guidance with iterating over nested json and extract values

new to coding and java so trying to figure out how I can iterate over this JSON and extract the nested values
{
"prop1": {
"description": "",
"type": "string"
},
"prop2": {
"description": "",
"type": "string"
},
"prop3": {
"description": "",
"type": "string"
},
"prop4": {
"description": "",
"type": "string"
}
}
So far I have this :
public class JSONReadExample
{
public static void main(String[] args) throws Exception {
Object procedure = new JSONParser().parse(new FileReader("myFile.json"));
ObjectMapper objectMapper = new ObjectMapper();
String procedureString = objectMapper.writeValueAsString(procedure);
Map<String, Object> map
= objectMapper.readValue(procedureString, new TypeReference<Map<String,Object>>(){});
map.forEach((key, value) -> System.out.println(key + ":" + value));
How can I retrieve the "type" such as "string" or "number" nested value for each key?
Try to specific type of Map like this:
Map<String, LinkedHashMap<String, String>> map = objectMapper.readValue(procedureString, new TypeReference<>() {});
And then you can retrieve "type" by using:
map.forEach((key, value) -> System.out.println(key + ":" + value.get("type")));

Need help to parsing JSON in Flutter

I am trying to get data from the internet in Flutter.
But I am getting an error on JSON parsing.
Can anyone tell me what is the problem?
I am trying to get data from this URL
https://swapi.co/api/starships/
Example JSON
{
"count": 37,
"next": "https://swapi.co/api/starships/?page=2",
"previous": null,
"results": [
{
"name": "Executor",
"model": "Executor-class star dreadnought",
"manufacturer": "Kuat Drive Yards, Fondor Shipyards",
"cost_in_credits": "1143350000",
"length": "19000",
"max_atmosphering_speed": "n/a",
"crew": "279144",
"passengers": "38000",
"cargo_capacity": "250000000",
"consumables": "6 years",
"hyperdrive_rating": "2.0",
"MGLT": "40",
"starship_class": "Star dreadnought",
"pilots": [],
"films": [
"https://swapi.co/api/films/2/",
"https://swapi.co/api/films/3/"
],
"created": "2014-12-15T12:31:42.547000Z",
"edited": "2017-04-19T10:56:06.685592Z",
"url": "https://swapi.co/api/starships/15/"
},
]
}
Model class
class RestModel {
final String name;
final String model;
final String manufacturer;
final String cost_in_credits;
final String length;
final String max_atmosphering_speed;
final String crew;
final String passengers;
final String cargo_capacity;
final String consumables;
final String hyperdrive_rating;
final String MGLT;
final String starship_class;
final List films;
final String pilots;
final String created;
final String edited;
final String url;
RestModel(
{this.name,
this.model,
this.manufacturer,
this.cost_in_credits,
this.length,
this.max_atmosphering_speed,
this.crew,
this.passengers,
this.cargo_capacity,
this.consumables,
this.hyperdrive_rating,
this.MGLT,
this.starship_class,
this.films,
this.pilots,
this.created,
this.edited,
this.url});
factory RestModel.fromJson(Map<String, dynamic> json) {
return RestModel(
name: json["name"],
model: json["model"],
manufacturer: json["manufacturer"],
cost_in_credits: json["cost_in_credits"],
max_atmosphering_speed: json["max_atmosphering_speed"],
crew: json["crew"],
passengers: json["passengers"],
cargo_capacity: json["cargo_capacity"],
consumables: json["consumables"],
hyperdrive_rating: json["hyperdrive_rating"],
MGLT: json["MGLT"],
starship_class: json["starship_class"],
films: json["flims"],
pilots: json["pilots"],
created: json["created"],
edited: json["edited"],
url: json["url"],
);
}
}
and the Flutter code is:
final link = "https://swapi.co/api/starships/";
List<RestModel> list;
Future getData() async {
var res = await http
.get(Uri.encodeFull(link), headers: {"Accept":"application/json"});
if (res.statusCode == 200) {
var data = json.decode(res.body);
var rest = data["results"];
for (var model in rest) {
list.add(RestModel.fromJson(model));
}
print("List Size: ${list.length}");
}
}
The main problem is when it tries to fill data from JSON.
RestModel.fromJson(model)
so what I have to change to fix this problem.
Try to cast the data 'results' to List , like this :
var rest = data["results"] as List;
Updated
Now that we know the error log: "No static method 'fromJson' declared in class 'RestModel'"
It's because you are using a static method in this line:
list.add(RestModel.fromJson(model));
You must change the call in order to use the factory constructor, like this :
list.add(new RestModel.fromJson(model));

Wiremock match request POST by params

I have a simple POST request sending params using application/x-www-form-urlencoded encoding.
Looking in the wiremock docs I can't find a way to match the request by the params values, something like the querystring match I mean.
Furthermore it seems also impossible to contains for the body, nor to match the entire body in clear (just as base64).
Is there a way to match this kind of requests?
Another option that I found was to use contains for Stubbing Content-Type: application/x-www-form-urlencoded
{
"request": {
"method": "POST",
"url": "/oauth/token",
"basicAuthCredentials": {
...
},
"bodyPatterns": [
{
"contains": "username=someuser"
}
]
},
"response": {
....
}
}
With classic wiremock you can use bodyPatterns' matchers and regular expressions:
for example:
...
"request": {
"method": "POST",
"url": "/api/v1/auth/login",
"bodyPatterns": [
{
"matches": "(.*&|^)username=test($|&.*)"
},
{
"matches": "(.*&|^)password=123($|&.*)"
}
]
},
I had a similar problem - I wanted to check the exact parameters , but without patterm magic (so easier to maintain). As a workaround, I created a helper class :
import java.util.Iterator;
import java.util.LinkedHashMap;
public class WireMockUtil {
public static String toFormUrlEncoded(LinkedHashMap<String, String> map) {
if (map == null) {
return "";
}
StringBuilder sb = new StringBuilder();
Iterator<String> it = map.keySet().iterator();
while (it.hasNext()) {
String key = it.next();
String value = map.get(key);
appendFormUrlEncoded(key,value,sb);
if (it.hasNext()) {
sb.append('&');
}
}
return sb.toString();
}
public static String toFormUrlEncoded(String key, String value) {
StringBuilder sb = new StringBuilder();
appendFormUrlEncoded(key, value,sb);
return sb.toString();
}
public static void appendFormUrlEncoded(String key, String value, StringBuilder sb) {
sb.append(key).append('=');
if (value != null) {
sb.append(value);
}
}
}
Inside the Wiremock test you can use it via:
LinkedHashMap<String, String> map = new LinkedHashMap<>();
map.put("key1", "value1");
map.put("key2", "value2");
...
withRequestBody(equalTo(WireMockUtil.toFormUrlEncoded(map))).
Or check only dedicated parts by containing:
withRequestBody(containing(WireMockUtil.toFormUrlEncoded("key","value1"))).
You could try https://github.com/WireMock-Net/WireMock.Net
Matching query parameters and body can be done with this example json:
{
"Guid": "dae02a0d-8a33-46ed-aab0-afbecc8643e3",
"Request": {
"Url": "/testabc",
"Methods": [
"put"
],
"Params": [
{
"Name": "start",
"Values": [ "1000", "1001" ]
},
{
"Name": "end",
"Values": [ "42" ]
}
],
"Body": {
"Matcher": {
"Name": "WildcardMatcher",
"Pattern": "test*test"
}
}
}
}

Map JSON to the model irrespective of Array or Object - ObjectMapper

I am having trouble in mapping the JSON to my object class. Here is my Model Object
class CityObject : NSObject, Mappable{
var id : String?
var name : String?
required init?(map: Map) {
}
func mapping(map: Map) {
id <- map["id"]
name <- map["name"]
}
}
The JSON response I get from server sometime may be Array or an Object like this.
Array:
{
"cities": [
{
"id": "190",
"name": "Elurupadu"
},
{
"id": "1230",
"name": "Sendhwa"
},
{
"id": "1262",
"name": "Multai"
},
{
"id": "1480",
"name": "Kherwara"
}]
}
Sometimes I get like this,
{
"cities": {"id": "6","name": "Hyderabad"}
}
Instead of an JSONArray it gives me JSONObject.
I am mapping to my class like this,
let list = Mapper<CityObject>().mapArray(JSONObject:cities["cities"])
This works perfectly when I get JSONArray, but the same doesn't work when I get JSONObject.
How to handle both with ObjectMapper?
As per Paulw11 suggestion down casting to MAP worked for me.
if let list = Mapper<CityObject>().mapArray(JSONObject:cities["cities"]){
//Handles JSONArray response
}
else if let list = Mapper<CityObject>().map(JSONObject: cities["cities"]){
//Handles JSONObject response
}
else{
//Handles error
}

Resources