Web Service 傳輸大型資料物件 (如報表、文檔、圖片 Base64) 或在低頻寬網路環境下調用,啟用資料流壓縮可顯著減小封包體積、提升傳輸效能。CXF 內建 GZIP 攔截器支援雙向壓縮/解壓。
package com.googlecode.garbagecan.cxfstudy.compress;
public class BigData {
private String name;
private String data; // 模擬大字串
public BigData() {}
public BigData(String name, int size) {
this.name = name;
StringBuilder sb = new StringBuilder(size);
for (int i = 0; i < size; i++) sb.append('0');
this.data = sb.toString();
}
// getter/setter 略
}
@WebService
public interface BigDataService {
@WebMethod
@WebResult
BigData getBigData(@WebParam String name, @WebParam int size);
}
public class BigDataServiceImpl implements BigDataService {
public BigData getBigData(String name, int size) {
return new BigData(name, size);
}
}
public class BigDataServiceTest {
private static final String ADDRESS = "https://localhost:9000/ws/compress/bigDataService";
@BeforeClass
public static void setUpBeforeClass() {
JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean();
factory.getInInterceptors().add(new LoggingInInterceptor());
factory.getOutInterceptors().add(new LoggingOutInterceptor());
// 伺服端:解壓請求、壓縮回應
factory.getInInterceptors().add(new GZIPInInterceptor());
factory.getOutInterceptors().add(new GZIPOutInterceptor());
factory.setServiceClass(BigDataServiceImpl.class);
factory.setAddress(ADDRESS);
factory.create();
}
@Test
public void testGetBigData() {
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setAddress(ADDRESS);
factory.setServiceClass(BigDataService.class);
Object proxy = factory.create();
Client client = ClientProxy.getClient(proxy);
Endpoint endpoint = client.getEndpoint();
// 客戶端:壓縮請求、解壓回應
endpoint.getInInterceptors().add(new GZIPInInterceptor());
endpoint.getOutInterceptors().add(new GZIPOutInterceptor());
BigDataService service = (BigDataService) proxy;
String name = "my big data";
int size = 10 * 1024 * 1024; // 10 MB 字串
long start = System.currentTimeMillis();
BigData result = service.getBigData(name, size);
long elapsed = System.currentTimeMillis() - start;
assertNotNull(result);
assertEquals(name, result.getName());
assertEquals(size, result.getData().length());
System.out.println("Transfer 10MB took " + elapsed + " ms");
}
}
GZIPInInterceptor:自動解壓帶有 Content-Encoding: gzip 的輸入流。GZIPOutInterceptor:自動壓縮輸出流並加上 Content-Encoding: gzip 標頭。LoggingIn/OutInterceptor) 可觀察壓縮前後報文大小差異。啟用 GZIP 壓縮僅需幾行攔截器配置,即可大幅降低大數據 Web Service 的頻寬與延遲成本。