java で gzip の実装
server.java
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.zip.GZIPOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/test")
public class TestController {
private static final Logger LOGGER = LoggerFactory.getLogger(TestController.class);
@GetMapping
public void test(HttpServletRequest request, HttpServletResponse reponse) throws IOException {
// 响应体
String content = "昔日龌龊不足夸,今朝放荡思无涯。春风得意马蹄疾,一日看尽长安花。";
String acceptEncooding = request.getHeader(HttpHeaders.ACCEPT_ENCODING);
/**
* 获取客户端支持的编码格式,程序可以根据这个header判断是否要对响应体进行编码
*/
LOGGER.info(acceptEncooding);
// 响应体使用 gzip 编码
reponse.setHeader(HttpHeaders.CONTENT_ENCODING, "gzip");
// 响应体类型是字符串
reponse.setContentType(MediaType.TEXT_PLAIN_VALUE);
// 编码是utf-8
reponse.setCharacterEncoding(StandardCharsets.UTF_8.displayName());
// Gzip压缩后响应
reponse.getOutputStream().write(gZip(content.getBytes(StandardCharsets.UTF_8)));
}
/**
* Gzip压缩数据
* @param data
* @return
* @throws IOException
*/
public static byte[] gZip(byte[] data) throws IOException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
try (GZIPOutputStream gzipOutputStream = new GZIPOutputStream(byteArrayOutputStream)) {
gzipOutputStream.write(data);
gzipOutputStream.finish();
return byteArrayOutputStream.toByteArray();
}
}
}
client.java
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.zip.GZIPInputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
public class Main {
public static final Logger LOGGER = LoggerFactory.getLogger(Main.class);
public static void main(String[] args) throws Exception {
RestTemplate restTemplate = new RestTemplate();
HttpHeaders httpHeaders = new HttpHeaders();
// Accept 表示客户端支持什么格式的响应体
httpHeaders.set(HttpHeaders.ACCEPT, MediaType.TEXT_PLAIN_VALUE);
// Accept-Encoding 头,表示客户端接收gzip格式的压缩
httpHeaders.set(HttpHeaders.ACCEPT_ENCODING, "gzip");
ResponseEntity<byte[]> responseEntity = restTemplate.exchange("http://localhost/test", HttpMethod.GET, new HttpEntity<>(httpHeaders), byte[].class);
if (!responseEntity.getStatusCode().is2xxSuccessful()) {
// TODO 非200响应
}
// 获取服务器响应体编码
String contentEncoding = responseEntity.getHeaders().getFirst(HttpHeaders.CONTENT_ENCODING);
if ("gzip".equals(contentEncoding)) { // gzip编码
// gzip解压服务器的响应体
byte[] data = unGZip(new ByteArrayInputStream(responseEntity.getBody()));
LOGGER.info(new String(data, StandardCharsets.UTF_8));
} else {
// TODO 其他的编码
}
}
/**
* Gzip解压缩
* @param inputStream
* @return
* @throws IOException
*/
public static byte[] unGZip(InputStream inputStream) throws IOException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
try (GZIPInputStream gzipInputStream = new GZIPInputStream(inputStream)) {
byte[] buf = new byte[4096];
int len = -1;
while ((len = gzipInputStream.read(buf, 0, buf.length)) != -1) {
byteArrayOutputStream.write(buf, 0, len);
}
return byteArrayOutputStream.toByteArray();
} finally {
byteArrayOutputStream.close();
}
}
}
以上!