zoukankan      html  css  js  c++  java
  • iOS与Java服务器GZip压缩问题【转】

    昨天搞了一天的GZip压缩,试了三种方式(libz库,ZipArchive,ASIHttpRequest),一开始都不成功。
    理论上三个应该都能用的,但我都不行。等我试到第三种方式的时候才知道,不是我的问题,而是后台的问题(Java端输出方式一会再说)。
    今天就总结一下,写写iOS与Java服务器获取压缩数据的方法吧。
    一、客户端-服务端数据压缩解压流程(ASIHttpRequest)
    客户端生成request,设置header允许使用压缩("Accept-Encoding","gzip"),即是告诉服务器,客户端支持压缩,但凡 可以压缩的服务器,尽管来吧!服务器收到这个header,如果它支持压缩,可以通过压缩方式输出数据,然后再写入response的 header("Content-Encoding","gzip")
    1.以ASIHttpRequest为例,代码如下:
     

       NSURL* requestURL = [NSURL URLWithString:_listURL];
        ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:requestURL];
        // 默认为YES, 你可以设定它为NO来禁用gzip压缩
        [request setAllowCompressedResponse:YES];
        [request setDelegate:self];
        [request startAsynchronous];
    如果是普通的URLRequest,只要:
        request.setHeader("Accept-Encoding","gzip");
    2.服务器端返回:
        response.setHeader("Content-Encoding","gzip");
    3.客户端响应,同样以ASIHttpRequest为例(此例传输的是json数据,我还使用了SBJson解析一下):
    - (void)requestFinished:(ASIHTTPRequest *)request{
        NSString *jsonString = @"";
        SBJsonParser* jsonParser = [[SBJsonParser alloc] init];
        NSMutableDictionary *jsonDictionary = nil;
       
        BOOL dataWasCompressed = [request isResponseCompressed]; // 响应是否被gzip压缩过?
        if (dataWasCompressed) {
            NSData *uncompressedData = [request responseData]; // 解压缩后的数据
            NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
            jsonString = [[NSString alloc]initWithData:uncompressedData encoding:enc];
            jsonDictionary = [jsonParser objectWithString:jsonString error:nil];
            [jsonString release];

        } else {
            jsonString = [request responseString];
            jsonDictionary = [jsonParser objectWithString:jsonString error:nil];
        }
       
        self._tableDict = jsonDictionary;
        [jsonParser release];
        [self loadTableDict];
       
        [self release];
    }
    附上一篇非常详细的ASIHttpRequest请求Json数据教程(无GZip相关内容):
    http://ios-blog.co.uk/articles/tutorials/parsing-json-on-ios-with-asihttprequest-and-sbjson/

    libz库
    libz库是官方的一个库,貌似ASIHttpRequest也是用这个库解压的,当我们获得压缩过的data数据以后(方法与上面类似,只是获得了普通 的data数据响应),可以使用这种方法解压数据,解压方法如下所示(如果仅仅放在当前类下面使用,传个data参数进来,然后把self换成变量名):
    #include 
    @implementation NSData (DDData)
    - (NSData *)gzipInflate { if ([self length] == 0) return self;
    unsigned full_length = [self length]; unsigned half_length = [self length] / 2;
    NSMutableData *decompressed = [NSMutableData dataWithLength: full_length + half_length]; BOOL done = NO; int status;
     z_stream strm; strm.next_in = (Bytef *)[self bytes]; strm.avail_in = [self length]; strm.total_out = 0; strm.zalloc = Z_NULL; strm.zfree = Z_NULL;

     if (inflateInit2(&strm, (15+32)) != Z_OK) return nil;
    while (!done) { // Make sure we have enough room and reset the lengths. if (strm.total_out >= [decompressed length]) [decompressed increaseLengthBy: half_length]; strm.next_out = [decompressed mutableBytes] + strm.total_out; strm.avail_out = [decompressed length] - strm.total_out; // Inflate another chunk.
    status = inflate (&strm, Z_SYNC_FLUSH);
    if (status == Z_STREAM_END) done = YES;
    else if (status != Z_OK) break;
    }
    if (inflateEnd (&strm) != Z_OK) return nil;
    // Set real length. if (done) { [decompressed setLength: strm.total_out];
    return [NSData dataWithData: decompressed]; } else return nil; }

    附上一篇非常详细的libz库压缩教程
    http://www.clintharris.net/2009/how-to-gzip-data-in-memory-using-objective-c/
    以及压缩解压教程(代码从这里拷贝的):
    http://deusty.blogspot.com/2007/07/gzip-compressiondecompression.html
    ZipArchive
    上面讲的都是Memory压缩与解压,ZipArchive主要是对文档进行处理。
    昨天在上述方法不成功的情况下,我把获取的data数据savetofile,然后再处理,理论上是可行的,但是由于服务器有误,获取的数据不对,所以我怎么都解压不成功!!!!
    示例如下:
    Objective-C class used to zip / unzip compressed zip file.

    Usage:
    Add all the files to you project, and and framework libz.1.2.3.dylib.

    include ZipArchive.h using #import "ZipArchive/ZipArchive.h"

    * create zip file
    ZipArchive* zipFile = [[ZipArchive alloc] init];
    [zipFile CreateZipFile2:@"zipfilename"]; // A
    OR
    [[zipFile CreateZipFile2:@"zipfilename" Password:@"your password"];// if password needed,
                                       //empty password will get same result as A

    [zipFile addFileToZip:@"fullpath of the file" newname:@"new name of the file without path"];
    ....add any number of files here
    [zipFile CloseZipFile2];
    [zipFile release]; // remember to release the object

    * unzip compressed file
    ZipArchive* zipFile = [[ZipArchive alloc] init];
    [zipFile UnzipOpenFile:@"zip file name"]; // B (the zip got no password)
    OR
    [zipFile UnzipOpenFile:@"zip file name" Password:@"password" ];

    [zipFile UnzipFileTo:@"output path" overwrite:YES];
    [zipFile UnzipCloseFile];
    [zipFile release];
  • 相关阅读:
    idea 快捷键
    python 之网页解析器
    python 之正则表达式
    Python Requests快速入门
    Html style="visibility:hidden"与style="display:none"的区别
    html 之table标签结构学习
    python 之format字符串格式化
    Python 时间戳和日期相互转换
    SQL 字符串函数
    xampp默认配置拿shell
  • 原文地址:https://www.cnblogs.com/horo/p/2647082.html
Copyright © 2011-2022 走看看