Grouping by and create Json in Java efficiently - json

Below is the pojo holding data
class user{
private string userId;
private string role;
private string accessCode;
}
From DB I am getting the below response as one user can have multiple accessCode
"data": [
{
"userId": "userId1",
"role": "admin",
"accesscode": "000008"
},
{
"userId": "userId1",
"role": "admin",
"accesscode": "000007"
},
{
"userId": "userId2",
"role": "analyst",
"accesscode": "000001"
}
]
Expected output as Final Json from rest endpoint
"data": [
{
"userId": "userId1",
"role": "admin",
"accesscode": "000008","000007" // group all access code.
}
{
"userId": "userId2",
"role": "analyst",
"accesscode": "000001"
}
]
What is the best way to achieve this. Any pointers

Here is one way to do it, without using POJOs:
String input = "{" +
" \"data\": [\n" +
" {\n" +
" \"userId\": \"userId1\",\n" +
" \"role\": \"admin\",\n" +
" \"accesscode\": \"000008\"\n" +
" },\n" +
" {\n" +
" \"userId\": \"userId1\",\n" +
" \"role\": \"admin\",\n" +
" \"accesscode\": \"000007\"\n" +
" },\n" +
" {\n" +
" \"userId\": \"userId2\",\n" +
" \"role\": \"analyst\",\n" +
" \"accesscode\": \"000001\"\n" +
" }\n" +
" ]\n" +
"}";
ObjectMapper mapper = new ObjectMapper();
Map<String, List<Map<String, String>>> data = mapper.readValue(input,
new TypeReference<Map<String, List<Map<String, String>>>>() {/**/});
Map<String, List<Map<String, Object>>> combinedData = new HashMap<>();
combinedData.put("data", data.get("data").stream()
.collect(Collectors.groupingBy(
u -> Arrays.asList(u.get("userId"), u.get("role")),
Collectors.mapping(u -> u.get("accesscode"), Collectors.toList())))
.entrySet().stream()
.map(e -> {
Map<String, Object> user = new LinkedHashMap<>();
user.put("userId", e.getKey().get(0));
user.put("role", e.getKey().get(1));
user.put("accesscode", e.getValue());
return user;
})
.collect(Collectors.toList()));
String output = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(combinedData);
System.out.println(output);
Output
{
"data" : [ {
"userId" : "userId2",
"role" : "analyst",
"accesscode" : [ "000001" ]
}, {
"userId" : "userId1",
"role" : "admin",
"accesscode" : [ "000008", "000007" ]
} ]
}

Related

how to use other class object instead of ObjectMapper and remove the type value from Array json

My Code
public static void main(String[] args) throws JsonMappingException, JsonProcessingException {
String data = "{\r\n"
+ " \"id\":\"124\",\r\n"
+ " \"type\":\"MY\",\r\n"
+ " \"tank\": {\r\n"
+ " \"type\": \"py\",\r\n"
+ " \"object\": \"id007\",\r\n"
+ " \"time\": \"12:30\",\r\n"
+ " \"providedBy\": {\r\n"
+ " \"type\": \"py\",\r\n"
+ " \"object\": \"id009\"\r\n"
+ " }\r\n"
+ " },\r\n"
+ " \"fruit\": [\r\n"
+ " {\r\n"
+ " \"type\": \"py\",\r\n"
+ " \"object\": \"sweet\"\r\n"
+ " },\r\n"
+ " {\r\n"
+ " \"type\": \"py\",\r\n"
+ " \"object\": \"sweet\"\r\n"
+ " }\r\n"
+ " ] \r\n"
+ " }";
ObjectMapper mapper = new ObjectMapper();
JsonNode nodes = mapper.readTree(data);
Iterator<Entry<String, JsonNode>> iterator = nodes.fields();
while (iterator.hasNext()) {
Entry<String, JsonNode> node = iterator.next();
remove(node.getValue());
}
System.out.println(nodes.toString());
}
public static void remove(JsonNode node) {
if (node.hasNonNull("type")) {
((ObjectNode) node).remove("type");
}
Iterator<Entry<String, JsonNode>> iterator = node.fields();
while (iterator.hasNext()) {
Entry<String, JsonNode> childnode = iterator.next();
if (childnode.getValue().isObject()) {
reduceJson(node.get(childnode.getKey()));
}
}
}
input data
{
"id":"124",
"type":"MY",
"tank": {
"type": "py",
"object": "id007",
"time": "12:30",
"providedBy": {
"type": "py",
"object": "id009"
}
},
"fruit": [
{
"type": "py",
"object": "sweet"
},
{
"type": "py",
"object": "sweet"
}
]
}
using above code when I am trying to get id 124.
** {
"id":"124",
"type":"MY",
"tank": {
"type": "py",
"object": "id007",
"time": "12:30",
"providedBy": {
"type": "py",
"object": "id009"
}
},
"fruit": [
{
"type": "py",
"object": "sweet"
},
{
"type": "py",
"object": "sweet"
}
]
}**
I want to get id 124 to data representation should be like this.
{
"id":"124",
"type":"MY",
"tank": {
"object": "id007",
"time": "12:30",
"providedBy": {
"object": "id009"
}
},
"fruit": [
{
"object": "sweet"
},
{
"object": "sweet"
}
]
}
so guide me where should I put logic to get response Like this

Skip double quotes using JSON path [duplicate]

This question already has answers here:
Getting a single value from a JSON object using JSONPath
(4 answers)
Closed 3 years ago.
I have following JSON
{
"firstName": "John",
"lastName" : "doe",
"age" : 26,
"address" : {
"streetAddress": "naist street",
"city" : "Nara",
"postalCode" : "630-0192"
},
"phoneNumbers": [
{
"type" : "iPhone",
"number": "0123-4567-8888"
},
{
"type" : "home",
"number": "0123-4567-8910"
}
]
}
and $.phoneNumbers[:1].type json path to extract phone number type iPhone value but the output is
[
"iPhone"
]
I would like to get it as simple string like iPhone. How do i create the JSON path to strip double quote " and [ ?
You cannot remove [ & " directly from JSON Path, However, you can use this replace function given here https://community.apigee.com/questions/63281/how-to-remove-square-bracket-and-double-quotes-fro.html
var extracted_json = ["vIMS"]; // use context.getVariable("<<extracted-variable>>");
modifiedJson = JSON.stringify(extracted_json).replace(/[\[\]"]+/g,"");
context.setVariable("final-variable", modifiedJson)
By default, using JsonPath to process JSON means you will get the result as a JSONArray. So, you have to make one more step to get the desired result.
For example,
#Test
public void test() {
String json = "{\n" +
" \"firstName\": \"John\",\n" +
" \"lastName\" : \"doe\",\n" +
" \"age\" : 26,\n" +
" \"address\" : {\n" +
" \"streetAddress\": \"naist street\",\n" +
" \"city\" : \"Nara\",\n" +
" \"postalCode\" : \"630-0192\"\n" +
" },\n" +
" \"phoneNumbers\": [\n" +
" {\n" +
" \"type\" : \"iPhone\",\n" +
" \"number\": \"0123-4567-8888\"\n" +
" },\n" +
" {\n" +
" \"type\" : \"home\",\n" +
" \"number\": \"0123-4567-8910\"\n" +
" }\n" +
" ]\n" +
"}";
net.minidev.json.JSONArray iPhone = JsonPath.parse(json).read("$.phoneNumbers[?(#.type=='iPhone')].type");
System.out.println("Type : " + iPhone.get(0).toString());
}
, will eventually print Type : iPhone

How get response on get request in JSON format using Rest Assured

I need get data in JSON format on get request, data should be the following format:
{
"birth_date": "1980-01-01",
"birth_place": "",
"sex": "",
"inn": "",
"snils": "",
"rezident": "0",
"depend_count": null,
"name": {
"surname": "Заноза",
"name": "Заноза",
"patronymic": "Заноза"
}
}
But data is returned in the following form, response as string:
{
"birth_date" : "1980-01-01"
,
"birth_place" : ""
,
"sex" : ""
,
"inn" : ""
,
"snils" : ""
,
"rezident" : "0"
,
"depend_count" : null,
"name" : {
"surname" : "\u0417\u0430\u043D\u043E\u0437\u0430"
,
"name" : "\u0417\u0430\u043D\u043E\u0437\u0430"
,
"patronymic" : "\u0417\u0430\u043D\u043E\u0437\u0430"
}
}
Code:
public static String getClientInfo(String clientId) {
String response = given().
param("id", clientId).
when().get("/services/clients").
then().assertThat().statusCode(200).and().
extract().body().asString();
System.out.println("Response = " + response);
return response;
}
How get JSON format on get request using Rest-Assured?
Below snippet might help you.
public static String getClientInfo(String clientId) {
Response response = given().
param("id", clientId).
when().get("/services/clients");
response.then().assertThat().statusCode(200);
System.out.println("Non pretty Response : " + response.body().asString());
System.out.println("Pretty Response : " + response.prettyPrint().toString());
return response.prettyPrint().toString().replace("\\", "");
}

Groovy: Why the node is returning null

I wanted to add my json response values to an array. My groovy script,
import groovy.json.*
def ResponseMessage = '''{
"Unit": {
"Screen": [{
"Profile ": {
"ID ": 12,
"Rate ": 0
},
"Rate ": 600,
"Primary ": 1,
"Audio ": [{
"Id ": 1,
"Name ": null
}],
"Pre ": 5,
"Post ": 1
}]
}
} '''
def json = new JsonSlurper().parseText(ResponseMessage)
def Screen = json.Unit.Screen
log.info Screen
def array= []
Screen.each { s ->
array.addAll(s.Rate,s.Primary,s.Pre)
log.info "array : " + array
}
Array is returning,
INFO:array : [null, null, null]
Instead of the "create an array, call addAll in a loop" pattern, try this:
def array = Screen.collectMany { s ->
[s.Rate,s.Primary,s.Pre]
}
(Of course, once you've removed the spaces from your JSON keys)

Avro Pair Schema In JSON Format

I'm fairly familiar with creating Avro pair schemas in Java. For example,
static final String RECORD_STRING =
"{\n" +
" \"type\": \"record\",\n" +
" \"name\": \"exampleRecord1\",\n" +
" \"fields\": [\n" +
" {\"name\": \"id\", \"type\": \"string\"}\n" +
"]\n" +
"}";
static{
final Schema.Parser parser = new Schema.Parser();
Schema KEY_SCHEMA = parser.parse(RECORD_STRING);
Schema VALUE_SCHEMA = Schema.create(Schema.Type(STRING)) ;
Schema PAIR_SCHEMA = Pair.getPairSchema(KEY_SCHEMA, VALUE_SCHEMA);
}
How would I go about writing this Pair Schema directly as JSON in a file without using any Java?
The Schema class has a toString() method that does what you want:
import org.apache.avro.Schema;
import org.apache.avro.mapred.Pair;
public class Test
{
static final Schema PAIR_SCHEMA;
static final String RECORD_STRING =
"{\n" +
" \"type\": \"record\",\n" +
" \"name\": \"exampleRecord1\",\n" +
" \"fields\": [\n" +
" {\"name\": \"id\", \"type\": \"string\"}\n" +
"]\n" +
"}";
static
{
final Schema.Parser parser = new Schema.Parser();
Schema KEY_SCHEMA = parser.parse( RECORD_STRING );
Schema VALUE_SCHEMA = Schema.create( Schema.Type.STRING );
PAIR_SCHEMA = Pair.getPairSchema( KEY_SCHEMA, VALUE_SCHEMA );
}
public static void main( String[] args )
{
System.out.println( PAIR_SCHEMA.toString(true) );
}
}
Here's the output:
{
"type" : "record",
"name" : "Pair",
"namespace" : "org.apache.avro.mapred",
"fields" : [ {
"name" : "key",
"type" : {
"type" : "record",
"name" : "exampleRecord1",
"namespace" : "",
"fields" : [ {
"name" : "id",
"type" : "string"
} ]
},
"doc" : ""
}, {
"name" : "value",
"type" : "string",
"doc" : "",
"order" : "ignore"
} ]
}