在MeToo的研发过程中,部分模块需要使用http请求向服务器同时传输图片和一些附属信息。由于图片使用NSDATA格式传输,附属信息使用JSON格式传输,而消息的body只能支持其中一种格式,因此在只要传输JSON信息的时候,使用UTF8编码传输;在需要同时传输图片和附属信息时,将图片以二进制格式放在body里,附属信息的JSON放在header里,如下所示:
[[SVHTTPClient sharedClientWithIdentifier:@"upload"] setValue:_delegate.userID forHTTPHeaderField:@"userid"]; 。。。。。。 [[SVHTTPClient sharedClientWithIdentifier:@"upload"]POST:POSTVOTE_SERVLET parameters:[NSDictionary dictionaryWithObjectsAndKeys: imageData, @"image", nil] completion:^(id response, NSHTTPURLResponse *urlResponse, NSError *error) { …… }];
但这里有个问题,在httpheader中设置的编码格式只对body起作用,header本身只支持ascii的文本,如果将中文放在header中(即使用JSON包装也一样),传到服务器端后服务器解析不出来,从而报JSON格式错误。
解决方法是,对汉字进行UTF编码,得到类似16进制的文本串,在作为JSON的数据传输。Objectivec中的代码为:
NSString *str = @"中国1美国a23"; NSString *unicodeStr = [str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; NSLog(@"%@", unicodeStr);
输出结果为:
%E4%B8%AD%E5%9B%BD1%E7%BE%8E%E5%9B%BDa23
该结果有两点问题:
1, oc只能用”%”来标记一个字节的16进制数,而java的写法是”\x”
2, 对于latin字符,如示例中的1,2,3,a,oc不会对其进行编码,而如果用JAVA的UTF8编码会将”1”编码成”\x31”的形式
因此在还原时,不能对oc编码后的结果直接还原,而需要先将%E4替换为\xE4的形式(其实是转成0XE4形式),对于没有替换的latin字符则直接读入不做任何处理。
服务器端的java代码如下:
public static String hex2Str(String str) throws UnsupportedEncodingException { byte[] byteArr = new byte[1024]; int num=0; for (int i = 0; i < str.length();) { if (str.charAt(i)=='%'){ Integer hexInt = Integer.decode("0x" + str.charAt(i+1) + str.charAt(i+2)); byteArr[num] = hexInt.byteValue(); i+=3; num++; }else{ byteArr[num] = (byte)str.charAt(i); num++; i++; } } byteArr[num] = '\0'; return new String(byteArr, "UTF-8"); }