send JSON with POST to Restful web service - iphone

i want to send JSON with POST/PUT i don't know if it's the same think .
This is the json .
{"author":"mehdi","email":"email#hotmail.fr","message":"Hello2"}
this is my wadl .
<resource path="/messages/"><method id="get" name="GET"><request><param name="start" style="query" type="xs:int" default="0"/><param name="max" style="query" type="xs:int" default="10"/><param name="expandLevel" style="query" type="xs:int" default="1"/><param name="query" style="query" type="xs:string" default="SELECT e FROM Message e"/></request><response><representation mediaType="application/xml"/><representation mediaType="application/json"/></response></method><method id="post" name="POST"><request><representation mediaType="application/xml"/><representation mediaType="application/json"/></request><response><representation mediaType="*/*"/></response></method><resource path="{keyid}/"><param name="keyid" style="template" type="xs:int"/><method id="get" name="GET"><request><param name="expandLevel" style="query" type="xs:int" default="1"/></request><response><representation mediaType="application/json"/></response></method></resource></resource>
When i trie to post with netbeans "Test restful webservice " it work and this is wat the http monitor show
Status: 201 (Created)
Time-Stamp: Sat, 21 May 2011 20:30:33
GMT
Sent:
{"author":"mehdi","email":"email#hotmail.fr","message":"Hello2"}
Received:
Request: POST
http://localhost:8080/TRESTful/resources/messages/?
timestamp=1306009225785
Status: 201 (Created)
Time-Stamp: Sat, 21 May 2011 20:20:25
GMT
Sent:
{"author":"mehdi","email":"email#hotmail.fr","message":"Hello2"}
But now i dont know how it with ASIHttpRequest .first should i make [request setRequestMethod:#"PUT"]; ? and should i send all the json like a string , or put each value with hey key , like this :
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setPostValue:#"Ben" forKey:#"author"];
[request setPostValue:#"Copsey" forKey:#"email"];
[request setPostValue:#"Hello2" message:#"author"];
[request startSynchronous];
or should i put the JSON string in one value ?
Help please .

Well if you want to send a json you have two options:
a) Send it in a file
-Use this if you have a lot of data in a json and you may want to store it on the server for later parsing.
b) Send it as string in one value
-Use this if your json is short and you want to parse it immediately
EDIT
c) Send it as seperate values if you want to skip parsing on the server and access data directly. This should be used if there is few data.

Related

Call soap web-service in mobilefirst hybrid app

I'm attempting to call SOAP Web-Service in hybrid app. How should I form SOAP message correctly if the back-end service displays the next error in log:
Caused by: com.ibm.websphere.security.WSSecurityException: Exception
org.apache.axis2.AxisFault: CWWSS7509W: The received SOAP request
message is rejected becasue it does not correctly specify SOAP action
and WS-Addressing action while there is at least one PolicySet
attachment at operation level of the
TestServiceService.TestServicePort service. ocurred while running
action:
com.ibm.ws.wssecurity.handler.WSSecurityConsumerHandler$1#9b5addf6 at
com.ibm.ws.security.context.ContextImpl.runWith(ContextImpl.java:394)
at
com.ibm.ws.wssecurity.platform.websphere.auth.WSSContextImpl.runWith(WSSContextImpl.java:65)
... 35 more
This is content of js file in adapter
function getToken(){
var token = WL.Server.getActiveUser().attributes.LtpaToken;
var fulltoken = "LtpaToken2=" + token;
return fulltoken;
}
function callService(){
WL.Logger.warn("INSIDE callService "+getToken());
var path="checkauth/TestServiceService";
var request=
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:q0="http://provider.ws/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<q0:callService />
</soapenv:Body>
</soapenv:Envelope>;
var input = {
method : 'post',
returnedContentType : 'xml',
path : path,
body: {
content: request.toString(),
contentType: 'text/xml; charset=utf-8',
},
headers: {"Cookie": getToken()}
};
var result= WL.Server.invokeHttp(input);
return result;
}
This is SOAP Envelope which was displayed via TCP/IP Monitor:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
<s:Security xmlns:s="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:w2="http://www.ibm.com/websphere/appserver/tokentype" soapenv:mustUnderstand="1">
<u:Timestamp>
<u:Created>2015-08-10T13:18:56.644Z</u:Created>
</u:Timestamp>
<s:BinarySecurityToken ValueType="w2:LTPAv2" u:Id="ltpa_20">dt8G5gZ9PpZ/Ea5oXr6EQd8dpmfXKiqeXiShPlpSWntK59hUzyoDNX9TKq1nFLfxUEJyJdjMxoG7EVxw8Q1zhyZdYhTXnsMkNVqScvSsPpX7ln/ad+/WAHqaaFymD8XtVEsjOlezQDarPaUmnKAQRUSrLkRnL5B1MoCclTe129Oojg8o+hACgDKjuvPnvL8jaf45wNiou6Il5ZOayBcoHpNehI7i2hADa4fTKzX/T69OPnsZOyWYrNosdezNd24b61vs85k2YK26rLTp5dkEp8f3mwKZBwOOK4z1wQdiAXJf6kQvzR22SfFitbJA5MStlBcovHAvB5T+J5Ip80/kI5BPa2ogoufd9HZAdKTNII8cHpHBN2Ub/+atzg1L7EhIWuzO1BPI62KoU/hPqAHn3uGCGrbIILesKx0TPvlgmU4Bg54H9prC0I8hgXbO1HLuz4M5DNE5ASFbH0W3LJ/UU7BGXJs6iJmfAfJtQ+ip5ZFHlLItZA+ca2LkVWmyD/xKVxyxHE1uDz8zV/CfV9Km0T+8FTA0Cfi/PIb5KiAagdrmqtw6GuJDbSCsC3sdh21G/cA3Y0p/f+rhDw8m/e17y1cEuq9HOBharwn7ET3wO30V4D4rGoLhd4QsN6X1z89gZmZVaI6J9urpPAEiSndmyQ==</s:BinarySecurityToken>
</s:Security>
<wsa:To>http://X.X.X.X:9082/checkauth/TestServiceService</wsa:To>
<wsa:MessageID>urn:uuid:5d1f8656-5550-40d2-9f39-c58f57279489</wsa:MessageID>
<wsa:Action>http://provider.ws/TestServiceDelegate/callServiceRequest</wsa:Action>
</soapenv:Header>
<soapenv:Body>
<ns2:callService xmlns:ns2="http://provider.ws/"/>
</soapenv:Body></soapenv:Envelope>
The body consists of a single line, and this makes the scenario a peculiar one, as well as raises a question is this is meant to work at all.
I can suggest two things:
You can attempt to parse your WSDL file with the SOAPUI application; it should show you how the SOAP envelope is supposed to look like
Use the Service Discovery feature in MobileFirst Studio that can generate the adapter for you with a ready SOAP envelope. Read more how to use this feature, here: http://www-01.ibm.com/support/knowledgecenter/SSHS8R_7.0.0/com.ibm.worklight.dev.doc/dev/c_using_service_discovery_wizard_to_explore_backend-services.html

Delete Object in Restkit .20 did not take JSON Values

I have an API which is used to delete a record in server DB. I used to construct the API with the request ID .It was working with CURL, but in Restkit it seems to give an error.
The Curl is:
curl -d '{eve:{mod_policy:"current"}}' -X DELETE -H Content-Type:application/json https://myurl.com/eve/eve_id?token=my_aut_token\&apikey=myapi_key.
I checked with POST & PATCH. It takes the JSON as a correct form.
My RestKit Code Sample:
RKObjectMapping *requestMapping = [RKObjectMapping requestMapping];
[requestMapping addAttributeMappingsFromDictionary:#{ #"modPolicy" : #"mod_policy"}];
RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:requestMapping objectClass:[Event class] rootKeyPath:#"eve"];
RKObjectMapping *responseMapping = [RKObjectMapping mappingForClass:[Events class]];
[responseMapping addAttributeMappingsFromDictionary:#{
#"data" : #"data",
#"status":#"status"
}];
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:responseMapping pathPattern:nil keyPath:#"" statusCodes:[NSIndexSet indexSetWithIndex:200]];
[objectManager addRequestDescriptor:requestDescriptor];
[objectManager addResponseDescriptor:responseDescriptor];
NSString * urlPath = [NSString stringWithFormat:#"/eve/%#?token=%#&apikey=%#",eventID,loginToken,apiKey];
[objectManager deleteObject:hubEve path:urlPath parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *result)
{
DLog(#" response code is %d",operation.HTTPRequestOperation.response.statusCode);
Events * _event = [result firstObject];
DLog(#"status %#",_event.status);
if([_eventt.status isEqualToString:#"success"])
{
DLog("Move Next");
}
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
DLog("error %#",error);
}];
Some log details, if I send As DeleteObject in request:
request.body=(null) //Restkit Log
Or if I send as post Object/Patch Object
request.body={"eve":{"mod_policy":"all"}} //Restkit Log
Request mapping is explicitly not performed for DELETE requests. RestKit expects that when deleting you will be using the system to add parameters into the URL. You will need to plan some other method by which to delete. This could be using the RestKit mapping operation to create the payload data and then using the methods to create the URL request and setting the body data explicitly.
RESTKit does not support DELETE request with request.body parameter
natively because HTTP 1.1 doesn't support DELETE request with
request.body. There is a work around to set request.body explicitly but
its complex.
The request works well with cURL but not with HTTP, maybe because cURL
does not send DELETE request with request.body as DELETE but upgrades it
to PUT, we are not sure though.

Upload file from iPhone to Django

Sorry, a beginner's question: I have a very simple function in my Django application with which I can upload a file from a web browser to my server (works perfectly!). Now, instead of the web browser, I would like to use an iPhone.
I got a bit stuck as I don't really know how to provide Django with a valid form, i.e. we need a file name and enctype="multipart/form-data" as far as I understand.
Here is my upload function in Django:
class UploadFileForm(forms.Form):
file = forms.FileField()
def handle_uploaded_file(f):
destination = open('uploads/example.txt', 'wb+')
for chunk in f.chunks():
destination.write(chunk)
destination.close()
def upload_file(request):
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
handle_uploaded_file(request.FILES['file'])
print form
print request.FILES
return HttpResponse('Upload Successful')
else:
form = UploadFileForm()
return render_to_response('upload.html', {'form': form})
My template looks like this (upload.html):
<form action="" method="post" enctype="multipart/form-data">
{{ form.file }}
{{ form.non_field_errors }}
<input type="submit" value="Upload" />
</form>
Now, let's suppose that I want to send a simple txt file from my iPhone app to the sever.
I don't really know how to:
provide the file name
specify the enctype and
make sure that it's in a format Django can read
This is how far I got:
NSString *fileContents = [self loadTXTFromDisk:#"example.txt"];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]
initWithURL:[NSURL
URLWithString:#"http://127.0.0.1:8000/uploadfile/"]];
[request setHTTPMethod:#"POST"];
[request setValue:#"text/xml" forHTTPHeaderField:#"Content-type"];
[request setValue:[NSString stringWithFormat:#"%d", [fileContents length]]
forHTTPHeaderField:#"Content-length"];
[request setHTTPBody:[fileContents dataUsingEncoding:NSUTF8StringEncoding]];
NSURLConnection *theConnection = [[NSURLConnection alloc]
initWithRequest:request
delegate:self];
However, Django will not except this as the form it expects is not valid. Cf. above:
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid(): #this will not be true ...
The enctype from the HTML form should be the Content-Type of the HTTP request. You are currently setting the content type to 'text/xml' instead.
You will also have to build up the body as a multipart mime object. The answers to this question seem to have some code for that: File Upload to HTTP server in iphone programming
Your other option, since you have complete control of the client, is to do an HTTP PUT request. That actually looks closer to what you were doing with your original code. Change the method to 'PUT', and don't use a Django form on the other end; just access request.raw_post_data to get the complete file data.

ASIHTTPRequest Returning HTML instead of JSON

I am using ASIHTTPRequest to contact an API the problem is that it is returning html instead of JSON and i have no idea why. Everything has been working great for weeks and i can't seem to figure out what has broken..
What's strange is doing exactly the same request with a browser or postie returns the correct JSON response, but when i do the request via ASIHTTPRequest these are the response headers i get:
"Cache-Control" = "private, max-age=0, must-revalidate";
Connection = "keep-alive";
"Content-Encoding" = gzip;
"Content-Type" = "text/html; charset=utf-8";
Date = "Tue, 05 Jul 2011 21:11:10 GMT";
Etag = "\"e467792713ac4124f055c1719f4ea6c2\"";
Server = "nginx/0.7.65";
Status = "200 OK";
"Transfer-Encoding" = Identity;
"X-Runtime" = 1;
And the html (which should be json)..
<div id="universal_meta" logged_in_user_id="removed" style="display:none"></div>
<div id="meta" screen="projects" logged_in_as="removed"></div>
<h1>9 projects with 50 open issues</h1>
<ul class="biglinks progressbars">
etc...
Here is the code used to do the request..
NSURL *url = [NSURL URLWithString:path];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
if(secure){
[request setUsername:self.username];
[request setPassword:self.password];
}
[request setDelegate:self];
[request setDidFinishSelector:#selector(requestDone:)];
[request setDidFailSelector:#selector(requestWentWrong:)];
[request setDownloadDestinationPath:destination];
[[self queue] addOperation:request]; //queue is an NSOperationQueue
I have triple checked all of the login details/url, everything is correct, i would really appreciate any help with this one as i am completely lost.
--
Update:
Lighthouse have acknowledged a bug regarding headers on their side. Waiting on a solution from them.
Did you check that the headers sent using your browser are also the same as when you send the request by code?
Especially did you try to add the "Accept" header to your request to define that you accept the json Content-Type?
[request addRequestHeader:#"Accept" value:#"application/json"];
Try using a tool like wireshark or charlesproxy to compare the working requests from your browser/postie, and compare them to the non-working requests from ASIHTTPRequest - once you spot what's different it should be easy to fix.
AliSoftware's suggestion is one of the most likely differences you'll see, but it's possible there are other things too.

SOAP message error with addiotional XML tags

NSString *urlString = #"http://172.29.165.219:8090/abc/services/Abc";
NSString *soapMessage = [NSString stringWithFormat:
#"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n"
"<soap:Body>\n"
"<getUserInfo>\n"
"<email>%#</email>\n"
"<pwd>%#</pwd>\n"
"</getUserInfo>\n"
"</soap:Body>\n"
"</soap:Envelope>\n", #"babla.sharan#tcs.com",#"UGFzc0AxMjM="//,#"50006F0063006B0065007400500043000000-444556494345454D00",#"PocketPC"
];
NSMutableURLRequest *loginRequest = [RequestGenerator -generateSOAPRequestWithURLString:urlString soapMessage:soapMessage contentType:#"text/xml; charset=utf-8" action:#"getUserInfo"];
WebServiceHandler *connection = [[WebServiceHandler alloc]init];
For the Above code, it works fine, but when I add additional Tag as parent tag to id and password
NSString *urlString = #"http://172.29.165.219:8090/abc/services/Abc";
NSString *soapMessage = [NSString stringWithFormat:
#"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n"
"<soap:Body>\n"
"<getUserInfo>\n"
**"<ABC>\n"**
"<email>%#</email>\n"
"<pwd>%#</pwd>\n"
**"</ABC>\n"**
"</getUserInfo>\n"
"</soap:Body>\n"
"</soap:Envelope>\n", #"babla.sharan#tcs.com",#"UGFzc0AxMjM="//,#"50006F0063006B0065007400500043000000-444556494345454D00",#"PocketPC"
];
NSMutableURLRequest *loginRequest = [RequestGenerator generateSOAPRequestWithURLString:urlString soapMessage:soapMessage contentType:#"text/xml; charset=utf-8" action:#"getUserInfo"];
WebServiceHandler *connection = [[WebServiceHandler alloc]init];
It shows exception and get this error:
org.xml.sax.SAXException: SimpleDeserializer encountered a child element, which is NOT expected, in something it was trying to deserialize.
It doesn't even allow me to hit the server.
Here in second soap message you are sending an additional parent tag for you information, which may not be recognized by you server. If this tag is optional than there should be no problem at all, but if it is undesired then you should not use it. Below are the excerpts from W3.org(http://www.w3.org/TR/2000/NOTE-SOAP-20000508/) .... which tells about the receiving and processing of soap request.
A SOAP application receiving a SOAP message MUST process that message by performing
the following actions in the order listed below:
1. Identify all parts of the SOAP message intended for that application
2. Verify that all mandatory parts identified in step 1 are supported by
the application for this message (see section 4.2.3) and process them accordingly.
If this is not the case then discard the message .
The processor MAY ignore optional parts identified in step 1 without affecting the outcome of the processing.
3. If the SOAP application is not the ultimate destination of the message then
remove all parts identified in step 1 before forwarding the message.
Processing a message or a part of a message requires that the SOAP processor
understands, among other things, the exchange pattern being used (one way,
request/response, multicast, etc.), the role of the recipient in that pattern, the
employment (if any) of RPC mechanisms such as the one documented in section 7, the
representation or encoding of data, as well as other semantics necessary for correct
processing