iOS交互WebService(cxf框架)

时间:2023-03-09 15:22:59
iOS交互WebService(cxf框架)

公司后台java用的cxf框架,说是iOS、Android、web客户端都可以通用,但是我还是第一次遇到,所以做的时候遇到了不小的坑。下面总结下我开发中遇到的问题以及解决方案:

  首先,后台提供了一份接口文档,描述称入参以及返回内容都要严格参照JSON格式进行约束。于是我对AFHTTPSessionManager进行了如下操作:

  1.设置请求格式以及接收类型为Json

 //设置请求格式为Json
  self.requestSerializer = [AFJSONRequestSerializer serializer];
//设置返回解析接收类型为Json
AFJSONResponseSerializer *serializer = [AFJSONResponseSerializer serializer];
5  serializer.acceptableContentTypes = [NSSet setWithObjects:@"text/json",@"application/json",nil];
6  self.responseSerializer = serializer;

  然后我尝试解析后台传过来的数据,发现后台无法解析我的入参,提示是“解析到‘{’标识的时候遇到了错误”。后台提示我要不让我把“{}”去掉试试,还是失败。然后又提示我是不是没有UTF-8转码,转了之后还是报错。尝试了种种后,后台使用SoapUI工具把他发的请求与响应展示我看了下。对,是SOAP!原来所说的JSON格式是在SOAP协议包裹里的JSON格式,所以其实是XML包JSON的格式收发请求与响应的。利用SOAPUI工具我拿到了SOAP协议的XML通用格式:

 soapMsg = [NSString stringWithFormat:@"<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ser=\"http://service.%@.xzb.com/\">"
"<soapenv:Header/>"
"<soapenv:Body>"
"<ser:%@>"
"<arg0>%@</arg0>"
"</ser:%@>"
"</soapenv:Body>"
"</soapenv:Envelope>",serPre,action,[self dictionaryToJson:arguDict],action];//这里将我用到的参数传了进去

当然还有字典转JSON字符串的方法:

- (NSString*)dictionaryToJson:(NSDictionary *)dic

{
NSError *parseError = nil;
if (dic == nil) {
return nil;
}
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dic options:NSJSONWritingPrettyPrinted error:&parseError];
return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
}

完整封装MutableRequest的方法如下:

- (NSMutableURLRequest *)SOAPWithService:(NSString *)service action:(NSString *)action arguDict:(NSDictionary *)arguDict
{
//这里service是指后台写的服务名称,action表示服务下具体的某个方法:比如:sysService/queryLocation 系统服务下的,查询地理信息方法
NSURL *url = [NSURL URLWithString:BASEURL(service)];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; NSString *soapMsg = @""; if (arguDict != nil) { soapMsg = [NSString stringWithFormat:@"<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ser=\"http://service.%@.xzb.com/\">"
"<soapenv:Header/>"
"<soapenv:Body>"
"<ser:%@>"
"<arg0>%@</arg0>"
"</ser:%@>"
"</soapenv:Body>"
"</soapenv:Envelope>",serPre,action,[self dictionaryToJson:arguDict],action];
}else{ //由于没有参数和有参数时XML有点不同,所以这里进行了区分
soapMsg = [NSString stringWithFormat:@"<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ser=\"http://service.%@.xzb.com/\">"
"<soapenv:Header/>"
"<soapenv:Body>"
"<ser:%@/>"
"</soapenv:Body>"
"</soapenv:Envelope>",serPre,action];
}
NSString *soapLength = [NSString stringWithFormat:@"%lu", (unsigned long)[soapMsg length]]; [request addValue:@"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
[request addValue:soapLength forHTTPHeaderField:@"Content-Length"];
[request setTimeoutInterval:];
[request setHTTPMethod:@"POST"];
[request setHTTPBody:[soapMsg dataUsingEncoding:NSUTF8StringEncoding]];
return request;
}

接着用sessionManager发请求就好了

 AFHTTPSessionManager *mgr = [AFHTTPSessionManager manager];

 NSURLSessionDataTask *task = [mgr.session dataTaskWithRequest:[self SOAPWithService:service action:action arguDict:arguDict] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {         //解析数据,利用回调block把数据传出去
}]; [task resume];

ps.SOAP协议是基于POST请求的,所以全部都是用POST进行请求的。