I get data from a URL, and am working on the data to check for a few conditions. The data from the URL look like this:
1528190345":100,"1528190346":100,"1528190368":100,"1528190414":100,"1528190439":99,"1528190440":99,"1528190463":100,"1528190485":100,"1528190508":100,"1528190550":100,"1528190575":100,"1528190576":100,"1528190599":100,"1528190600":100,"1528190622":100,"1528190667":100,"1528190688":100,"1528190689":100,"1528190712":100,"1528190736":100,"1528190762":100,"1528190785":100,"1528190786":100,"1528190807":100,"1528190828":100,"1528190853":100,"1528190877":100,"1528190901":100,"1528190925":100,"1528190948":100,"1528190968":100,"1528190991":100}}]
====
I have converted that too JSON
{"metric"=>"Insta_real-unique_value", "tags"=>{"host"=>"letme.quickly.com", "tier"=>"2", "device"=>"tester1", "dc"=>"xxx"}, "aggregateTags"=>["device_name", "device_ip"], "dps"=>{"1526972408"=>100, "1526972424"=>100, "1526972440"=>100, "1526972456"=>100, "1526972472"=>100, "1526972488"=>100, "1526972504"=>100, "1526972520"=>100, "1526972536"=>100, "1526972552"=>100, "1526972568"=>100, "1526972569"=>100, "1526972584"=>100, "1526972585"=>100, "1526972601"=>100, "1526972617"=>100, "1526972633"=>100, "1526972649"=>100, "1526972665"=>100, "1526972681"=>100}}
I want to extract the value that corresponds to 100. When I do this:
url = "#{URL}"
uri = URI(url)
response = Net::HTTP.get(uri)
value = response[-6..-4]
puts value
I get the last value, but when the last value changes to 99/9/0, it prints :99 or ":9.
Is there a way to get the exact value as is?
When dealing with JSON data, it's almost always better to parse the data properly rather than using regex against the string.
In this case, we can do:
JSON.parse(response)['dps'].values.last #=> 100
If the response is a json response, you must use a json parser else if is not a json response, you can use a regex expression with a Regex Object.
In case of a json response, assuming that the object is something like is declared into the variable response of the next code, you can parse it into a JObject. (using Newtonsoft.Json available from nuget repository).
See the next example :
string response = "[{\"response\":{\"1528190345\":100,\"1528190346\":100,\"1528190368\":100,\"1528190414\":100,\"1528190439\":99,\"1528190440\":99,\"1528190463\":100,\"1528190485\":100,\"1528190508\":100,\"1528190550\":100,\"1528190575\":100,\"1528190576\":100,\"1528190599\":100,\"1528190600\":100,\"1528190622\":100,\"1528190667\":100,\"1528190688\":100,\"1528190689\":100,\"1528190712\":100,\"1528190736\":100,\"1528190762\":100,\"1528190785\":100,\"1528190786\":100,\"1528190807\":100,\"1528190828\":100,\"1528190853\":100,\"1528190877\":100,\"1528190901\":100,\"1528190925\":100,\"1528190948\":100,\"1528190968\":100,\"1528190991\":100}}]";
List<Dictionary<string, Dictionary<string, int>>> values = JsonConvert.DeserializeObject<List<Dictionary<string, Dictionary<string, int>>>>(response);
Dictionary<string, Dictionary<string, int>> firstLevel = values[0]; // Access to the first object of the list closed with ']'
Dictionary<string, int> secondLevel = firstLevel["response"]; // Access to the first object response and get's it's object context of first '}' starting from the end of response
/** This is an option, if you ever knows the name of the element (1528190991) */
int thirdLevel = secondLevel["1528190991"]; // Access to the last element of the object by it's name, context of second '}' starting from the end of response.
Console.WriteLine(thirdLevel);
/** This is another option if you doesn't know the name of the element and wants ever the last element. */
List<int> listOfValues = secondLevel.Values.ToList();
Console.WriteLine(listOfValues[listOfValues.Count-1]);
Note that i've chenged a little bit your response adding [{\"response\":{\" at the start to become a json response.
If is not a json response you can use this pattern with regular expression :
:(.{2,6})}}\]$
Hope will help!
Related
I'm using OKHttpClient in a Kotlin app to post a file to an API that gets processed. While the process is running the API is sending back messages to keep the connection alive until the result has been completed. So I'm receiving the following (this is what is printed out to the console using println())
{"status":"IN_PROGRESS","transcript":null,"error":null}
{"status":"IN_PROGRESS","transcript":null,"error":null}
{"status":"IN_PROGRESS","transcript":null,"error":null}
{"status":"DONE","transcript":"Hello, world.","error":null}
Which I believe is being separated by a new line character, not a comma.
I figured out how to extract the data by doing the following but is there a more technically correct way to transform this? I got it working with this but it seems error-prone to me.
data class Status (status : String?, transcript : String?, error : String?)
val myClient = OkHttpClient ().newBuilder ().build ()
val myBody = MultipartBody.Builder ().build () // plus some stuff
val myRequest = Request.Builder ().url ("localhost:8090").method ("POST", myBody).build ()
val myResponse = myClient.newCall (myRequest).execute ()
val myString = myResponse.body?.string ()
val myJsonString = "[${myString!!.replace ("}", "},")}]".replace (",]", "]")
// Forces the response from "{key:value}{key:value}"
// into a readable json format "[{key:value},{key:value},{key:value}]"
// but hoping there is a more technically sound way of doing this
val myTranscriptions = gson.fromJson (myJsonString, Array<Status>::class.java)
An alternative to your solution would be to use a JsonReader in lenient mode. This allows parsing JSON which does not strictly comply with the specification, such as in your case multiple top level values. It also makes other aspects of parsing lenient, but maybe that is acceptable for your use case.
You could then use a single JsonReader wrapping the response stream, repeatedly call Gson.fromJson and collect the deserialized objects in a list yourself. For example:
val gson = GsonBuilder().setLenient().create()
val myTranscriptions = myResponse.body!!.use {
val jsonReader = JsonReader(it.charStream())
jsonReader.isLenient = true
val transcriptions = mutableListOf<Status>()
while (jsonReader.peek() != JsonToken.END_DOCUMENT) {
transcriptions.add(gson.fromJson(jsonReader, Status::class.java))
}
transcriptions
}
Though, if the server continously provides status updates until processing is done, then maybe it would make more sense to directly process the parsed status instead of collecting them all in a list before processing them.
I'm trying to assert the data coming from variable in JDBC PostProcessor(using SQL server) with JSON response, the data is coming from JSON as expected but the problem is the one that coming from Database has braces and an equal character, so the test fails
The value coming from DB --> {=598}
The expected one(from JSON) --> 598
groovy code:
import groovy.json.JsonOutput
import groovy.json.JsonSlurper
def jsonSlurper = new JsonSlurper();
//parsing incoming json
def response = jsonSlurper.parseText(prev.getResponseDataAsString());
//getting actual json
def AssessmentId_JSON = JsonOutput.toJson(response[0].AssessmentId);
// Getting "data" variable from DB query(getObject() method returns ArrayList data type)
def valueFromDBQuery = vars.getObject("data");
//Converting from arraylist to string (if list has one element)
String AssessmentId_DB = valueFromDBQuery[0];
log.info ("The Value is: " + AssessmentId_DB);
log.info ("It should be: " + AssessmentId_JSON);
Log:
2018-07-18 16:35:18,399 INFO o.a.j.a.JSR223Assertion: The Value is: {=598}
2018-07-18 16:35:18,399 INFO o.a.j.a.JSR223Assertion: It should be: 598
any help ?
thanks
Looking into Debugging JDBC Sampler Results in JMeter article your data variable should be an ArrayList of HashMaps
Looking into {=598} my expectation is that your JDBC query is returning a single value
Assuming above 2 points I would recommend updating this line:
String AssessmentId_DB = valueFromDBQuery[0]
to this one:
String AssessmentId_DB = valueFromDBQuery[0].find().value as String
Groovy's AbstractMap.find() function basically returns the first element matching the query from the collection, in your case it would be first and the only element.
So, I get some JSON values from the server but I don't know if there will be a particular field or not.
So like:
{ "regatta_name":"ProbaRegatta",
"country":"Congo",
"status":"invited"
}
And sometimes, there will be an extra field like:
{ "regatta_name":"ProbaRegatta",
"country":"Congo",
"status":"invited",
"club":"somevalue"
}
I would like to check if the field named "club" exists so that at parsing I won't get
org.json.JSONException: No value for club
JSONObject class has a method named "has":
http://developer.android.com/reference/org/json/JSONObject.html#has(java.lang.String)
Returns true if this object has a mapping for name. The mapping may be NULL.
You can check this way where 'HAS' - Returns true if this object has a mapping for name. The mapping may be NULL.
if (json.has("status")) {
String status = json.getString("status"));
}
if (json.has("club")) {
String club = json.getString("club"));
}
You can also check using 'isNull' - Returns true if this object has no
mapping for name or if it has a mapping whose value is NULL.
if (!json.isNull("club"))
String club = json.getString("club"));
you could JSONObject#has, providing the key as input and check if the method returns true or false. You could also
use optString instead of getString:
Returns the value mapped by name if it exists, coercing it if
necessary. Returns the empty string if no such mapping exists
just before read key check it like before read
JSONObject json_obj=new JSONObject(yourjsonstr);
if(!json_obj.isNull("club"))
{
//it's contain value to be read operation
}
else
{
//it's not contain key club or isnull so do this operation here
}
isNull function definition
Returns true if this object has no mapping for name or
if it has a mapping whose value is NULL.
official documentation below link for isNull function
http://developer.android.com/reference/org/json/JSONObject.html#isNull(java.lang.String)
You can use has
public boolean has(String key)
Determine if the JSONObject contains a specific key.
Example
JSONObject JsonObj = new JSONObject(Your_API_STRING); //JSONObject is an unordered collection of name/value pairs
if (JsonObj.has("address")) {
//Checking address Key Present or not
String get_address = JsonObj .getString("address"); // Present Key
}
else {
//Do Your Staff
}
A better way, instead of using a conditional like:
if (json.has("club")) {
String club = json.getString("club"));
}
is to simply use the existing method optString(), like this:
String club = json.optString("club);
the optString("key") method will return an empty String if the key does not exist and won't, therefore, throw you an exception.
Try this:
let json=yourJson
if(json.hasOwnProperty(yourKey)){
value=json[yourKey]
}
Json has a method called containsKey().
You can use it to check if a certain key is contained in the Json set.
File jsonInputFile = new File("jsonFile.json");
InputStream is = new FileInputStream(jsonInputFile);
JsonReader reader = Json.createReader(is);
JsonObject frameObj = reader.readObject();
reader.close();
if frameObj.containsKey("person") {
//Do stuff
}
Try this
if(!jsonObj.isNull("club")){
jsonObj.getString("club");
}
I used hasOwnProperty('club')
var myobj = { "regatta_name":"ProbaRegatta",
"country":"Congo",
"status":"invited"
};
if ( myobj.hasOwnProperty("club"))
// do something with club (will be false with above data)
var data = myobj.club;
if ( myobj.hasOwnProperty("status"))
// do something with the status field. (will be true with above ..)
var data = myobj.status;
works in all current browsers.
You can try this to check wether the key exists or not:
JSONObject object = new JSONObject(jsonfile);
if (object.containskey("key")) {
object.get("key");
//etc. etc.
}
I am just adding another thing, In case you just want to check whether anything is created in JSONObject or not you can use length(), because by default when JSONObject is initialized and no key is inserted, it just has empty braces {} and using has(String key) doesn't make any sense.
So you can directly write if (jsonObject.length() > 0) and do your things.
Happy learning!
You can use the JsonNode#hasNonNull(String fieldName), it mix the has method and the verification if it is a null value or not
Executing below code returns the result that contains the element of type hashmap instead of type T (the basicDBList coming from mongoDB does not have "_class" attribute:
com.mongodb.BasicDBList basicDBList = // output of mongoDB query;
List<T> result = mongoOperations.getConverter().read(List.class, basicDbList);
Is there any way to provide type information of List to the read method ?
Not exactly clear what you're trying to achieve, but if you acquired your BasicDBList by calling the getRawResults().get("result") of an AggregationResults instance, you can instead call getMappedResults:
Aggregation aggregation = Aggregation.newAggregation(...);
AggregationResults<Foo> r = mongoTemplate.aggregate(aggregation, "foos", Foo.class);
List<Foo> foos = r.getMappedResults();
How do I get the full message and not just the metadata using gmail api?
I have a service account and I am able to retrieve a message but only in the metadata, raw and minimal formats. How do I retrieve the full message in the full format? The following code works fine
var request = service.Users.Messages.Get(userId, messageId);
request.Format = UsersResource.MessagesResource.GetRequest.FormatEnum.Metadata;
Message message = request.Execute();
However, when I omit the format (hence I use the default format which is FULL) or I change the format to UsersResource.MessagesResource.GetRequest.FormatEnum.Full
I get the error: Metadata scope doesn't allow format FULL
I have included the following scopes:
https://www.googleapis.com/auth/gmail.readonly,
https://www.googleapis.com/auth/gmail.metadata,
https://www.googleapis.com/auth/gmail.modify,
https://mail.google.com/
How do I get the full message?
I had to remove the scope for the metadata to be able to get the full message format.
The user from the SO post have the same error.
Try this out first.
Go to https://security.google.com/settings/security/permissions
Choose the app you are working with.
Click Remove > OK
Next time, just request exactly which permissions you need.
Another thing, try to use gmailMessage.payload.parts[0].body.dataand to decode it into readable text, do the following from the SO post:
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.StringUtils;
System.out.println(StringUtils.newStringUtf8(Base64.decodeBase64(gmailMessage.payload.parts[0].body.data)));
You can also check this for further reference.
try something like this
public String getMessage(string user_id, string message_id)
{
Message temp =service.Users.Messages.Get(user_id,message_id).Execute();
var parts = temp.Payload.Parts;
string s = "";
foreach (var part in parts) {
byte[] data = FromBase64ForUrlString(part.Body.Data);
s += Encoding.UTF8.GetString(data);
}
return s
}
public static byte[] FromBase64ForUrlString(string base64ForUrlInput)
{
int padChars = (base64ForUrlInput.Length % 4) == 0 ? 0 : (4 - (base64ForUrlInput.Length % 4));
StringBuilder result = new StringBuilder(base64ForUrlInput, base64ForUrlInput.Length + padChars);
result.Append(String.Empty.PadRight(padChars, '='));
result.Replace('-', '+');
result.Replace('_', '/');
return Convert.FromBase64String(result.ToString());
}