[英]Is there a way to detect if an incoming serialized object stream is GZIPOutputStream compressed or a simple ObjectOutputStream?
我有一個遺留系統,服務器會在幾周內緩慢更新。 層次結構是這樣的:
1
2
3 4 5
1 is the client pc
2 is a master server
3 4 and 5 are servers across the country.
目前所有這些都是以未壓縮格式來回發送POJO(普通的舊Java對象)。 想想OjbectOutputStream()等。
我想壓縮通過網絡序列化的數據,但這樣做的方式是只壓縮從查詢接收的數據。 發送的數據是微不足道的(查詢過濾器數據)。
只有客戶端#1和主服務器#2立即更新。 服務器#3,#4和#5可以相隔數周或數月更新。 我需要一種方法讓服務器#2能夠檢測從#3,#4或#5返回的流是否被壓縮並相應地處理它(當它們升級時)。
-EDIT-對於服務器#3,#4和#5,解決方案必須不引人注目。 如果發生異常,這些服務器不具有重新發送數據的概念。
以下是#2用於與#3,#4或#5通信的代碼示例:
// Set the content type to be application/x-java-serialized-object
connection.setRequestProperty("Content-Type", "application/x-java-serialized-object");
setupHeaderAttributes(getHttpHeaders());
setupSessionCookies(getHttpHeaders());
// Load/add httpHeaders
addHeadersToConnection(connection, getHttpHeaders());
// Write the serialized object as post data
objectoutputstream = new ObjectOutputStream(connection.getOutputStream());
objectoutputstream.writeObject(obj);
objectoutputstream.flush();
// Get ready to receive the reply.
inputstream = connection.getInputStream();
setHttpStatus(connection.getResponseCode());
這可能嗎? 感謝您的時間。
丹尼斯
您可以在流的標題中讀取。 GZIPOutputStream
在其他任何內容之前將GZIP標頭寫入流中,在詞法十六進制中,它看起來像:
0x1f8b 0800 0000 0000 0000
請注意,如果舊版服務器未使用Java的GZIPOutputStream
,則最后8個字節可能不同。 但是, 前2個字節將始終為0x1f8b
。 其余的標頭值只是關於它來自何處以及GZIP格式使用的其他標志的信息。
@Puce有一半的答案。 另一半是使用mark()
和reset()
來重置流,如果它不是GZipped流:
InputStream in = // stream from server
in = new BufferedInputStream(in);
in.mark(1024);
try {
in = new GZIPInputStream(in);
}
catch (ZipException ex) {
in.reset();
}
// "in" is now ready for use
BufferedInputStream
在這里有兩個目的:首先,我知道它支持標記/重置。 其次,如果底層流沒有緩沖,它將提高IO性能(盡管如果它是套接字流,它將是)。
標記值1024是任意值。 GZipInputStream
構造函數應該能夠通過讀取前兩個字符來確定底層流是否已被GZip化。 但是,GZIP標頭長度為10個字節,因此可能會嘗試讀取更多字節。 它不應該讀取超過1024個字節(如果是,則增加標記值)。
編輯:因為我從您的編輯中看到您正在使用Content-Type標頭,您還可以使用它來選擇性地解壓縮流:新服務器將返回類似x-application/java-gzipped-serialized-object
而舊服務器繼續返回x-application/serialized-java-object
(或其他任何東西)。
以“x-”開頭的內容類型不受限制; 只要兩端都同意,你就可以使用你想要的任何東西。
如果GZIPInputStream的構造函數無法處理輸入流,則拋出ZipException。
ZipException - 如果發生GZIP格式錯誤或不支持使用的壓縮方法
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.