这两天一直在搞一个问题,请求接口要就是添加请求头,本想着这个简单呀,(本人用的AFNetworking3.0),afnet封装好的添加header:
[manager.requestSerializer setValue:@"XXX" forHTTPHeaderField:@"UserPW"];
[manager.requestSerializer setValue:@"XXX" forHTTPHeaderField:@"UserID"];
但是就是请求不成功,期间也问了一些朋友都说他们也是这样添加的,安卓的也可以请求成功,这就很尴尬了!!!
难道Webservice的SOAP请求这么难?于是就开始查资料,发现还是自己想简单了,SOAP请求不能直接这样添加header(或许也可以,可能我们的情况比较特殊),看下SOAP请求的测试。
SOAP协议实际上就是一种基于XML编码规范的文本协议。目前WebService的协议主要有SOAP1.0、SOAP1.1和1.2(我们用的是1.1)。soap默认POST请求,GET好像不可以,SOAP协议的版本会影响请求是否成功。
SOAP1.1
SOAP1.2
上面框内就是请求头的添加,我们的服务器还加了请求头识别WyxSoapHeader,必须要有这个,不然请求不成功。下面的框内是参数。你还会发现这个两个框内都有一个东西就是:
<WyxSoapHeader xmlns=\"http://www.wincansoft.com/wyxsms\">
<VerifyAppUserPassword xmlns=\"http://www.wincansoft.com/wyxsms\">
这里的WyxSoapHeader上面说了,VerifyAppUserPassword就是接口方法,http://www.wincansoft.com/wyxsms
就是命名空间,这些个都是后台给的,没有找他要。这里要注意,这个地址并不是你请求数据的真正地址。
下面我们就要开始按照上面的格式拼接SOAP1.1字符串:举个例子
<?xml version="1.0" encoding="utf-8"?>
<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/">
<soap:Header>
<WyxSoapHeader xmlns="http://www.wincansoft.com/wyxsms">
<UserID>xxxx</UserID>
<UserPW>xxxx</UserPW>
....(添加更多header)
</WyxSoapHeader>
</soap:Header>
<soap:Body>
<AssignSermoBill xmlns="http://www.wincansoft.com/wyxsms">
<iAssignStaffID>XXX</iAssignStaffID>
<sAssignDataJson>XXX</sAssignDataJson>
....(添加更多参数)
</AssignSermoBill>
</soap:Body>
</soap:Envelope>
开发的时候,不能每调用一次接口,都写一遍这一大串东西吧,把这个写成一个方法供外部调用就OK啦。首先要封装一个参数生成字符串方法:
+ (NSString *)getParameters:(NSDictionary *)dictionary
{
NSString *pamateString = @"";
NSArray * allkeys = [dictionary allKeys];
for (int i = 0; i < allkeys.count; i++)
{
NSString * key = [allkeys objectAtIndex:i];
//如果你的字典中存储的多种不同的类型,那么最好用id类型去接受它
id obj = [dictionary objectForKey:key];
NSString *string = [NSString stringWithFormat:@"<%@>%@</%@>\n",key,obj?obj:@"",key];
pamateString = [pamateString stringByAppendingString:string];
}
//NSLog(@"pamateString==%@",pamateString);
return pamateString;
}
再封装SOAP字符串:
+ (NSString *)getSOAPString:(NSString *)parame interface:(NSString *)interf
{
NSString *soapStr = [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:Header>\n"
"<WyxSoapHeader xmlns=\"http://www.wincansoft.com/wyxsms\">\n"
"<UserID>xxx/UserID>\n"
"<UserPW>xxx</UserPW>\n"
"</WyxSoapHeader>\n"
"</soap:Header>\n"
"<soap:Body>\n"
"<%@ xmlns=\"http://www.wincansoft.com/wyxsms\">\n"
"%@"
"</%@>\n"
"</soap:Body>\n"
"</soap:Envelope>\n",interf,parame,interf];
return soapStr;
}
OK,到这里准备工作基本完毕,现在开始请求:
NSString *soapStr = [UIUtils getSOAPString:[UIUtils getParameters:这里是参数字典] interface:@"这里是接口方法"];
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
// 返回NSData
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
// 设置请求头,也可以不设置,看自己的需求解开注释,一般不需要
//[manager.requestSerializer setValue:@"http://www.wincansoft.com/wyxsms/QueryUserID" forHTTPHeaderField:@"SOAPAction"];
//[manager.requestSerializer setValue:@"51serapp.wincansoft.net" forHTTPHeaderField:@"Host"];
//[manager.requestSerializer setValue:[NSString stringWithFormat:@"%zd", soapStr.length] forHTTPHeaderField:@"Content-Length"];
// 这个设置是必须的
[manager.requestSerializer setValue:@"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
// 设置HTTPBody
[manager.requestSerializer setQueryStringSerializationWithBlock:^NSString *(NSURLRequest *request, NSDictionary *parameters, NSError *__autoreleasing *error){
return soapStr;
}];
[manager POST:URLString parameters:soapStr progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSDictionary *dicRes = [NSDictionary dictionaryWithXMLData:responseObject];
NSLog(@"JSON: - %@", dicRes);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
}];
上面的URLString是请求地址,不知道是啥或没有问后台要,他清楚的。
OK到这里,一个完整的SOAP带有请求头的请求就完成了。
注意:上文SOAP中xmlns对应的url并不是你真正的数据请求地址(xmlns=\"http://www.wincansoft.com/wyxsms\"
),http://www.wincansoft.com/wyxsms
只是后台给的一个验证地址(换成你们自己的),这个地址是不变的,没有的话,管后台要。当你进行POST请求的时候,例如登录、注册等等,后台还会有相应的登录、注册接口,也就是上文的URLString。
安卓的就简单多了,不需要拼接这些玩意:
直接设置就好了,羡慕!!!