Sending a JSON via POST in NSURLRequest

2019-01-17 08:30发布

问题:

I have a problem with sending a JSON to a Server with REST API. This is the code i use:

NSString *jsonPostBody = [NSString stringWithFormat:@"'json' = '{\"user\":{\"username\":"
                          "\"%@\""
                          ",\"password\":"
                          "\"%@\""
                          "}}'",
                          [username stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],
                          [password stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];       
NSData *postData = [jsonPostBody dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
NSString *apiPathParams = [NSString stringWithFormat:@"%@",
                           @"getUser"
                           ];

NSURL *url = [NSURL URLWithString:[[apiPath retain] stringByAppendingString:apiPathParams]];    
NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:url
                                                       cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
                                                   timeoutInterval:180.0];
[request setHTTPMethod:@"POST"];
[request setHTTPBody:postData];
NSString* postDataLengthString = [[NSString alloc] initWithFormat:@"%d", [postData length]];
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request setValue:postDataLengthString forHTTPHeaderField:@"Content-Length"];
[self internalRequest:request];

This is what the API would look like, if it was a html form:

<form method="post" action="someAPI-URL">
<input name="json" value="{"user":...}" />
</form>

This is what my POST Data looks like when i add it to the request:

json={"user":{"username":"someUser","password":"somePassword"}}

For a reason I don't know the POST Data does not arrive at the server. Have i done something wrong with the formatting of the dataString? How exactly must i format my dataString so that it matches the String a form as shown above would deliver to the server?

Any help would be highly appreciated.

P.S. I would rather not use ASIHttpRequest, since i took over the project from somebody else an every other request works fine, except this post-request. So changing this whole bulk to an other connection framework would be very time consuming.

Here is the internalRequest Method's sourcecode

NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:req delegate:self];
NSMutableDictionary *di = [NSMutableDictionary dictionaryWithObject:[[NSMutableData alloc] init] forKey:@"receivedData"];   
[di setObject:[NSString stringWithFormat:@"%i",identifier] forKey:@"identifier"];
if (delegate == nil) 
{ 
    delegate = self;         
}
[di setObject:delegate forKey:@"delegate"];

CFDictionaryAddValue(connectionToInfoMapping, connection, di)

回答1:

since you try to submit a HTTP POST header like

json={"user":{"username":"%@","password":"%@"}},

this example is fully qualified to end up in confusion.

It's a mixture of application/x-www-form-urlencoded for the whole body and application/json for the value.

Maybe a way to resolve this:

You'll probably need to adjust that HTTP header:

 [request setValue:@"application/x-www-form-urlencoded" 
forHTTPHeaderField:@"Content-Type"];

due to an encoding of the JSON part (value) of the HTTP body:

[request setHTTPBody:[[jsonPostBody stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding]
                      dataUsingEncoding:NSUTF8StringEncoding 
                   allowLossyConversion:YES]];    

where stringByAddingPercentEscapesUsingEncoding is objective c jabberwocky for the PHP equivalent urlencode.

HTH



回答2:

I think you have to use a JSON framework and convert jsonPostBody to it's JSON representation before sending it. Check this accepted answer , it shows how to build the request.



回答3:

Does this web service has a web client that you can use your browser and test. I reccomend you that if they have a web client already try using Mozilla Firefox with the plug-in firebug and check what data and headers are being sent to server with a request also it is possible to see the json string in post data tab.

After you make sure what sort of message the server expect then you can create the exact same message by yourself and send it.

For what reason you try to create your own json I dont know, but I reccomend you to use a third party library such as JSON Framework. Also I reccomend you to use ASIHttpRequest library for http requests. It makes everything eaasy.

But first thing is first, you need to be sure the type of the message, what are the parameters, headers, type and data...



回答4:

You can test different headers and form parameters using the Chrome Advanced Rest Client. So, before coding you could know how the web service is behaving using this tool.