0
0

More than 3 years have passed since last update.

javaでgzipの実装

Posted at

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();
        }
    }
}

以上!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0