JSON Array with multiple parameters for POST request using Rest Assured - graphql

I am new to Rest Assured & GraphQL, Please can someone help me to create the body request from the following output:
{
"variables": {
"EmployeeName": "ABC",
"EmployeeDept": "Computers",
"EmployeeStatus": false,
"employeeRegion": [{
"country": "USA",
"values": ["NewYork"]
}]
}
}
My sample:
ObjectNode variables = mapper.createObjectNode()
.put("EmployeeName", EmployeeName)
.put("EmployeeDept", "EmployeeDept")
.put("EmployeeStatus", "EmployeeStatus")
Not sure how to construct the employeeRegion in variables?

To make json array, just use List in java.
Example:
Region usa = new Region("USA", Arrays.asList("NewYork", "LA"));
Region uk = new Region("UK", Arrays.asList("London", "Manchester"));
List<Region> list = Arrays.asList(usa, uk);
....
put("employeeRegion", list);
Region.java
import lombok.Data;
import java.util.List;
#Data
public class Region {
private String country;
private List<String> values;
public Region(String country, List<String> values) {
this.country = country;
this.values = values;
}
}

Related

How to use Jackson for parse object follow json type?

I have two Json objects like :
Object 1
{
"value": {
"data": [
"John",
"Justin",
"Tom"
],
"isGraduated": false
}
}
Object 2
{
"value": {
"data": {
"info": {
"background": {
"primarySchool" : "A school",
"univeristy": "X univeristy"
},
"name": "John",
"gender": "male",
"dayOfBirth": "1995-04-24"
}
},
"isGraduated": false
}
}
How can I deserialize the data field to list of strings or class(I've already declared) by using Jackson?
Edit
Add class Info declaration.
public class Info {
#JsonProperty("background")
private BackGround backGround;
#JsonProperty("name")
private String name;
#JsonProperty("gender")
private String gender;
#JsonProperty("dayOfBirth")
private String dayOfBirth;
public static class BackGround {
#JsonProperty("primarySchool")
private String primarySchool;
#JsonProperty("univeristy")
private String univeristy;
}
}
Looking at your JSON objects, there is no way you can figure out what will be there in data parameter. So you can use JsonNode as type for data parameter.
Note: This is the object hierarchy I have created to represent JSON objects
#ToString
class Wrapper {
private Value value;
// getter & setter
}
#ToString
class Value {
private JsonNode data;
private Boolean isGraduated;
// getter & setter
}
#ToString
class Data {
private Info info;
// getter & setter
}
#ToString
class Info {
private Background background;
private String name;
private String gender;
private String dayOfBirth;
// getter & setter
#ToString
static class Background {
private String primarySchool;
private String univeristy;
// getter & setter
}
}
Then you can check the node type before deserialize between List<String> and Info.calss like this,
JsonNodeType type = value.getValue().getData().getNodeType();
You will see type = JsonNodeType.ARRAY if the json object is type 1 and type = JsonNodeType.OBJECT if the json object is type 2.
Check this exaple,
public class Main {
public static void main(String[] args) throws IOException {
// String s = "{\"value\":{\"data\":[\"John\",\"Justin\",\"Tom\"],\"isGraduated\":false}}";
String s = "{\"value\":{\"data\":{\"info\":{\"background\":{\"primarySchool\":\"A school\",\"univeristy\":\"X univeristy\"},\"name\":\"John\",\"gender\":\"male\",\"dayOfBirth\":\"1995-04-24\"}},\"isGraduated\":false}}";
ObjectMapper om = new ObjectMapper();
Wrapper wrapper = om.readValue(s, Wrapper.class);
JsonNodeType type = wrapper.getValue().getData().getNodeType();
if (type == JsonNodeType.ARRAY) {
List<String> data = om.convertValue(wrapper.getValue().getData(), new TypeReference<List<String>>() {});
System.out.println(data);
} else if (type == JsonNodeType.OBJECT) {
Data data = om.convertValue(wrapper.getValue().getData(), Data.class);
System.out.println(data);
}
}
}
Not the general approach but approach for your specific case
ObjectMapper mapper = new ObjectMapper();
ObjectNode root = (ObjectNode) mapper.readTree(jsonContent);
JsonNode data = root.get("value").get("data");
if (data.has("info")) {
Info result = mapper.convertValue(data.get("info"), Info.class);
// handle result as Info instance
} else {
List<String> result = mapper.convertValue(data, new TypeReference<List<String>>() {});
// handle result as list of strings
}

Spring Boot - Get Data from DB and store it in list and parse it to JSON using jackson

I'm trying to get data from multiple tables and put it in Array List of class, and then convert it to JSON Object.
But when i'm trying to parse it to json using Jackson Object Mapper all the lists are converted as below
Using ObjectMapper().writeValueAsString for deserialization from class objects to json
```{
"College": [
{
"institution": [
{
"instId": "T34",
"Country": "India",
"Code": "T33"
},
{
"instId": "T22",
"Country": "India",
"Code": "T22"
}
],
"Rating": [
{
"star": "4"
"comments": "good"
},
{
"star": "2"
"comments": "ok"
},
}
]
}```
But i want the result as below
{
"College": [
{
"institution": [
{
"instId": "T34",
"Country": "India",
"Code": "T33"
}
],
"Rating": [
{
"star": "4"
"comments": "good"
}
]
},
{
"institution": [
{
"instId": "T22",
"Country": "India",
"Code": "T22"
}
],
"Rating": [
{
"star": "2"
"comments": "ok"
}
]
}
]
}
The above is just an example.
Please help in getting the desired output.
Below are the class files used.
public class AllCollege{
List<College> college = new ArrayList<>();
public List<College> getCollege() {
return college;
}
public void setCollege(List<College> college) {
this.college = college;
}
}
public class College{
private List<Institution> institution = new ArrayList<>();
private List<Rating> rating = new ArrayList<>();
public List<Institution> getInstitution() {
return institution;
}
public void setInstitution(List<Institution> institution) {
this.institution = institution;
}
public List<Rating> getRating() {
return rating;
}
public void setRating(List<Rating> rating) {
this.rating = rating;
}
}
public class Institution {
private String instId;
private String country;
private String code;
public String getInstId() {
return instId;
}
public void setInstId(String instId) {
this.instId = instId;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
}
public class Rating {
private String star;
private String comments;
public String getStar() {
return star;
}
public void setStar(String star) {
this.star = star;
}
public String getComments() {
return comments;
}
public void setComments(String comments) {
this.comments = comments;
}
}
Below is where the data from tables is set into ArrayList and then converted to json string.
session = sessionFactory.openSession();
String sql = "from institution";
Query<InstDto> query = session.createQuery(sql);
List<Institution> configdtoList =query.list();
College alc = new College();
alc.setInstitution(configdtoList);
.
.
.
similarly Rating table.
List<College> clist = new new ArrayList<>();
clist.add(alc);
AllCollege ac = new AllCollege();
ac.setCollege(clist);
String responseJson = new ObjectMapper().writeValueAsString(ac)
class structure as below it will help you to parse:
public class Sample {
#JsonProperty("College")
private List<College> college;
}
public class College {
private List<Institution> institution;
#JsonProperty("Rating")
private List<Rating> rating;
}
public class Rating {
private String comments;
private String star;
}
public class Institution {
#JsonProperty("Code")
private String code;
#JsonProperty("Country")
private String country;
private String instId;
}
I have created an HashMap contains the List<AllCollege> as value and then used json parser which worked as expected.

Find Distinct Embedded Document and further make distinct using Field

I'm using Spring Boot Mongo example. I went through many links like: I want result with distinct value of one field from mongodb using spring data, but still did not get any break through. I am using below code:
List<Object> obj = mongoTemplate.query(Health.class).distinct("healths").all();
List<Health> healths = null;
if (!CollectionUtils.isEmpty(obj)) {
healths = obj.stream().map(e -> (Health) e).collect(Collectors.toList());
}
With this code I am getting duplicate HealthCode=E, Is there any way if I can take decision with the healthCd field ? Note: healths is embedded document within Patient document.
Response:
[
{
"healthCd": "D",
"healthName": "ABC",
"effDate": "2012-08-24T07:16:33"
},
{
"healthCd": "C",
"healthName": "MONO",
"effDate": "2012-08-24T07:16:33"
},
{
"healthCd": "E",
"healthName": "BONO",
"effDate": "2012-08-24T07:16:33"
},
{
"healthCd": "B",
"healthName": "JOJO",
"effDate": "2012-08-24T07:16:33"
},
{
"healthCd": "A",
"healthName": "KOKO",
"effDate": "2012-08-24T07:16:33"
},
{
"healthCd": "1",
"healthName": "LULU",
"effDate": "2012-08-24T07:16:33"
},
{
"healthCd": "E",
"healthName": "BOBO",
"effDate": "2014-07-26T22:37:49"
}
]
Health
#Data
#Builder
#NoArgsConstructor
#AllArgsConstructor
public class Health {
#Field
private String healthCd;
#Field
private String healthName;
#Field
private LocalDateTime effDate;
}
You may use MongoBD aggregation to get desired result (Take a look):
db.health.aggregate([
{
$sort: {
"healths.effDate": 1
}
},
{
$group: {
_id: "$healths.healthCd",
healths: {
$first: "$healths"
}
}
},
{
$replaceRoot: {
newRoot: "$healths"
}
}
])
MongoPlayground
Spring Boot Implementation
package com.example.demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
#SpringBootApplication
public class DemoApplication implements CommandLineRunner {
#Autowired
private MongoTemplate mongoTemplate;
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
#Override
public void run(String... args) throws Exception {
// //If your operator is not available inside Aggregation or query is too complex,
// //use below code to write MongoDB shell code directly as JSON
// new AggregationOperation() {
//
// #Override
// public Document toDocument(AggregationOperationContext context) {
// return new Document("$group",
// new Document("_id", "$healths.healthCd")
// .append("healths", new Document("$first", "$healths")));
// }
//
// },
Aggregation agg = Aggregation.newAggregation(
Aggregation.sort(Direction.ASC, "healths.effDate"),
Aggregation.group("healths.healthCd").first("healths").as("healths"),
Aggregation.replaceRoot("healths")
);
AggregationResults<Healths> healths = mongoTemplate.aggregate(agg,
mongoTemplate.getCollectionName(Health.class), Healths.class);
for (Healths health : healths.getMappedResults()) {
Gson gson = new GsonBuilder().setPrettyPrinting().create();
System.out.println(gson.toJson(health));
}
}
}

restful webservice get list of objects

My rest webservice returns the following output:
{
"result": {
"TICKET1": {
"number": "TICKET1",
"description": "aa"
},
"TICKET2": {
"number": "TICKET2",
"description": "dd"
}
}
}
To convert this into a list of Tickets I tried as below.
class TicketResponse {
private List<Ticket> result;
// Get Set
}
class Ticket {
private String number;
private String description;
// Get Set
}
TicketResponse response = restTemplate.getForObject(WEB_SERVICE_URL, TicketResponse.class);
But I get response as null. How to do this.
I'll provide two ways to do with the JSON structure you have.
Option 1:
Modify your TicketResponse class like below:
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
public class TicketResponse {
#JsonProperty("result")
private Map<String, Ticket> ticketsMap = new HashMap<>();
#JsonAnySetter
public void setUnknownField(String name, Ticket value) {
ticketsMap.put(name, value);
}
#JsonIgnore private List<Ticket> ticketsList;
public List<Ticket> getTicketsList() {
return ticketsMap.entrySet().stream().map(Entry::getValue).collect(Collectors.toList());
}
}
then you can get your list of tickets from:
response.getTicketsList();
Option 2:
Read your response in to a String
String response = restTemplate.getForObject(WEB_SERVICE_URL, String.class);
and use below code to convert it to a List<Ticket>
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonNode = mapper.readTree(response);
JsonNode wantedJsonNode = jsonNode.get("result");
Map<String, Ticket> map =
mapper.convertValue(wantedJsonNode, new TypeReference<Map<String, Ticket>>() {});
List<Ticket> tickets =
map.entrySet().stream().map(Entry::getValue).collect(Collectors.toList());
The object you provided doesn't contain a list/array, which would be inside square brackets, like this:
{
"result": {
"tickets": [
{
"number": "TICKET1",
"description": "aa"
},
{
"number": "TICKET2",
"description": "dd"
}
]
}
}
Change your service if possible to return a list/array. Otherwise what you have is an object with individual fields named TICKET1 and TICKET2, so you'll need a field for each.
TicketResponse must have a structure that corresponds to response of the service.
You can change your TicketResponse class and add getTicketArray method:
public class TicketResponse {
private Map<String,Ticket> result;
// getter setter
public List<Ticket> getTicketsAsArray(){
return new ArrayList<Ticket>(result.values());
}
}

Get data as a JSON format in spring boot

I want to build a request endepoints using spring boot: I have to consume restful api and convert that into another rest endpoint.
I have a json Response on www.exampleapiurl.com/details
[{
"name": "age",
"value": "Child"
},
{
"name": "recommendable",
"value": true
},
{
"name": "supported",
"value": yes
},
]
[{
"name": "age",
"value": "Adult"
},
{
"name": "recommendable",
"value": true
},
{
"name": "supported",
"value": no
},
]
I want the response to be:
[{
"age": "Child"
},
{
"recommendable": true
},
{
"supported": "yes"
},
]
[{
"age": "Adult"
},
{
"recommendable": true
},
{
"supported": "no"
},
]
For this I have a attribute class with getter and setter:
Attributes.class
#JsonIgnoreProperties(ignoreUnknown = true)
public class Attributes {
private String age;
private boolean recommendable;
private String supported;
getter and setter for these:
}
This is my service.java class
#Service
public class CService {
private static RestTemplate restTemplate;
public String url;
#Autowired
public CService(String url) {
this.url = url;
}
public Attributes getAttributes() {
HttpHeaders headers= new HttpHeaders();
headers.add("Authorization", "some value");
HttpEntity<String> request = new HttpEntity<String>(headers);
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, request, Attributes.class);
return response.getBody();
}
}
And this is my controller.class
#Controller
public class CController {
private CService cService;
#Autowired
public CController(CService cService) {
this.cService = cService;
}
#RequestMapping(value="/example")
#ResponseBody
public Attributes getCAttributes() {
return cService.getAttributes(); }
}
The Authorization is successful but,
I am not getting any response for now
What you can do is create a model class to recive the response from example API
as follows.
#JsonIgnoreProperties(ignoreUnknown = true)
public class Details{
private String name;
private String value;
#JsonProperty("value")
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
#JsonProperty("name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Then change your invoking RestTemplate code as follows
Details[] details = null;
//Keeps the example API's data in array.
ResponseEntity<Details[]> response = restTemplate.exchange(url, HttpMethod.GET, request, Details[].class);
details = response.getBody();
//Next step is to process this array and send the response back to your client
List<Attributes> attributes = new ArrayList<Attributes>();
Attributes attr = null;
for(Details detail : details) {
attr = new Attributes();
//set the values here
}
//returns the attributes here
attributes.toArray(new Attributes[attributes.size()]);

Resources