I'm trying to build a JSON object in my servlet.
The object should look like this:
{
"firms": [
{
"name": "firm1",
"projects": [
{
"name": "firm1project1"
},
{
"name": "firm1project2"
},
{
"name": "firm1project3"
}
]
},
{
"name": "firm2",
"projects": [
{
"name": "firm2project1"
},
{
"name": "firm2project2"
},
{
"name": "firm2project3"
}
]
},
{
"name": "firm3",
"projects": [
{
"name": "firm3project1"
},
{
"name": "firm3project2"
},
{
"name": "firm3project3"
}
]
},
{
"name": "firm4",
"projects": [
{
"name": "firm4project1"
},
{
"name": "firm4project2"
},
{
"name": "firm4project3"
}
]
}
]
}
I have a problem in creating array of project names objects:
[
{
"name": "firm2project1"
},
{
"name": "firm2project2"
},
{
"name": "firm2project3"
}
]
Right now I have the code as showed below (oJsonInner is a JSONObject object, aProjects - ArrayList of JSONObject type). I build the oJsonInner object from the results I get from database query:
while(result.next()){
oJsonInner.put("name",result.getString("project_name"));
aProjects.add(oJsonInner);
}
Is there any way to get the value of the oJsonInner object in aProjects.add(oJsonInner); so during the next loop I could create a new oJsonInner object with different "project_name" value without updating the object that got into aProjects array during the first loop?
while(result.next()){
oJsonInner = new JsonObject();
oJsonInner.put("name",result.getString("project_name"));
aProjects.add(oJsonInner);
}
you can use a JSONArray object and add it JSON object.
while(result.next()){
JSONObject oJsonInner = new JSONObject();
JSONArray arr = new JSONArray();
json.put("name",result.getString("project_name"));
arr.put(json);
}
Try this method:
ArrayList<JSONObject> aProjects = new <JSONObject>ArrayList();
while(result.next()){
JSONObject oJsonInner = new JSONObject();
oJsonInner.put("name","project1");
aProjects.add(oJsonInner);
}
RESULT:
[{"name":"project1"}, {"name":"project2"}]
Use Gson lib that help you to serialize json format which take java bean and convert it to json format.
Model
public class Firm {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
private List<Project> projetcts;
public List<Project> getProjetcts() {
return projetcts;
}
public void setProjetcts(List<Project> projetcts) {
this.projetcts = projetcts;
}
public static class Project{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
Gson code
public static void main(String[] args) {
Firm [] firms = new Firm[2];
Project p1 = new Project();
p1.setName("project 1");
Project p2 = new Project();
p2.setName("project 2");
Project p3 = new Project();
p3.setName("project 3");
List<Project> projects = new ArrayList<Firm.Project>();
projects.add(p1);
projects.add(p2);
projects.add(p3);
Firm firm1 = new Firm();
firm1.setName("firm1");
firm1.setProjetcts(projects);
Firm firm2 = new Firm();
firm2.setName("firm2");
firm2.setProjetcts(projects);
firms[0] = firm1;
firms[1] = firm2;
String jsonText = new Gson().toJson(firms);
System.out.println(jsonText);
}
Result Sample
[{"name":"firm1","projetcts":[{"name":"project 1"},{"name":"project
2"},{"name":"project
3"}]},{"name":"firm2","projetcts":[{"name":"project
1"},{"name":"project 2"},{"name":"project 3"}]}]
Check this solution, it may satisfy your expectations:
https://stackoverflow.com/a/74174150/2609399
UPDATE:
In your case, the needed JSON object can be created like so (note that actual key-value lines can be imported from external files or other sources like socked, db and so on):
System.out.println(
JsonBuilder.of()
.add("[0].name", "firm2project1")
.add("[1].name = firm2project2")
.add("[2].name: \"firm2project3\"")
.build()
.toPrettyString()
);
, which results to:
[
{
"name": "firm2project1"
},
{
"name": "firm2project2"
},
{
"name": "firm2project3"
}
]
Related
I'm not fluent in API testing hence my question. I have a body to POST (mock) that will consist of:
{
"request":
{
"urlPath": "path/to/",
"method": "POST",
"bodyPatterns":[{
"equalToJson" : "{\n\"query\": [\n{\n\"name\": \"name1\",\n\"value\": \"123\"\n },\n{\n\"name\": \"name2\",\n\"value\": \"345\"\n},\n{\n\"name\": \"name3\",\n\"value\": \"someName\"\n}\n],\n\"anotherItem\": [],\n\"side\": 77,\n\"pageSize\": 44\n}", "jsonCompareMode": "LENIENT"
}]
},
"response":
{
"status": 200,
"headers":
{
"Content-Type" : "application/json"
},
"body": "{"items\": [\n{\n\"item\": 1,\n
\"item2\": 2,\n
etc
"\n}\n]\n}"
}
}
I want to use some pojo classes to separately create Request and Response:
public Request initRequest() {
BodyPattern bodyPat = new BodyPattern();
Query query = new Query();
Query query2 = new Query();
Query query3 = new Query();
EqualToJson equalToJ = new EqualToJson();
query.setName("name1");
query.setValue("123");
query2.setName("name2");
query2.setValue("345");
query3.setName("name2");
query3.setValue("someName");
List<Query> queryList = new ArrayList<>();
queryList.add(query);
queryList.add(query2);
queryList.add(query3);
equalToJ.setQuery(queryList);
List<Filter> filtersList = new ArrayList<>();
equalToJ.setFilter(filtersList);
equalToJ.setSide(77);
equalToJ.setPageSize(44);
List<EqualToJson> eqList = new ArrayList<>();
eqList.add(equalToJ);
req.setUrlPath(URL + "/Test001");
req.setMethod("POST");
bodyPat.setEqualToJson(eqList);
bodyPat.setJsonCompareMode("LENIENT");
List<BodyPattern> bodyPatList = new ArrayList<>();
bodyPatList.add(bodyPat);
req.setBodyPatterns(bodyPatList);
return req;
}
To see it in more user-friendly view, here you go:
{
"request": {
"urlPath": "/path/to",
"method": "POST",
"bodyPatterns": [
{
"equalToJson": {
"query": [
{
"name": "name1",
"value": "123"
},
{
"name": "name2",
"value": "345"
},
{
"name": "name3",
"value": "someName"
}
],
"filter": [
],
"side": 77,
"pageSize": 44
},
"jsonCompareMode": "LENIENT"
}
]
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"body": {
"side": 77,
"pageSize": 44,
"items": [
{
"name1": "123",
"name2": "345",
"name3": "someName"
etc...
}
]
}
}
}
Similarly, I do with Response.
My question is, how can I make to have just a part of this json (BodyPatters) as escaped signs? Mock is created this way that it only accepts escaped characters in this part of json.
I can of course hardcode this payload, but I want to have control over those fields' values and steer them, as parameters.
I really have no idea how to handle this.
You can use objectmapper of jackson to convert Object to String. For example:
void name2() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
Query query = new Query("name1", "123");
EqualToJson equalToJson = new EqualToJson();
equalToJson.setQuery(Arrays.asList(query));
BodyPattern bodyPattern = new BodyPattern();
bodyPattern.setEqualToJson(mapper.writeValueAsString(equalToJson));
String bodyPatternText = mapper.writerWithDefaultPrettyPrinter()
.writeValueAsString(bodyPattern);
System.out.println(bodyPatternText);
}
#Data
#AllArgsConstructor
static class Query{
private String name;
private String value;
}
#Data
static class EqualToJson {
private List<Query> query;
}
#Data
static class BodyPattern {
private String equalToJson;
}
This is a result:
{
"equalToJson" : "{\"query\":[{\"name\":\"name1\",\"value\":\"123\"}]}"
}
I am very new to json, How can I make a JSON object the structure (output string)would be like this? I am using the org.json library.
Is this a json array contians json array?
I have input like this:
111(root)
----222(child of 111)
--------333(child of 222)
--------444(child of 222)
----123(child of 111)
--------456(child of 123)
--------456(child of 123)
How can I make a json the output would be like blow,
{
"name": "flare",
"children": [
{
"name": "analytics",
"children": [
{
"name": "cluster",
"children": [
{
"name": "AgglomerativeCluster",
"value": 3938
},
{
"name": "CommunityStructure",
"value": 3812
}
]
},
{
"name": "graph",
"children": [
{
"name": "BetweennessCentrality",
"value": 3534
},
{
"name": "LinkDistance",
"value": 5731
}
]
}
]
},
{
"name": "animate",
"children": [
{
"name": "Easing",
"value": 17010
},
{
"name": "FunctionSequence",
"value": 5842
}
]
}
]
}
Thanks for you help!
You can change your dependency and use a library that allows Object mapping such as Jackson, or you can do the mapping by hand as follows:
private static JSONObject toJSONObject(String name, Object value) {
JSONObject ret = new JSONObject();
ret.put("name", name);
if (value != null) {
ret.put("value", value);
}
return ret;
}
public static JSONObject addChildren(JSONObject parent, JSONObject... children) {
parent.put("children", Arrays.asList(children));
return parent;
}
public static void main(String[] sargs) {
JSONObject flare = toJSONObject("flare", null);
addChildren(flare,
addChildren(toJSONObject("analytics", null),
addChildren(toJSONObject("cluster", null),
toJSONObject("AgglomerativeCluster", 3938),
toJSONObject("CommunityStructure", 3812)
),
addChildren(toJSONObject("graph", null),
toJSONObject("BetweennessCentrality", 3534),
toJSONObject("LinkDistance", 5731)
)
),
addChildren(toJSONObject("animate", null),
toJSONObject("Easing", 17010),
toJSONObject("FunctionSequence", 5842)
)
);
System.out.println(flare.toString());
}
You can simply have class like this.
public class Node {
String name;
List<Node> children;
String value;
}
This can be achieved by ObjectMapper's pretty print.
public String pretty(Object object) throws JsonProcessingException {
return OBJECT_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(object);
}
You may use my library for it.
<dependency>
<artifactId>json-utils</artifactId>
<groupId>org.bitbucket.swattu</groupId>
<version>1.0.16</version>
</dependency>
new JsonUtil().pretty(object);
String jsonResponse=Utils.getGsonInstance().toJson(Object);
jsonResponse returns :
[
{
"Key":"1",
"Code": "11",
},
{
"key":"2",
"code": "22",
}
]
End result I am looking for is to wrap this JSON-String in another Key E.g.
{
"MainObj":
[
{
"Key":"1",
"Code": "11",
},
{
"key":"2",
"code": "22",
}
]
}
Is there a way I can achieve this using GSON Api ?
I tried ::
JSONObject jsonObject = new JSONObject();
jsonObject.put("MainObj",jsonResponse);
Output I am getting is :
{"MainObj": "[{\"Key\":\"1",\"Code\":\"11\"}, {\"Key\":\"2",\"Code\":\"22\"}]"}
Continue with GSON like :
public class MainObj {
#SerializedName("MainObj")
public List<Key> Main;
public class Key {
#SerializedName("Key")
public String Key;
#SerializedName("code")
public String Code;
}
}
And change
JSONObject jsonObject = new JSONObject();
jsonObject.put("MainObj",jsonResponse);
by
String tmp = new Gson().toJson(new MainObj());
{"myContainer" :
{ "couldBeAnything" : [
{"id":1, "name":"sb", "category":"couldBeAnything"},
{"id":2, "name":"bs", "category":"couldBeAnything"}
],
"somethingElse" : [
{"id":1, "name":"sdsa","category":"somethingElse"},
{"id":2, "name":"ve","category":"somethingElse"}
]
},
"id" : 0
}
So far I have :
Type myContainerType = new TypeToken<MyContainer>(){}.getType();
MyContainerType myContainerType = gson.fromJson(myJson.getValue(), myContainerType);
Where
public class MyContainer {
private int id;
private Map<String, List<Foo>> foo; // and foo has id, name, category
The result, no errors, a populated id field, but just a null map
I think the json is wrong for the structure Map<String, List<Foo>>. When you say map you need not enclose each key-value with {. Just put the whole key values in one {} and seprate with commas. eg
{
"myContainer": {
"couldBeAnything": [
{
"id": 1,
"name": "sb",
"category": "couldBeAnything"
},
{
"id": 2,
"name": "bs",
"category": "couldBeAnything"
}
],
"somethingElse": [
{
"id": 1,
"name": "sdsa",
"category": "somethingElse"
},
{
"id": 2,
"name": "ve",
"category": "somethingElse"
}
]
},
"id": 0
}
With this json it works perfectly
public static void main(String[] args){
String json = "{\"myContainer\":{\"couldBeAnything\":[{\"id\":1,\"name\":\"sb\",\"category\":\"couldBeAnything\"},{\"id\":2,\"name\":\"bs\",\"category\":\"couldBeAnything\"}],\"somethingElse\":[{\"id\":1,\"name\":\"sdsa\",\"category\":\"somethingElse\"},{\"id\":2,\"name\":\"ve\",\"category\":\"somethingElse\"}]},\"id\":0}";
Map<String, List<Foo>> obj = new HashMap<String, List<Foo>>();
Gson gson = new Gson();
obj = gson.fromJson(json, obj.getClass());
System.out.println(obj);
}
Output
{id=0.0, myContainer={couldBeAnything=[{id=1.0, name=sb, category=couldBeAnything}, {id=2.0, name=bs, category=couldBeAnything}], somethingElse=[{id=1.0, name=sdsa, category=somethingElse}, {id=2.0, name=ve, category=somethingElse}]}}
The issue with your approach was the naming of the field foo. Your json contains the Map<String, List<Foo>> name as myContainer. So modify your container class like below and it will work fine :)
public class MyContainer {
private int id;
private Map<String, List<Foo>> myContainer;
}
Now this will work
Type myContainerType = new TypeToken<MyContainer>(){}.getType();
MyContainer myContainer = gson.fromJson(json, myContainerType);
System.out.println(myContainer);
Can somebody help me with Gson parser. When I remove change from JSON and Result it works fine but with change it throws JsonParseException-Parse failed.
Result[] response = gson.fromJson(fileData.toString(), Result[].class);
I have classes like this
public class Result {
public String start_time;
public String end_time;
public change[] change;
}
and
public class change {
public String id;
public String name;
}
and Json string like
[
{
"start_time": "8:00",
"end_time": "10:00",
"change": [
{
"id": "1",
"name": "Sam"
},
{
"id": "2",
"name": "John"
}
]
},
{
"start_time": "9:00",
"end_time": "15:00",
"change": [
{
"id": "1",
"name": "Sam"
},
{
"id": "2",
"name": "John"
}
]
}
]
Can somebody tell me what I did wrong ? Any idea why it won't work with array ?
As has been suggested, you need to use a list instead. Gson has pretty good documentation for using parametized types with the parser, you can read more about it here. Your code will end up looking like this:
Type listType = new TypeToken<List<Result>>() {}.getType();
List<Result> results = gson.fromJson(reader, listType);
for (Result r : results) {
System.out.println(r);
}