I am querying twitter api to get the tweets with a hashtag in grails 2.1.1.
My Controller is
import grails.converters.*
import org.codehaus.groovy.grails.web.json.*; // package containing JSONObject, JSONArray,...
import groovyx.net.http.*
import static groovyx.net.http.ContentType.*
import static groovyx.net.http.Method.*
class NepTweetController {
def index() {
//def restEndpointUrl = "http://search.twitter.com/search.json?q=%23nepal";
def restEndpointUrl = "http://search.twitter.com/search.json?q=%23nepal";
def http = new HTTPBuilder(restEndpointUrl);
// perform a GET request, expecting JSON response data
http.request( GET, JSON ) {
//uri.path = '/search.json'
//uri.query = [ q: '%23nepal' ]
response.success = { resp, json ->
// def tweetsResult = json.results;
// List parsedList = JSON.parse(json) as List;
// JSONObject tweetJson = JSON.parse(json);
//def tweetJson = JSON.parse(json);
def tweets = new JSON(json) as Map;
render(view: "index", model: [message: "Request sent" , tweets: tweets]);
}
}//end of request
}//end of method
}
I successfully get the json response as follows :
{
"completed_in": 0.017,
"max_id": 271907240007581696,
"max_id_str": "271907240007581696",
"next_page": "?page=2&max_id=271907240007581696&q=%23nepal%2F",
"page": 1,
"query": "%23nepal%2F",
"refresh_url": "?since_id=271907240007581696&q=%23nepal%2F",
"results": [
{
"created_at": "Fri, 23 Nov 2012 09:25:12 +0000",
"from_user": "iBshnu",
"from_user_id": 25051623,
"from_user_id_str": "25051623",
"from_user_name": "Bishnu Bhattarai",
"geo": null,
"id": 271907240007581696,
"id_str": "271907240007581696",
"iso_language_code": "ne",
"metadata": {
"result_type": "recent"
},
"profile_image_url": "http:\/\/a0.twimg.com\/profile_images\/2622309791\/42z33jnw1kak9ttyqkrf_normal.jpeg",
"profile_image_url_https": "https:\/\/si0.twimg.com\/profile_images\/2622309791\/42z33jnw1kak9ttyqkrf_normal.jpeg",
"source": "<a href="http:\/\/twitter.com\/">web<\/a>",
"text": "RT #dipakbhattarai: \u0930\u093e\u0937\u094d\u091f\u094d\u0930\u092a\u0924\u093f \u0921\u093e. \u0930\u093e\u092e\u092c\u0930\u0923 \u092f\u093e\u0926\u0935\u0926\u094d\u0935\u093e\u0930\u093e \u092e\u0919\u094d\u0938\u093f\u0930 \u0967\u096a \u092d\u093f\u0924\u094d\u0930 \u0926\u0932\u0939\u0930\u0941\u0932\u093e\u0908 \u0930\u093e\u0937\u094d\u091f\u094d\u0930\u093f\u092f \u0938\u0939\u092e\u0924\u093f\u0915\u094b \u0938\u0930\u0915\u093e\u0930 \u092c\u0928\u093e\u0909\u0928 \u0906\u0935\u094d\u0939\u093e\u0928\u0964 #Nepal",
"to_user": null,
"to_user_id": 0,
"to_user_id_str": "0",
"to_user_name": null
},
{
"created_at": "Fri, 23 Nov 2012 09:24:58 +0000",
"from_user": "Phanindra07",
"from_user_id": 63104333,
"from_user_id_str": "63104333",
"from_user_name": "Phanindra Dahal",
"geo": null,
"id": 271907179404095488,
"id_str": "271907179404095488",
"iso_language_code": "en",
"metadata": {
"result_type": "recent"
},
"profile_image_url": "http:\/\/a0.twimg.com\/profile_images\/2417859753\/febstuo4p4zltimnpky0_normal.jpeg",
"profile_image_url_https": "https:\/\/si0.twimg.com\/profile_images\/2417859753\/febstuo4p4zltimnpky0_normal.jpeg",
"source": "<a href="http:\/\/twitter.com\/">web<\/a>",
"text": "RT #DeepakAdk: Chef's assault on #Nepal #Maoist reflects grassroots anger, excellent piece by my #AFP colleague #FrankieTaggart http:\/\/t.co\/M47qJeoD",
"to_user": null,
"to_user_id": 0,
"to_user_id_str": "0",
"to_user_name": null
}
[....more....]
My /views/nepTweet/index.gsp is
<meta name='layout' content='main'/>
<b>${message}</b>
<p>Tweets</p>
<g:each in="${tweets}" var="tweet">
<p>${tweet.text}</p>
</g:each>
But, I get error parsing json to grails Map.
Error I get is :
Error 500: Internal Server Error
URI
/WhoTweetsNepal/nepTweet
Class
groovy.lang.MissingMethodException
Message
No signature of method: grails.converters.JSON.entrySet() is applicable for argument types: () values: [] Possible solutions: every()
I went through How do I access A JSON Object(String) from GSP page?, but couldn't get help.
Helpppp!!!
You definitely want
def tweetJson = JSON.parse(json);
(which will return a JSONObject, which is a Map) instead of
def tweetJson = new JSON(json) as Map;
but it looks like you have a bit of a name clash in your code - presumably the JSON in
http.request( GET, JSON )
is intended to be the HTTPBuilder content type rather than grails.converters.JSON. If you can clear up this name clash (i.e. remove the import static and say ContentType.JSON) then things may run more smoothly.
With to the point suggestions from Ian Roberts, I got the solution with my final Controller to be(realising there is no need to parse it) :
import grails.converters.*
import org.codehaus.groovy.grails.web.json.*; // package containing JSONObject, JSONArray,...
import groovyx.net.http.*
import static groovyx.net.http.ContentType.*
import static groovyx.net.http.Method.*
class NepTweetController {
def index() {
def restEndpointUrl = "http://search.twitter.com/search.json?q=%23nepal";
def http = new HTTPBuilder(restEndpointUrl);
// perform a GET request, expecting JSON response data
http.request( GET, ContentType.JSON ) {
//uri.path = '/search.json'
//uri.query = [ q: '%23nepal' ]
response.success = { resp, json ->
def tweetsResult = json.results;
render(view: "index", model: [message: "Request sent" , tweets: tweetsResult]);
}
}//end of request
}//end of method
}
Related
Thanks in advance!
If it helps, this is my initial post.
As an input, I have this json:
{
"BidId": "ID1088622222",
"ItemNumber": "4.3.9",
"CodiceNegoziazione": "Doc104222222",
"CreationDate": "Wed, 15 Jun, 2022",
"ProjectId": "WS1042222222",
"ProjectOwner": "Silvia Gani",
"ProjectTitle": "gara import Europa Y2022-2023",
"CompanyCode": "A222 Olivetti",
"PurchasingOrganization": "",
"PurchasingGroup": "",
"PaymentTerms": "",
"Currency": "EUR",
"EventType": "RFP",
"EventOwner": "Silvia Gani",
"EventId": "Doc1042222222",
"EventTitle": "gara Import Europa Y2022-2023",
"SupplierOrgName": "ARCESE",
"SupplierOrgId": "buyersystemid:acm_2222",
"SectionLot": "GERMANIA (Emmer)",
"ItemName": "CAMION COMPLETO (EURO)",
"Type": "Line Item",
"SubmissionDate": "Mon, 4 Jul, 2022",
"Price": "1530",
"Quantity": "1",
"ExtendedPrice": "1530",
"MaterialGroup": "",
"RequestedDeliveryDate": "",
"BidCurrency": "EUR",
"BidExtendedPrice": "1530",
"BidSavings": "0",
"BidPrice": "1530",
"AwardAllocationPercentage": "100"
}
I would like to adjust this part of code:
class Version {
int major
Integer minor, patch
#Override String toString() {
return [major, minor, patch].findAll().join('.')
}
}
def parseVersion(String versionString) {
if (!versionString) return null
int[] tokens = versionString.split(/\./).collect { it as int }
return new Version(
major: tokens[0],
minor: tokens.length > 1 ? tokens[1] : null,
patch: tokens.length > 2 ? tokens[2] : null,
)
}
class Payload {
String ItemNumber
}
Payload payload = new Payload(ItemNumber: "2.4")
Version version = parseVersion(payload.ItemNumber?.trim())
printf("Major version : %d%n", version.major)
printf("Minor version : %s%n", version.minor ?: "<UNSET>")
printf("Patch version : %s%n", version.patch ?: "<UNSET>")
printf("Full version : %s%n", version)
In this groovy script:
import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
import groovy.json.*
def Message processData(Message message) {
//Body
def body = message.getBody(String.class);
def jsonSlurper = new JsonSlurper()
def list = jsonSlurper.parseText(body)
def ItemNumber = list.get("ItemNumber")
def Price = list.get("Price")
def Quantity = list.get("Quantity")
def ExtendedPrice = list.get("ExtendedPrice")
def BidExtendedPrice = list.get("BidExtendedPrice")
def BidTotalCost = list.get("BidTotalCost")
def BidSavings = list.get("BidSavings")
def BidPrice = list.get("BidPrice")
def RfqItemNumber = list.get("RfqItemNumber")
def AwardAllocationPercentage = list.get("AwardAllocationPercentage")
if (ItemNumber?.trim()){
list.ItemNumber = Double.parseDouble(ItemNumber.toString());
}
if (Price?.trim()){
list.Price = Double.parseDouble(Price.toString());
}
if (Quantity?.trim()){
list.Quantity= Double.parseDouble(Quantity.toString());
}
if (ExtendedPrice?.trim()){
list.ExtendedPrice= Double.parseDouble(ExtendedPrice.toString());
}
if (BidExtendedPrice?.trim()){
list.BidExtendedPrice= Double.parseDouble(BidExtendedPrice.toString());
}
if (BidTotalCost?.trim()){
list.BidTotalCost= Double.parseDouble(BidTotalCost.toString())
}
if (BidSavings?.trim()){
list.BidSavings= Double.parseDouble(BidSavings.toString());
}
if (BidPrice?.trim()){
list.BidPrice= Double.parseDouble(BidPrice.toString());
}
if (RfqItemNumber?.trim() && RfqItemNumber != 'null'){
list.RfqItemNumber= Integer.parseInt(RfqItemNumber.toString());
}else if (RfqItemNumber == 'null'){
list.RfqItemNumber = null
}
if (AwardAllocationPercentage?.trim()){
list.AwardAllocationPercentage= Double.parseDouble(AwardAllocationPercentage.toString());
}
def jsonOP = JsonOutput.toJson(list)
message.setBody(jsonOP)
return message;
}
The goal is to parse the field ItemNumber. (From "ItemNumber": "4.4.5" --> "ItemNumber": 4.4.5)
The desired result:
{"BidId":"ID1088625754","ItemNumber":4.4.5,"CodiceNegoziazione":"Doc1042163109","CreationDate":"Wed, 15 Jun, 2022","ProjectId":"WS1042082696","ProjectOwner":"Silvia Ganio Mego","ProjectTitle":"gara import Europa Y2022-2023","CompanyCode":"A200 Olivetti S.p.A.","PurchasingOrganization":"","PurchasingGroup":"","PaymentTerms":"","Currency":"EUR","EventType":"RFP","EventOwner":"Silvia Ganio Mego","EventId":"Doc1042163109","EventTitle":"gara Import Europa Y2022-2023","SupplierOrgName":"ARCESE TRASPORTI S.P.A.","SupplierOrgId":"buyersystemid:acm_36628101|sap:0000333441|networkid:an01009585103","SectionLot":"GERMANIA (Emmerich)","ItemName":"CAMION COMPLETO (EURO)","Type":"Line Item","SubmissionDate":"Mon, 4 Jul, 2022","Price":1530.0,"Quantity":1.0,"ExtendedPrice":1530.0,"MaterialGroup":"","RequestedDeliveryDate":"","BidCurrency":"EUR","BidExtendedPrice":1530.0,"BidSavings":0.0,"BidPrice":1530.0,"AwardAllocationPercentage":100.0}
I tried to adjust the above part of code in the groovy but I still get "ItemNumber": "4.4.5" .
If I try the code in a groovy ide it works fine though. I am not so familiar with all of this, not so long in this area.
I have text attribute in GenerateFlowfile processor like this:
[{
"status": {
"runStatus": "STOPPED"
},
"component": {
"state": "STOPPED",
"id": "ea5db028-015d-1000-5ad5-80fd006dda92"
},
"revision": {
"version": 46,
"clientId": "ef592126-015d-1000-bf4f-93c7cf7eedc0"
}
} ]
and related groovy script in my ExecuteScript processor :
import org.apache.commons.io.IOUtils
import java.nio.charset.*
def flowFile = session.get();
if (flowFile == null) {
return;
}
def slurper = new groovy.json.JsonSlurper()
def attrs = [:] as Map<String,String>
session.read(flowFile,
{ inputStream ->
def text = IOUtils.toString(inputStream, StandardCharsets.UTF_8)
text=flowFile.getAttribute('text')
def obj = slurper.parseText(text)
obj.each {k,v ->
attrs[k] = v.toString()
}
} as InputStreamCallback)
flowFile = session.putAllAttributes(flowFile, attrs)
session.transfer(flowFile, REL_SUCCESS)
but my processor still shows me exception like this, what should i change?
the problem that the root element of your json is an array
and you try to iterate it like map .each{k,v-> ... }
probably you want to take the first map to iterate it like in code below
def obj=[ [a:1] ]
//this line will throw exception:
//obj.each{k,v-> println "$k->$v" }
//but this one not
obj[0].each{k,v-> println "$k->$v" }
fyi: there is a EvaluateJsonPath processor that could extract attributes from json flowfile content and put result into attribute
I need to send response from R using plumber package in below format
{
"status": "SUCCESS",
"code": "200",
"output": {
"studentid": "1001",
"name": "Kevin"
}
}
But I am getting below format
[
"{\n \"status\": \"SUCCESS\",\n \"code\": \"200\",\n \"output\": {\n \"studentid\": \"1001\",\n \"name\": \"Kevin\"\n }\n}"
]
Please help me format this json properly
My Code
#* #post /sum
addTwo <- function(){
library(jsonlite)
x <- list(status = "SUCCESS", code = "200",output = list(studentid = "1001", name = "Kevin"))
output<-toJSON(x,pretty = TRUE, auto_unbox = TRUE)
return (output)
}
I added an unboxedJSON serializer to the development version of plumber. Depending on when in the future this is being read, that serializer might have been published to CRAN and might even be the default serializer now (I'm still debating).
But for now, you can install the development version from GitHub (devtools::install_github("trestletech/plumber")) then add the #serializer unboxedJSON annotation to your function like so:
#* #post /sum
#* #serializer unboxedJSON
addTwo <- function(){
list(status = "SUCCESS", code = "200",output = list(studentid = "1001", name = "Kevin"))
}
FYI if you ever do want to force plumber to return some text that you're providing directly, you should be able to set the $body element on res then return the res object from the function.
#* #get /
function(res){
res$body <- "I am raw"
res
}
which will return the unformatted, unserialized text I am raw in its response.
Just remove the toJSON() wrapper.
Plumber already does JSON serialisation so you are doing it twice by adding a toJSON function.
This should work.
addTwo <- function(){
x <- list(status = "SUCCESS", code = "200",output = list(studentid = "1001", name = "Kevin"))
return (x)
}
I receive a JSon string from WS. It's so long that I can't use Json2charp to parse it and receive the structurated class.
I want to parse the string with a command. How is it possible?
I don't know the classes so I can't use a command like:
Dim result = JsonConvert.DeserializeObject(Of MyClass.RootObject)(String_From_File)
Is it possible from the string to obtain the class without using json2charp site ?
For example, in vs.net if on the variable 'string_from_file' I choose 'Json Visualizer' and see all classes and data in correct mode.
How can I obtain the same in my code ?
I have installed Newtonsoft.json
If you cannot use the json to class mappers like NewtonSoft.Json. You can use the Windows.Data.Json api. It let you parse and extract the data you want from your JSON string.
JsonValue jsonValue = JsonValue.Parse("{\"Width\": 800, \"Height\": 600, \"Title\": \"View from 15th Floor\", \"IDs\": [116, 943, 234, 38793]}");
double width = jsonValue.GetObject().GetNamedNumber("Width");
double height = jsonValue.GetObject().GetNamedNumber("Height");
string title = jsonValue.GetObject().GetNamedString("Title");
JsonArray ids = jsonValue.GetObject().GetNamedArray("IDs");
You can find a sample in the Windows Universal Sample GitHub.
A complex object parsing is shown here. I've extracted the most relevant parts here. The JSON string is provided to the User constructor which is extracting what it needs and then delegating the parsing to the nested School constructor.
{
"id": "1146217767",
"phone": null,
"name": "Satya Nadella",
"education": [
{
"school": {
"id": "204165836287254",
"name": "Contoso High School"
},
"type": "High School"
},
{
"school": {
"id": "116138758396662",
"name": "Contoso University"
},
"type": "College"
}
],
"timezone": -8,
"verified": true
}
This JSON fragment is parsed with this code:
public User(string jsonString) : this()
{
JsonObject jsonObject = JsonObject.Parse(jsonString);
Id = jsonObject.GetNamedString(idKey, "");
IJsonValue phoneJsonValue = jsonObject.GetNamedValue(phoneKey);
if (phoneJsonValue.ValueType == JsonValueType.Null)
{
Phone = null;
}
else
{
Phone = phoneJsonValue.GetString();
}
Name = jsonObject.GetNamedString(nameKey, "");
Timezone = jsonObject.GetNamedNumber(timezoneKey, 0);
Verified = jsonObject.GetNamedBoolean(verifiedKey, false);
foreach (IJsonValue jsonValue in jsonObject.GetNamedArray(educationKey, new JsonArray()))
{
if (jsonValue.ValueType == JsonValueType.Object)
{
Education.Add(new School(jsonValue.GetObject()));
}
}
}
public School(JsonObject jsonObject)
{
JsonObject schoolObject = jsonObject.GetNamedObject(schoolKey, null);
if (schoolObject != null)
{
Id = schoolObject.GetNamedString(idKey, "");
Name = schoolObject.GetNamedString(nameKey, "");
}
Type = jsonObject.GetNamedString(typeKey);
}
If you cannot use the automatic mapping from NewtonSoft.Json, you have no other way than doing it yourself.
Is not so simple.
The Json i received is very complicated and have many class
So i can't use
double width = jsonValue.GetObject().GetNamedNumber("Width");
Inside class i have more ...
I can't find any solution for my issue. Many I've tried doesn't work. Could someone help me?
I have a JSON like this:
{
"device": {
"sdk_revision": "dev",
"sdk_type": "android",
"app_id": "0518101906",
"app_version": "0.0.0"
},
"request": {}
}
in my request step in soapUI (RestProject).
I'd like to change the app_id value in this JSON, so in my groovy script I do:
import groovy.json.JsonSlurper
def today = new Date()
appId = today.format("MMddHHmmss")
def extractSelectionJson(String from) {
def slurper = new JsonSlurper()
def holderData = slurper.parseText(context.expand('${'+ from +'#Request}'))
appIdKey = holderData["device"]["app_id"]
appIdKey = appId
}
extractSelectionJson("SessionCreate")`
appId changed only locally, at my json request I have still "app_id": "0518101906" although I've tried setPropertyValue(), updateProperty() (maybe not right way).
For something simple like this, you can use just a one-liner:
{
"device": {
"sdk_revision": "dev",
"sdk_type": "android",
"app_id": "${=String.format('%tm%td%tH%tM%tS'
, new Date()
, new Date()
, new Date()
, new Date()
, new Date())}",
"app_version": "0.0.0"
},
"request": {}
}
If you need details for the String.format(), it is in the documentation.