日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

如何用Django處理gzip數(shù)據(jù)流

瀏覽:266日期:2024-09-13 17:51:13

最近在工作中遇到一個(gè)需求,就是要開(kāi)一個(gè)接口來(lái)接收供應(yīng)商推送的數(shù)據(jù)。項(xiàng)目采用的python的django框架,我是想也沒(méi)想,就直接一梭哈,寫(xiě)出了如下代碼:

class XXDataPushView(APIView): ''' 接收xx數(shù)據(jù)推送 '''# ... @white_list_required def post(self, request, **kwargs): req_data = request.data or {}# ...

但隨后,發(fā)現(xiàn)每日數(shù)據(jù)并沒(méi)有任何變化,質(zhì)問(wèn)供應(yīng)商是否沒(méi)有做推送,在忽悠我們。然后對(duì)方給的答復(fù)是,他們推送的是gzip壓縮的數(shù)據(jù)流,接收端需要主動(dòng)進(jìn)行解壓。此前從沒(méi)有處理過(guò)這種壓縮的數(shù)據(jù),對(duì)方具體如何做的推送對(duì)我來(lái)說(shuō)也是一個(gè)黑盒。

因此,我要求對(duì)方給一個(gè)推送的簡(jiǎn)單示例,沒(méi)想到對(duì)方不講武德,仍過(guò)來(lái)一段沒(méi)法單獨(dú)運(yùn)行的java代碼:

private byte[] compress(JSONObject body) { try { ByteArrayOutputStream out = new ByteArrayOutputStream(); GZIPOutputStream gzip = new GZIPOutputStream(out); gzip.write(body.toString().getBytes()); gzip.close(); return out.toByteArray(); } catch (Exception e) { logger.error('Compress data failed with error: ' + e.getMessage()).commit(); } return JSON.toJSONString(body).getBytes();}public void post(JSONObject body, String url, FutureCallback<HttpResponse> callback) { RequestBuilder requestBuilder = RequestBuilder.post(url); requestBuilder.addHeader('Content-Type', 'application/json; charset=UTF-8'); requestBuilder.addHeader('Content-Encoding', 'gzip'); byte[] compressData = compress(body); int timeout = (int) Math.max(((float)compressData.length) / 5000000, 5000); RequestConfig.Builder requestConfigBuilder = RequestConfig.custom(); requestConfigBuilder.setSocketTimeout(timeout).setConnectTimeout(timeout); requestBuilder.setEntity(new ByteArrayEntity(compressData)); requestBuilder.setConfig(requestConfigBuilder.build()); excuteRequest(requestBuilder, callback);}private void excuteRequest(RequestBuilder requestBuilder, FutureCallback<HttpResponse> callback) { HttpUriRequest request = requestBuilder.build(); httpClient.execute(request, new FutureCallback<HttpResponse>() { @Override public void completed(HttpResponse httpResponse) { try {int responseCode = httpResponse.getStatusLine().getStatusCode();if (callback != null) { if (responseCode == 200) { callback.completed(httpResponse); } else { callback.failed(new Exception('Status code is not 200')); }} } catch (Exception e) {logger.error('Get error on ' + requestBuilder.getMethod() + ' ' + requestBuilder.getUri() + ': ' + e.getMessage()).commit();if (callback != null) { callback.failed(e);} } EntityUtils.consumeQuietly(httpResponse.getEntity()); } @Override public void failed(Exception e) { logger.error('Get error on ' + requestBuilder.getMethod() + ' ' + requestBuilder.getUri() + ': ' + e.getMessage()).commit(); if (callback != null) {callback.failed(e); } } @Override public void cancelled() { logger.error('Request cancelled on ' + requestBuilder.getMethod() + ' ' + requestBuilder.getUri()).commit(); if (callback != null) {callback.cancelled(); } } });}

從上述代碼可以看出,對(duì)方將json數(shù)據(jù)壓縮為了gzip數(shù)據(jù)流stream。于是搜索django的文檔,只有這段關(guān)于gzip處理的裝飾器描述:

django.views.decorators.gzip 里的裝飾器控制基于每個(gè)視圖的內(nèi)容壓縮。

gzip_page()

如果瀏覽器允許 gzip 壓縮,那么這個(gè)裝飾器將壓縮內(nèi)容。它相應(yīng)的設(shè)置了 Vary 頭部,這樣緩存將基于 Accept-Encoding 頭進(jìn)行存儲(chǔ)。

但是,這個(gè)裝飾器只是壓縮請(qǐng)求響應(yīng)至瀏覽器的內(nèi)容,我們目前的需求是解壓縮接收的數(shù)據(jù)。這不是我們想要的。

幸運(yùn)的是,在flask中有一個(gè)擴(kuò)展叫flask-inflate,安裝了此擴(kuò)展會(huì)自動(dòng)對(duì)請(qǐng)求來(lái)的數(shù)據(jù)做解壓操作。查看該擴(kuò)展的具體代碼處理:

# flask_inflate.pyimport gzipfrom flask import requestGZIP_CONTENT_ENCODING = ’gzip’class Inflate(object): def __init__(self, app=None): if app is not None: self.init_app(app) @staticmethod def init_app(app): app.before_request(_inflate_gzipped_content)def inflate(func): ''' A decorator to inflate content of a single view function ''' def wrapper(*args, **kwargs): _inflate_gzipped_content() return func(*args, **kwargs) return wrapperdef _inflate_gzipped_content(): content_encoding = getattr(request, ’content_encoding’, None) if content_encoding != GZIP_CONTENT_ENCODING: return # We don’t want to read the whole stream at this point. # Setting request.environ[’wsgi.input’] to the gzipped stream is also not an option because # when the request is not chunked, flask’s get_data will return a limited stream containing the gzip stream # and will limit the gzip stream to the compressed length. This is not good, as we want to read the # uncompressed stream, which is obviously longer. request.stream = gzip.GzipFile(fileobj=request.stream)

上述代碼的核心是:

request.stream = gzip.GzipFile(fileobj=request.stream)

于是,在django中可以如下處理:

class XXDataPushView(APIView): ''' 接收xx數(shù)據(jù)推送 '''# ... @white_list_required def post(self, request, **kwargs): content_encoding = request.META.get('HTTP_CONTENT_ENCODING', '') if content_encoding != 'gzip': req_data = request.data or {} else: gzip_f = gzip.GzipFile(fileobj=request.stream) data = gzip_f.read().decode(encoding='utf-8') req_data = json.loads(data) # ... handle req_data

ok, 問(wèn)題完美解決。還可以用如下方式測(cè)試請(qǐng)求:

import gzipimport requestsimport jsondata = {}data = json.dumps(data).encode('utf-8')data = gzip.compress(data)resp = requests.post('http://localhost:8760/push_data/',data=data,headers={'Content-Encoding': 'gzip', 'Content-Type':'application/json;charset=utf-8'})print(resp.json())

以上就是如何用Django處理gzip數(shù)據(jù)流的詳細(xì)內(nèi)容,更多關(guān)于Django處理gzip數(shù)據(jù)流的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: Django
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
国产精品二区影院| 日韩三级视频| 精品视频在线观看网站| 香蕉久久夜色精品国产| 啪啪国产精品| 欧美视频一区| 欧美日韩一区二区三区视频播放| 国产模特精品视频久久久久| 精品一区二区三区视频在线播放| 香蕉久久久久久久av网站| 国产一区二区三区不卡视频网站 | 精品视频97| 狠狠干成人综合网| 亚洲大片在线| 午夜在线视频观看日韩17c| 国产综合色区在线观看| 麻豆精品视频在线| 亚洲a成人v| 久久久久蜜桃| 日韩欧美看国产| 精品视频亚洲| 91成人福利| 日韩激情精品| 少妇高潮一区二区三区99| 另类国产ts人妖高潮视频| 电影亚洲精品噜噜在线观看 | 久久久久国产一区二区| 欧美日本精品| 久久精品 人人爱| 人人精品人人爱| 激情综合在线| 国产日韩综合| 欧美日韩国产高清| 伊人国产精品| 91精品成人| 天使萌一区二区三区免费观看| 综合日韩在线| 国产精品亚洲欧美| 99久久www免费| 日本欧美大码aⅴ在线播放| 国产精品午夜av| 精品亚洲二区| 四虎8848精品成人免费网站| 日本一区免费网站| 国产精品22p| 日韩精品社区| 亚洲三级网站| 麻豆精品久久久| 欧美综合精品| 美女日韩在线中文字幕| 在线亚洲观看| 国产精品美女久久久| 亚洲涩涩av| 欧美va天堂| 激情欧美丁香| 久久国产亚洲| 玖玖玖国产精品| 国产美女亚洲精品7777| 六月天综合网| 99tv成人| 国产91欧美| 99国内精品| 午夜久久中文| 久久精品亚洲| 免费日本视频一区| 欧美国产偷国产精品三区| 日本成人在线视频网站| 亚洲性色av| 国产婷婷精品| 精品视频网站| 久久99伊人| 日韩精品一区二区三区中文字幕| 综合激情一区| 国产一区二区三区自拍| 亚洲风情在线资源| 国产经典一区| 欧美一区免费| 视频一区视频二区中文字幕| 91精品在线观看国产| 婷婷亚洲精品| 久久久人人人| 国产麻豆精品| 国产亚洲一区二区三区啪| 国产精品一区亚洲| 国产欧美啪啪| 成人福利av| 久久成人国产| 视频一区二区不卡| 日本不卡高清| 国产精品午夜av| 国产一区二区三区91| 老司机精品视频网| 老司机精品视频网| 久久麻豆视频| 精品国产不卡| 免费在线日韩av| 欧美国产亚洲精品| 亚洲色图综合| 亚洲精品大全| 日韩国产一区| 手机精品视频在线观看| 91精品一区二区三区综合在线爱| 国产精品日韩精品中文字幕| 天堂网在线观看国产精品| 精精国产xxxx视频在线野外| 亚洲乱码一区| 色婷婷精品视频| 9色精品在线| 国产不卡人人| 午夜日韩影院| 成人久久一区| 欧美日一区二区在线观看| 久久高清免费| 久久久国产精品一区二区中文| 清纯唯美亚洲综合一区| 91精品国产乱码久久久久久久| 午夜视频一区二区在线观看| 精品视频国产| 狠狠干综合网| 日本亚洲视频在线| 国产精品亚洲综合色区韩国| 狠狠久久伊人中文字幕| 欧美日韩在线网站| 综合国产视频| 久久激情av| 亚洲欧洲高清| 日韩动漫一区| 亚洲激情另类| 日韩综合精品| 欧美理论视频| 日韩在线观看一区二区三区| 久久九九国产| 91中文字幕精品永久在线| 国产综合色产| 日韩av一级片| 精品三级久久| 日本精品另类| 精品丝袜在线| 日韩影片在线观看| av一区在线| 日本aⅴ亚洲精品中文乱码| 欧美成人午夜| 视频一区视频二区中文字幕| 国产精品一区二区精品视频观看| 在线看片国产福利你懂的| 日韩精品免费一区二区三区| 日韩影院精彩在线| 精品久久久久久久| 国产亚洲一区二区手机在线观看| 天堂资源在线亚洲| 日韩视频久久| 亚洲精品黄色| 国产欧美成人| 久久精品国产网站| 成人黄色av| 深夜视频一区二区| 欧美香蕉视频| 精品五月天堂| 国产精品一线| 亚洲欧美专区| 蜜桃伊人久久| 米奇777超碰欧美日韩亚洲| 亚洲黄色网址| 国产欧美日韩一区二区三区在线| 丝袜美腿亚洲一区| 亚洲激情另类| 91久久久久| 国产精品久久观看| 精品日韩一区| 国产66精品| 免费在线观看精品| 亚洲精品在线a| 亚洲精品福利电影| 欧美日本不卡| av亚洲免费| 精品一区二区三区免费看 | 91精品在线观看国产| 91麻豆精品激情在线观看最新| 韩国精品主播一区二区在线观看| 欧美在线91| 亚洲aa在线| 亚洲久久在线| 日韩av在线免费观看不卡| 伊人久久婷婷| 欧美精品高清| 国产日韩欧美一区在线| 中文字幕在线视频网站| 久久中文亚洲字幕| 91精品观看| 韩国女主播一区二区三区| 精品中文在线| 国产66精品| 三级亚洲高清视频| 日韩一区电影| 手机精品视频在线观看| 国产亚洲一区二区三区不卡| 夜久久久久久| 亚洲高清影视| 国产一卡不卡| 日本在线观看不卡视频|