I'm trying to deserialize an array of json object to array of java Object. I'm using data provider to pass this data combination to test methods so test method executes for each data set.
I've created Data provider method as mentioned below and deserilised the Json:
#DataProvider(name = "listData")
public Object[][] listData() throws FileNotFoundException {
Type listType = new TypeToken<List<DataBean>>() {
}.getType();
List<DataBean> data = new GsonBuilder().create().fromJson(new FileReader("resources/data.json"), listType);
data.forEach(iterator -> System.out.println(iterator.getUsername() + " : : " + iterator.getPassword()));
return new Object[][]{data.toArray()};
}
Test method :
#Test(dataProvider = "jsonData")
public void testdata(DataBean dataBean) {
System.out.println(dataBean.getUsername() + "============" + dataBean.getPassword());
}
and JSON :
[
{
"username": "someuser",
"password": "abc#add"
},
{
"username": "anotheruser",
"password": "daa#add"
}
]
Unfortunately its not working. If i use Strong typed Object like below then its work as expected :
return new Object[][]{{new DataBean("user1", "d121312")},
{new DataBean("user2", "asdsd")}};
Error:
org.testng.internal.reflect.MethodMatcherException: [public void
com.mind.DataProviderUtil.testdata(com.mind.DataBean)] has no
parameters defined but was found to be using a data provider (either
explicitly specified or inherited from class level annotation). Data
provider mismatch Method: testdata([Parameter{index=0,
type=com.mind.DataBean, declaredAnnotations=[]}]) Arguments:
[(com.mind.DataBean) com.mind.DataBean#78b66d36,(com.mind.DataBean)
com.mind.DataBean#5223e5ee]
Can someone please help me int storing List<DataBean> data in Object[][] so my test method execute for each set of data
Data stores in 2-D array in matrix form.
Lets say there is an array of 3x3 then matrix representation would be
1 2 1
3 4 2
1 2 1
As data provider return 2-D array to supply data to Test method for Data Driven test. So need to mention Object[][] with proper size. I've 2 sets of data in JSON file and I'm deserializing to a JAVA object that is DataBean in my case. So here I have to mention sizes as Object[dataBean.size()][1]
Complete Code:
Type listType = new TypeToken<List<DataBean>>() {
}.getType();
List<DataBean> bean = new GsonBuilder().create().fromJson(new FileReader("resources/data.json"), listType);
bean.forEach(iterator -> System.out.println(iterator.getUsername() + " : : " + iterator.getPassword()));
Object[][] data = new Object[bean.size()][1];
for (int i = 0; i < bean.size(); i++) {
data[i][0] = bean.get(i);
}
return data;
Related
I have a for loop which iterates and generates key value pairs for different employees.
I need to create a JSON array like below and write it to a JSON file at the end.
I am having trouble figuring out the ideal way to code it (JSON Objects -> JSON Array -> JSON file?).
I am open to use json-simple/GSON.
Desired JSON file format:
[
{
"employeeFirstName": "Mark",
"employeeLastName": "Williams",
"employeeDepartment": "Sales",
},
{
"employeeFirstName": "John",
"employeeLastName": "Carpenter",
"employeeDepartment": "Accounts",
},
{
"employeeFirstName": "David",
"employeeLastName": "Hunter",
"employeeDepartment": "Marketing",
},
]
I tried using a JSONObject and add it to a JSONArray. But, couldn't figure how to code it for iterations.
My current Java class:
public class Test {
public void createEmployeesJSONArrayFile(ITestContext iTestContext) {
for (ITestResult testResult : iTestContext.getFailedTests().getAllResults()) {
System.out.println("employeeFirstName: " + testResult.getEmployeeFirstName()));
System.out.println("employeeLastName: " + testResult.getEmployeeLastName());
System.out.println("employeeDepartment: " + testResult.getEmployeeDepartment());
}
}
}
What is the simplest or ideal way to achieve this?
A simple way to achieve this would be to use Gson, an API provided by Google. You could write the Collection of ITestResult objects to a file. The toJson function will take the Collection of ITestResult objects and write them to the the given Appenable object, which in this case is a BufferedWriter which points to a file.
(untested, one sec, not at workstation)
Collection<ITestResult> results = iTestContext.getFailedTests().getAllResults();
new GsonBuilder()
.create()
.toJson(results, Files.newBufferedWriter(Paths.get("path", "to", "file")));
If your goal is to write to file eventually, you can also use jackson apis.
ObjectMapper mapper = new ObjectMapper();
//To add indentation to output json
mapper.enable(SerializationFeature.INDENT_OUTPUT);
Collection<ITestResult> results = iTestContext.getFailedTests().getAllResults();
try{
mapper.writeValue(new File("/somepath/output.json"), results);
catch (IOException){
e.printStackTrace();
}
Note: Recommended to use single instance of object mapper
For following snippet:
public static final class Node {
class Employee {
private final String employeeFirstName;
private final String employeeLastName;
private final String employeeDepartment;
public Employee(String employeeFirstName, String employeeLastName, String employeeDepartment) {
this.employeeFirstName = employeeFirstName;
this.employeeLastName = employeeLastName;
this.employeeDepartment = employeeDepartment;
}
}
List<Employee> employees = Arrays.asList(
new Employee("Mark", "Williams", "Sales"),
new Employee("John", "Carpenter", "Accounts"),
new Employee("David", "Hunter", "Marketing"));
// String json = ...
}
Using gson-utils
String json = GsonUtils.writeValue(data);
Using jackson-utils
String json = JacksonUtils.writeValue(data);
I'm super new to Java and am trying to parse JSON and manipulate the data into a final data structure as shown below.
I have this model:
public class StoreInfo {
private String storeName;
private String storeCode;
private List<StoreLocations> locations = new ArrayList<>();
}
Here is the JSON response I get from calling Redis:
redisResult = "[{
storeName: 'Walmart',
storeCode: '0001',
locations: [ [Object] ]
},
{
displayName: 'Wegmans',
storeCode: '0002',
locations: [ [Object] ]
}]"
When I call Redis, I use the keyName groceryStores and the fieldName 1.
I want to have a resulting data structure that looks like this:
groceryStores: { 1 : [
{
storeName: 'Walmart',
storeCode: '0001',
locations: [ [Object] ]
},
{
displayName: 'Wegmans',
storeCode: '0002',
locations: [ [Object] ]
}]
I'm having lots of trouble using Jackson to parse the initial JSON string into the type StoreInfo. When I try the following, I get an exception from Jackson:
StoreInfo[] storeInfoArray = objectMapper.readValue(redisResult, StoreInfo[].class);
I don't understand how I would create an array of StoreInfo objects.
Then, to use the key and field in order to create my final data structure.
I'm super new to Java and I have figured out how to do the latter part in Javascript, but how to do it in Java?
// Assuming the JSON response has been parsed
function addResponse (response, key, field, data) {
response[key] = {}
response[key][field] = data
return response
}
Easiest Option is create a wrapper class for StoreInfo i.e.
class StoreInfoDTO {
List<StoreInfo> storeInfoList;
//getter and setters
}
Now use ObjectMapper as:
StoreInfo[] storeInfoArray = objectMapper.readValue(redisResult,
StoreInfoDTO.class).getStoreInfoList();
Part2, setting the Value in response :
class ResponseDTO {
#JsonProperty("groceryStores")
Map<Integer, List<StoreInfo>> props;
//getter and setters
}
Now to use it :
ResponseDTO responseDTO = new ResponseDTO();
GrosseryStores grosseryStores = new GrosseryStores();
ArrayList<StoreInfo> storeInfos = new ArrayList<StoreInfo>();
storeInfos.add(new StoreInfo("SN1","1234"));
ArrayList<StoreInfo> storeInfos1 = new ArrayList<StoreInfo>();
storeInfos1.add(new StoreInfo("SN2","1236"));
Map<Integer, List<StoreInfo>> map = new HashMap<>();
map.put(1,storeInfos);
map.put(2,storeInfos1);
responseDTO.setProps(map);
I am looking for a way to have a list of returned from a MySQL query, output in JSON with the field names instead of as an array. Here is some sample code:
List list = lookup_mgr.getResults("select someField, anotherField from someTable");
if (list != null) {
String json = new Gson().toJson(list);
}
This pulls a list and creates a JSON array like:
[
["someFieldValue","anotherFieldValue"],
["someFieldValue","anotherFieldValue"]
]
I'd like it to be like:
[
{
someField: "someFieldValue",
anotherField: "anotherFieldValue"]
},
{
someField: "someFieldValue",
anotherField: "anotherFieldValue"]
}
]
I am looking to keep it as simple and fast as possible. How would I go about doing that?
I think what you actually want is this ('{', '}' for objects):
[
{
someField: "someFieldValue",
anotherField: "anotherFieldValue"]
},
{
someField: "someFieldValue",
anotherField: "anotherFieldValue"]
}
]
This represents an array of objects in JSON notation. As opposed to what you currently get (an array of arrays of strings).
And to get that, you should create a Java bean class, that has exactly those two properties (let's call it SomeBean). Iterate over your query results and put the data you need in a List<SomeBean>, then pass that list to new Gson().toJson(list).
You can use JSONObject. Simply put your result into it and return that.
Example -
public JSONObject getResult(){
JSONObject responseJson = new JSONObject();
List<Object> resultList = new ArrayList<Object>();
User user1 = new User();
User user2 = new User();
User user3 = new User();
resultList.add(user1);
resultList.add(user2);
resultList.add(user3);
responseJson.put("result", resultList);
return responseJson;
}
Hope it helps!
Alright. I have a JSON Object sent to me from a server which contains the following data:
{
"result":
[
{"status":"green","type":"data1"},
{"status":"green","type":"data2"},
{"status":"green","type":"data3"}
],
"status":"ok"
}
The data I want to get is the status for the three status values. Data1, data2, and data3 always show up in that order, so I'm now trying to grab the data by index (e.g. data1 = index 0, data2 = index 1, data3 = index 2). How do I do that?
Try following:
String stat1;
String stat2;
String stat3;
JSONObject ret; //contains the original response
//Parse to get the value
try {
stat1 = ret.getJSONArray("results").getJSONObject(0).getString("status");
stat2 = ret.getJSONArray("results").getJSONObject(1).getString("status");
stat3 = ret.getJSONArray("results").getJSONObject(2).getString("status");
} catch (JSONException e1) {
e1.printStackTrace();
}
You would use JSONObject and JSONArray, the entire string is one JSONObject so you would construct one with it.
JSONObject object = new JSONObject(YOUR_STRING_OF_JSON);
Then you can access it with different get methods depending upon your expected type.
JSONArray results = object.getJSONArray("result"); // This is the node name.
String status = object.getString("status");
for (int i = 0; i < results.length(); i++) {
String resultStatus = results.getJSONObject(i).getString("status");
String type = results.getJSONObject(i).getString("type");
Log.w("JSON Result #" + i, "Status: " + resultStatus + " Type: " + type);
}
You need to surround it with a try/catch because JSON access can throw a JSONException.
Try re-factoring via a forEach loop
var testData =
{
"result":
[
{"status":"green","type":"data1"},
{"status":"green","type":"data2"},
{"status":"green","type":"data3"}
],
"status":"ok"
};
var output = new Object;
var resultSet = new Object;
resultSet = testData.result;
resultSet.forEach(function(data)
{
theStatus = data['status'];
theType = data['type']
output[theType] = theStatus;
});
console.log( output['data1'] );
If you've got your models setup to mirror that data set, then you can let GSON (https://code.google.com/p/google-gson/) do a lot of your work for you.
If you want a bit more control, and want to parse the set yourself you can use JSONObject, JSONArray. There's an example of parsing and assembling a json string here: Android create a JSON array of JSON Objects
Is it possible to pass a JavaScript object from JavaScript to Java using addJavascriptInterface()? Something along these lines:
var javaScriptObject = {"field1":"string1", "field2":"string2"};
JavaScriptInterface.passObject(javaScriptObject);
How would such a call be captured on the Java side? I have no problem setting up the interface to send a string, but when I send an object, I receive null on the Java end.
AFAIK, addJavascriptInterface() only works with primitive types and Strings, and so you cannot pass arbitrary Javascript objects.
This is how I am doing...
In Android...
#JavascriptInterface
public void getJSONTData(String jsonData) {
try {
JSONObject data = new JSONObject(jsonData); //Convert from string to object, can also use JSONArray
} catch (Exception ex) {}
}
In JavaScript...
var obj = { Name : 'Tejasvi', Age: 100};
var str = JSON.stringify(obj);
Android.getJSONTData(str);
As of now, I could not find any other proper way to pass the native JavaScript object directly to JavascriptInterface.
Calling Android.getJSONTData({ Name : 'Tejasvi', Age: 100}) results in null (if parameter type is Object) or undefined (if parameter type is defined as String) in getJSONTData.
I found a solution, using JSON. My Java method returns a JSONArray, on my javascript code I receive this and convert to a javascript vector using JSON.parse(). See the example:
Java:
public class JavaScriptInterface {
Context mContext;
private static int ind=-1;
private static int [] val = { 25, 25, 50, 30, 40, 30, 30, 5, 9 };
public JavaScriptInterface(Context c) {
mContext = c;
}
#JavascriptInterface
public JSONArray getChartData() {
String texto = " [ {name: 'valor1', 2007: "+val[(++ind)%9]+"}, "+
" {name: 'valor2', 2007: "+val[(++ind)%9]+"}, "+
" {name: 'valor3', 2007: "+val[(++ind)%9]+"} ]";
JSONArray jsonar=null;
try {
jsonar = new JSONArray(texto);
} catch (JSONException e) {
e.printStackTrace();
}
return jsonar;
}
}
Now the javascript code:
window.generateData = function() {
/*var data = [ {name: 'valor1', 2007: 50},
{name: 'valor2', 2007: 20},
{name: 'valor3', 2007: 30} ]; */
var data = JSON.parse( Android.getChartData() );
return data;
};
The commented code above show how it was when static, and now the data came from the Java code.
It was testes on Android 2.1 and 3.2.
I can run this feature
In Javascript :
var data = {
'username' : $('#username').val().trim(),
'password' : $('#password').val().trim(),
'dns' : $('#dns').val().trim()
}
var str = JSON.stringify(data);
Native.getLoginService(str);
In Android :
#JavascriptInterface
public void getLoginService(String jsonData){
try{
JSONObject data = new JSONObject(jsonData);
String username = data.getString("username");
String password = data.getString("password");
String dns = data.getString("dns");
Log.i("TAG",username + " - " + password + " - " + dns);
}catch (Exception ex){
Log.i("TAG","error : " + ex);
}
}
Good luck with...
I think you can also pass JSONObject and JSONArray. So not only primitive types, but also primitive types stored in a javascript array [0,1,2] or dictionary {one:1, two:2}.
I have NOT verified this in code, just read the docs. Might be using it soon.
You can't pass JSONObject or JSONArray, but you can send strings with that form and parse them to those types.
Your option is to expose the method using strings and then you can use the JSONObject or JSONArray to parse the string and use it accordingly.
Here is what I did.
#JavascriptInterface
public void passJSON(String array, String jsonObj) throws JSONException
{
JSONArray myArray = new JSONArray(array);
JSONObject myObj = new JSONObject(jsonObj);
...
}
where array is '["string1","string2"]' and jsonObj is '{attr:1, attr2:"myName"}'