I am trying to write a C++ application, using C++ REST SDK lib, that will process JSON data produced by a C# application. A C# program can produce JSON in a "wrapped" or "bare" style.
Using BodyStyle = WebMessageBodyStyle.Wrapped, C# produces JSON like the following:
{"Echo":"{\"firstname\":\"an'",\"number\":21,\"secondname\":\"pn\"}"}
Using BodyStyle = WebMessageBodyStyle.Bare, C# produces JSON like this:
"{\"firstname\":\"an'",\"number\":21,\"secondname\":\"pn\"}"
How can my program recognize which type was produced: Wrapped or Bare?
JSON is a standard format for representing, and exchanging, data. It does not define the terms Wrapped or Bare. I am not familiar with C# and its libraries for encoding data as JSON, however I can make a guess based on the samples you provided.
If you have control over the C# application, code it to use Bare only. I see no advantage, in general, to the Wrapped style. Perhaps it is designed specifically for some other C# client libraries.
The only difference I see in the produced output is the structure of the data. There is no way to be absolutely certain, but from those two samples you can simply look at the deserialized object and check if it has an attribute Echo. If it does, use the value of that attribute and if it doesn't then use the object as-is.
Since I haven't worked in C++ in over a decade and I do not know the JSON library you are using, I will give an example in JavaScript (though using a style that may be somewhat closer to C++). Here is how those two objects could be handled:
var data = JSON.parse(...); // the '...' represents where ever you get the text
if (data["Echo"] !== undefined)
{ data = data["Echo"]; }
console.log("The first name is:", data["firstname"]);
Here is a psuedo-code example that is almost valid Java which may be more easily recognized and translated to C++:
Map<String, Object> data = JSON.parse(...); // the '...' represents where ever you get the text
if (data.containsKey("Echo"))
{ data = (Map)data.get("Echo"); }
System.out.println("The first name is: " + data.get("firstname"));
Related
I'm writing a C function/extension. It's a function that'll be called by a trigger. In it, when a trigger is fired, I need determine the name of the current database.
It's a requirement that using SPI_prepare(), SPI_exec() isn't allowed in this case, therefore querying current_database() won't work.
Some other SPI_get* will be ok. Or, accessing to the current database name via TupleDesc or TriggerData somehow too.
How to do it?
It's not clear to me which of postgresql's server-internal programming interfaces are usable in SPI extensions. However, the implementation of the current_database SQL function does this:
Name db;
db = (Name) palloc(NAMEDATALEN);
namestrcpy(db, get_database_name(MyDatabaseId));
PG_RETURN_NAME(db);
So, I think get_database_name(MyDatabaseId) is the incantation you want. It returns a C string, which your C extension can use directly -- the rest of the above is to box up the string in a Datum object so the query evaluator can work with it.
I figured out that a function called "current_database()" seems useful which seems similar to "select database()". Later returns a string which represents the name of the database.
Yes, a parameter that your extension will get in order to deduce context or so.
PL/SQL can create functions. These can in turn call C-Language extensions via shared libraries. Finally, the name can be delegated from database towards extension.
How can I pass values from Karate API to Java class?
As mentioned in the documentation, I used the following code snippet to get the response from Java API. But its returning the response with un-formatted JSON content.
Map<String, Object> result = CucumberRunner.runClasspathFeature("demo/java/from-java.feature", args, true);
And then, I used the following script to print the response.
for(Map.Entry<String , Object> entry: getMbrWksMembershipDetailsResponse.entrySet())
{
if (entry.getKey().equalsIgnoreCase("response"))
{
System.out.println(entry.getValue());
}
}
It shows like,
{soap:Envelope={_={soap:Body={ns1:getMbrWksMembershipDetailsResponse={_={ns4:WksMembershipSummaryResponse={_={ns2:customerSummary={ns2:address={ns2:city=SOUTH CHESTERFIELD, ns2:country=USA, ns2:isoCountryCode=US, ns2:line1=9998, N. MICHIGAN ROAD., ns2:postalCode=23834, ns2:state=VA}, ns2:allowPasswordChange=true, ns2:arpMember=false, ns2:brandCode=RCI, ns2:brandId=1, ns2:companyCode=RCI, ns2:eliteMemberRewardStatus=false, ns2:eliteRewardStatus=true, ns2:europePointsClubMember=false, ns2:firstName=FRANK, ns2:homePhone=804/733-3004, ns2:isoCurrencyCode=USD, ns2:isoLanguageCode=EN, ns2:language=EN, ns2:lastName=BROWNING B, ns2:locale=en_US, ns2:memberDeveloperRenewed=false, ns2:memberEnrolledDate=2009-10-26T00:00:00-04:00, ns2:memberEnrolledForDirectDebit=false, ns2:memberEnrolledForPltDirectDebit=false, ns2:memberStatus=A, ns2:middleName=B, ns2:msgTranslationLanguageCode=EN, ns2:officePhone=0/-0, ns2:pointsCurrencyCode=0......
So it's little difficult to split the data based on the fields / tags from Map.
Please suggest what is the best option to get the values field wize / tag wise from Java API.
Thanks.
Yes, XML is internally held as a strange Map structure, refer to the section on type-conversion to understand more.
You have a simple way to do this. Just define a new variable that is the response converted to a string.
* xmlstring responseXml = response
After this you just need to get the responseXml out of the Map returned by the Java API which will be a string.
Note: don't use the Java API unless you are really trying to mix Karate with something else. The whole point of Karate is to avoid using Java for testing JSON and XML web-services.
This is probably a silly question, but I been scratching my head over this for far too long.
I am trying to request the photo information from the facebook GraphAPI using Facepy/social-auth in django.
My view has the following code, but how do i turn the resulting json into python objects?
instance = UserSocialAuth.objects.filter(user=request.user).filter(provider='facebook')
graph = GraphAPI(instance[0].extra_data['access_token'])
p=graph.get('me/photos')
Facepy seems very good, but the documentation is poor at best, is there a better python facebook sdk that plays nice with social-auth?
Thanks for all suggestions.
Facepy returns native Python objects, not JSON.
response = graph.get('me/photos')
for photo in response['data']:
print photo['source']
You can use simplejson's loads function
from django.utils import simplejson
simplejson.loads(args)
Deserialize s (a str or unicode instance containing a JSON
document) to a Python object.
If ``s`` is a ``str`` instance and is encoded with an ASCII based encoding
other than utf-8 (e.g. latin-1) then an appropriate ``encoding`` name
must be specified. Encodings that are not ASCII based (such as UCS-2)
are not allowed and should be decoded to ``unicode`` first.
``object_hook`` is an optional function that will be called with the
result of any object literal decode (a ``dict``). The return value of
``object_hook`` will be used instead of the ``dict``. This feature
can be used to implement custom decoders (e.g. JSON-RPC class hinting).
``parse_float``, if specified, will be called with the string
of every JSON float to be decoded. By default this is equivalent to
float(num_str). This can be used to use another datatype or parser
for JSON floats (e.g. decimal.Decimal).
``parse_int``, if specified, will be called with the string
of every JSON int to be decoded. By default this is equivalent to
int(num_str). This can be used to use another datatype or parser
for JSON integers (e.g. float).
``parse_constant``, if specified, will be called with one of the
following strings: -Infinity, Infinity, NaN, null, true, false.
This can be used to raise an exception if invalid JSON numbers
are encountered.
To use a custom ``JSONDecoder`` subclass, specify it with the ``cls``
kwarg.
i am trying to create a REST service that accepts a List of objects from a client and gives back a zip file.
i understand how to give back the zip file alright.
But i am right now trying to figure out a way i can pass a List of objects from a REST client/browser to the Rest service and how do i accept the List in the REST service.
Should this be done via XML input ?
or maybe the #consumes annotation could help?
Much thanks .
Som
You need to think out more clearly what you wish to do. There's no really good reason for taking a list of objects and returning a ZIP of them; you might as well use a local zip program (which just about all computers already have). That indicates that we instead need to be looking at something sensible: for example, a list of names of objects that you'll return a ZIP of, that makes a lot of sense. There are other sensible things you could be doing too, but you have to work it out in your mind what you want to happen.
Because you mention “#consumes annotation”, I'm going to assume you're using JAX-RS (i.e., Java). That's nice, because it's entirely possible to do on-the-fly ZIP generation with that; the content type you want to produce is application/zip. The easiest way I've found to handle the specification of the list of descriptions of things to return is as a wrapped list, where you use something like JAXB to do the mapping (which gives you XML support; some frameworks also support JSON off the same data models). To do a wrapped list, you use something like this:
#XmlRootElement
public class Wrapper {
#XmlElement
public List<String> item;
}
That then produces/handles XML documents like this (a three item list):
<wrapper>
<item>foo</item>
<item>...</item>
<item>bar</item>
</wrapper>
You'll need to set up the #Consumes annotation so that the content type accepted is application/xml (at least), and also consider what type of operation is involved and on what resource.
[EDIT]: In order to create a REST service that takes a list of strings as arguments, the easiest method is indeed to use a wrapper object, much as above. (You can't take a raw list; it needs to be a well-formed XML document when it's on the wire.) We then set up the annotated service method like this:
#POST
#Path("somewhere/{id}")
#Consumes("application/xml")
#Produces("application/zip")
public Response getSomeBytesForList(#PathParam("id") String id, Wrapper req) {
List<String> items = req.item; // For example...
byte[] zip = generateZipBytes(id, items); // or however
return Response.ok(zip).type("application/zip").build();
}
The key is that the req argument (the name is arbitrary, of course) is the only argument that is not annotated, that it is of a type that is JAXB-enabled, and there is an overall #Consumes ("application/xml") annotation to enable the JAXB processing of the request body. (I handle the returning of a ZIP by generating the Response directly rather than relying on the framework to do the processing for me; this lets me control the content type handling a little more precisely.)
Also note that some frameworks can also transfer JAXB-annotated objects as JSON documents, just by having a bit of extra annotation; you just state that the method can accept both "application/xml" and "application/json" in the #Consumes annotation. I do not know whether this applies to the framework you are using (I've only tested it with Apache CXF).
I have an ASP.net web service that I'm using for a web application which returns a either XML or JSON data to me, depending on the function I call. This has been working well thus far, but I've run into a problem. I want to create an "export" link on my page that will download a JSON file. The link is formatted very simply:
Export This Item
As you might imagine, this should export item 2. So far so good, yes?
Problem is that since I'm not specifically requesting that the accepted content type is JSON, ASP.net absolutely refuses to send back anything but XML, which just isn't appropriate for this situation. The code is essentially as follows:
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public Item ExportItem(int itemId)
{
Context.Response.AddHeader("content-disposition", "attachment; filename=export.json"); //Makes it a download
return GetExportItem(itemId);
}
Despite my specifying the ResponseFormat as JSON, I always get back XML unless I request this method via AJAX (using Google Web Toolkit, BTW):
RequestBuilder builder = new RequestBuilder(RequestBuilder.POST, "mywebserviceaddress/ExportFunc");
builder.setHeader("Content-type","application/json; charset=utf-8");
builder.setHeader("Accepts","application/json");
builder.sendRequest("{\"itemId\":2}", new RequestCallback(){...});
That's great, but AJAX won't give me a download dialog. Is there any way to force ASP.net to give me back JSON, regardless of how the data is requested? It would seem to me that not having a manual override for this behavior is a gross design oversight.
QUICK ANSWER:
First off, let me say that I think that womp's answer is probably the better way to go long term (Convert to WCF), but deostroll led me to the answer that I'll be using for the immediate future. Also, it should be noted that this seems to work primarily because I wanted just a download, may not work as well in all situations. In any case, here's the code that I ended up using to get the result I wanted:
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public void ExportItem(int itemId)
{
Item item = GetExportItem(itemId);
JavaScriptSerializer js = new JavaScriptSerializer();
string str = js.Serialize(item);
Context.Response.Clear();
Context.Response.ContentType = "application/json";
Context.Response.AddHeader("content-disposition", "attachment; filename=export.json");
Context.Response.AddHeader("content-length", str.Length.ToString());
Context.Response.Flush();
Context.Response.Write(str);
}
Please note the return type of void (which means that your WDSL will be next to useless for this function). Returning anything will screw up the response that is being hand-built.
Asp.net web services are SOAP-based web services. They'll always return XML. The Ajax libraries came along and the ScriptMethod stuff was introduced, but it doesn't change the underlying concept of it.
There's a couple things you can do.
WebMethods are borderline obsolete with the introduction of WCF. You might consider migrating your web services to WCF, in which you'll have much greater control over the output format.
If you don't want to do that, you can manually serialize the result of your webservice calls into JSON, and the service will wrap that in a SOAP header. You would then need to strip out the SOAP stuff.
Here are two forums threads for your reference:
http://forums.asp.net/t/1118828.aspx
http://forums.asp.net/p/1054378/2338982.aspx#2338982
I have no clear idea. They say on concentrating on setting the content type to application/json. I haven't worked with wcf before, but I think you can make use of the Response object.
Set the content type on the response object. Do a response.write passing your json data as string and then do a response.end.
Just thought I'd throw this out there since it wasn't mentioned previously... if you use WebServices with ASP.NET 3.5, JSON is the default return format. It also comes along with JSON serializer so you can stop using the JavascriptSerializer.
This article on Rick Strahl's blog talks about the strongly-typed conversion you can do between server side classes and JSON objects from the client.
I've recently completed a project using this new JSON stuff in .NET 3.5, and I'm extremely impressed with the performance. Maybe it's worth a look...