简介项目中,请求时发送超大 json 数据外;响应时也有可能返回超大 json数据 。上一篇实现了请求数据的 gzip 压缩 。本篇通过 filter 实现对响应 json 数据的压缩 。先了解一下以下两个概念:
- 请求头:
Accept-Encoding : gzip
告诉服务器,该浏览器支持 gzip 压缩 - 响应头:
Content-Encoding : gzip
告诉浏览器,输出信息使用了 gzip 进行压缩
文章插图
pom.xml 引入依赖
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.olive</groupId> <artifactId>response-compression</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>response-compression</name> <url>http://maven.apache.org</url> <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.5.14</version><relativePath /> <!-- lookup parent from repository --> </parent> <properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target> </properties> <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.alibaba.fastjson2</groupId><artifactId>fastjson2</artifactId><version>2.0.14</version></dependency><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.9.0</version></dependency> </dependencies></project>
对Response进行包装GzipResponseWrapper 类重新定义了输出流,拦截需要输出的数据,直接缓存到 ByteArrayOutputStream 中 。package com.olive.filter;import lombok.extern.slf4j.Slf4j;import javax.servlet.ServletOutputStream;import javax.servlet.WriteListener;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpServletResponseWrapper;import java.io.*;@Slf4jpublic class GzipResponseWrapper extends HttpServletResponseWrapper {/*** 字节数组缓冲流,用来保存截获到的输出数据*/private ByteArrayOutputStream buffer;/*** 重新定义servlet输出流,改变输出目的地将响应内容输出到给定的字节数组缓冲流中*/private GzipResponseWrapper.CustomServletOutputStream servletOutputStream;/*** 同上*/private PrintWriter writer;public GzipResponseWrapper(HttpServletResponse response) {super(response);//original HttpServletResponse objectbuffer = new ByteArrayOutputStream();servletOutputStream = new GzipResponseWrapper.CustomServletOutputStream(buffer);try {writer = new PrintWriter(new OutputStreamWriter(buffer, response.getCharacterEncoding()), true);} catch (UnsupportedEncodingException e) {log.error("GZipHttpServletResponse", e);}}@Overridepublic ServletOutputStream getOutputStream() throws IOException {return servletOutputStream;}@Overridepublic PrintWriter getWriter() throws IOException {return writer;}@Overridepublic void flushBuffer() throws IOException {if (servletOutputStream != null) {servletOutputStream.flush();}if (writer != null) {writer.flush();}}/*** 向外部提供一个获取截获数据的方法* @return 从response输出流中截获的响应数据*/public byte[] getOutputData() throws IOException {flushBuffer();return buffer.toByteArray();}private static class CustomServletOutputStream extends ServletOutputStream {/*** 字节数组缓冲流,用来保存截获到的输出数据*/private ByteArrayOutputStream buffer;public CustomServletOutputStream(ByteArrayOutputStream buffer) {this.buffer = buffer;}@Overridepublic boolean isReady() {return true;}@Overridepublic void setWriteListener(WriteListener listener) {}/*** 重写输出流相关的方法* 将输出数据写出到给定的ByteArrayOutputStream缓冲流中保存起来* @param b 输出的数据* @throws IOException*/@Overridepublic void write(int b) throws IOException {buffer.write(b);}}}
经验总结扩展阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- SpringBoot+Vue3 AgileBoot - 手把手一步一步带你Run起全栈项目
- 三伏天如何减肥快
- 咸鱼之王龙鱼坚盾怎么搭配
- 宝石研物语:伊恩之石好感度角色是什么
- 宝石研物语:伊恩之石迈向绚烂之时活动在哪
- 宝石研物语:伊恩之石迈向绚烂之时最后一关怎么打
- 宝石研物语:伊恩之石怎么培养莉莉的好感度
- 适合网恋不适合奔现的星座
- 原神熏风之境怎么通关
- 宝石研物语:伊恩之石都有哪些称号