Skip to content

Commit 88587c4

Browse files
author
Zhang Jin
committed
add q/s set
1 parent a2a1e98 commit 88587c4

9 files changed

Lines changed: 328 additions & 17 deletions

File tree

spring/output.bin

606 Bytes
Binary file not shown.

spring/pom.xml

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -52,26 +52,10 @@
5252
<plugin>
5353
<groupId>org.apache.maven.plugins</groupId>
5454
<artifactId>maven-compiler-plugin</artifactId>
55-
<configuration>
56-
<annotationProcessorPaths>
57-
<path>
58-
<groupId>org.projectlombok</groupId>
59-
<artifactId>lombok</artifactId>
60-
</path>
61-
</annotationProcessorPaths>
62-
</configuration>
6355
</plugin>
6456
<plugin>
6557
<groupId>org.springframework.boot</groupId>
6658
<artifactId>spring-boot-maven-plugin</artifactId>
67-
<configuration>
68-
<excludes>
69-
<exclude>
70-
<groupId>org.projectlombok</groupId>
71-
<artifactId>lombok</artifactId>
72-
</exclude>
73-
</excludes>
74-
</configuration>
7559
</plugin>
7660
</plugins>
7761
</build>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.jinchanc.spring.gzip;
2+
3+
import jakarta.annotation.Resource;
4+
import org.springframework.boot.web.servlet.FilterRegistrationBean;
5+
import org.springframework.context.annotation.Bean;
6+
import org.springframework.context.annotation.Configuration;
7+
8+
/**
9+
10+
* @since 2024/12/13 12:04
11+
*/
12+
13+
@Configuration
14+
public class CnAdxFilterConfig {
15+
16+
@Resource
17+
private WebServerFilter webServerFilter;
18+
19+
@Bean
20+
public FilterRegistrationBean<WebServerFilter> myFilterRegistration() {
21+
FilterRegistrationBean<WebServerFilter> registration = new FilterRegistrationBean<>(webServerFilter);
22+
registration.addUrlPatterns("/*");
23+
return registration;
24+
}
25+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.jinchanc.spring.gzip;
2+
3+
import lombok.extern.slf4j.Slf4j;
4+
import org.springframework.http.RequestEntity;
5+
import org.springframework.http.ResponseEntity;
6+
import org.springframework.web.bind.annotation.PostMapping;
7+
import org.springframework.web.bind.annotation.RestController;
8+
9+
/**
10+
11+
* @since 2025/1/21 17:13
12+
*/
13+
@Slf4j
14+
@RestController
15+
public class GzipController {
16+
17+
@PostMapping("/test")
18+
public ResponseEntity<String> test(RequestEntity<String> requestEntity) {
19+
log.info("request body: {}", requestEntity.getBody());
20+
return ResponseEntity.ok(requestEntity.getBody());
21+
}
22+
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
package com.jinchanc.spring.gzip;
2+
3+
import lombok.NonNull;
4+
import lombok.extern.slf4j.Slf4j;
5+
import org.springframework.util.StringUtils;
6+
7+
import java.io.ByteArrayInputStream;
8+
import java.io.ByteArrayOutputStream;
9+
import java.io.FileOutputStream;
10+
import java.io.IOException;
11+
import java.nio.charset.StandardCharsets;
12+
import java.util.zip.GZIPInputStream;
13+
import java.util.zip.GZIPOutputStream;
14+
15+
/**
16+
17+
* @since 2023/10/13 10:53
18+
*/
19+
@Slf4j
20+
public class GzipUtil {
21+
22+
/**
23+
* 压缩
24+
* string -> gzip byteArray
25+
*/
26+
public static byte[] compress(String str) throws IOException {
27+
if (!StringUtils.hasText(str))
28+
throw new RuntimeException("gzip String is empty.");
29+
return compress(str.getBytes(StandardCharsets.UTF_8));
30+
}
31+
32+
/**
33+
* 解压缩
34+
* gzip byteArray -> string
35+
*/
36+
public static String decompressionToString(byte[] byteArray) throws IOException {
37+
byteArray = decompression(byteArray);
38+
return new String(byteArray, StandardCharsets.UTF_8);
39+
}
40+
41+
/**
42+
* 压缩
43+
* byteArray -> gzip byteArray
44+
*/
45+
public static byte[] compress(byte[] byteArray) {
46+
if (byteArray == null || byteArray.length == 0) {
47+
throw new RuntimeException("gzip byteArray is empty.");
48+
}
49+
50+
try (ByteArrayOutputStream out = new ByteArrayOutputStream();
51+
GZIPOutputStream gzip = new GZIPOutputStream(out)) {
52+
gzip.write(byteArray);
53+
gzip.finish();
54+
byteArray = out.toByteArray();
55+
} catch (IOException e) {
56+
throw new RuntimeException(e);
57+
}
58+
return byteArray;
59+
}
60+
61+
/**
62+
* 解压缩
63+
* gzip byteArray -> byteArray
64+
*/
65+
public static byte[] decompression(byte[] byteArray) throws IOException {
66+
if (byteArray == null || byteArray.length == 0) {
67+
throw new RuntimeException("unzip byteArray is empty.");
68+
}
69+
try (ByteArrayInputStream byteArrayInput = new ByteArrayInputStream(byteArray);
70+
GZIPInputStream gzipInput = new GZIPInputStream(byteArrayInput);
71+
ByteArrayOutputStream byteArrayOutput = new ByteArrayOutputStream();) {
72+
byte[] buffer = new byte[1024];
73+
int n;
74+
while ((n = gzipInput.read(buffer)) != -1) {
75+
byteArrayOutput.write(buffer, 0, n);
76+
}
77+
return byteArrayOutput.toByteArray();
78+
}
79+
}
80+
81+
/**
82+
* 保存byte array为二进制文件
83+
*/
84+
public static void saveToBinaryFile(byte[] byteArray) {
85+
saveToBinaryFile(byteArray, "output.bin");
86+
}
87+
88+
public static void saveToBinaryFile(byte @NonNull [] byteArray, @NonNull String fileName) {
89+
try(FileOutputStream fos = new FileOutputStream(fileName)) {
90+
fos.write(byteArray);
91+
fos.flush();
92+
} catch (IOException e) {
93+
throw new RuntimeException(e);
94+
}
95+
}
96+
97+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package com.jinchanc.spring.gzip;
2+
3+
import jakarta.servlet.ReadListener;
4+
import jakarta.servlet.ServletInputStream;
5+
import jakarta.servlet.http.HttpServletRequest;
6+
import jakarta.servlet.http.HttpServletRequestWrapper;
7+
import org.springframework.util.StreamUtils;
8+
9+
import java.io.BufferedReader;
10+
import java.io.ByteArrayInputStream;
11+
import java.io.IOException;
12+
import java.io.InputStreamReader;
13+
import java.util.Objects;
14+
15+
/**
16+
17+
* @since 2025/1/21 14:51
18+
*/
19+
public class HttpRequestBodyUnzipWrapper extends HttpServletRequestWrapper {
20+
21+
private final byte[] cacheBytes;
22+
23+
public HttpRequestBodyUnzipWrapper(HttpServletRequest request) {
24+
super(request);
25+
try (ServletInputStream inputStream = request.getInputStream()) {
26+
if (Objects.equals(request.getHeader("Content-Encoding"), "gzip")) {
27+
cacheBytes = GzipUtil.decompression(StreamUtils.copyToByteArray(inputStream));
28+
} else {
29+
cacheBytes = StreamUtils.copyToByteArray(inputStream);
30+
}
31+
} catch (IOException e) {
32+
throw new RuntimeException(e);
33+
}
34+
}
35+
36+
@Override
37+
public ServletInputStream getInputStream() throws IOException {
38+
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(cacheBytes);
39+
return new ServletInputStream() {
40+
41+
@Override
42+
public int read() throws IOException {
43+
return byteArrayInputStream.read();
44+
}
45+
46+
@Override
47+
public boolean isFinished() {
48+
return false;
49+
}
50+
51+
@Override
52+
public boolean isReady() {
53+
return false;
54+
}
55+
56+
@Override
57+
public void setReadListener(ReadListener readListener) {
58+
throw new UnsupportedOperationException();
59+
}
60+
};
61+
}
62+
63+
@Override
64+
public BufferedReader getReader() throws IOException {
65+
return new BufferedReader(new InputStreamReader(getInputStream()));
66+
}
67+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package com.jinchanc.spring.gzip;
2+
3+
import jakarta.servlet.ServletOutputStream;
4+
import jakarta.servlet.WriteListener;
5+
import jakarta.servlet.http.HttpServletResponse;
6+
import jakarta.servlet.http.HttpServletResponseWrapper;
7+
8+
import java.io.ByteArrayOutputStream;
9+
import java.io.IOException;
10+
import java.io.PrintWriter;
11+
import java.util.Objects;
12+
13+
/**
14+
15+
* @since 2025/1/21 14:54
16+
*/
17+
public class HttpResponseBodyZipWrapper extends HttpServletResponseWrapper {
18+
19+
// 缓存起写入的字节流
20+
private final ByteArrayOutputStream cacheByteArray = new ByteArrayOutputStream();
21+
22+
public HttpResponseBodyZipWrapper(HttpServletResponse response) {
23+
super(response);
24+
}
25+
26+
@Override
27+
public ServletOutputStream getOutputStream() {
28+
return new ServletOutputStream() {
29+
@Override
30+
public void write(int b) {
31+
cacheByteArray.write(b);
32+
}
33+
34+
@Override
35+
public boolean isReady() {
36+
return false;
37+
}
38+
39+
@Override
40+
public void setWriteListener(WriteListener listener) {
41+
42+
}
43+
};
44+
}
45+
46+
@Override
47+
public PrintWriter getWriter() throws IOException {
48+
return new PrintWriter(cacheByteArray);
49+
}
50+
51+
// 使用缓存的字节流写入到输出流
52+
public void rewrite(String encoding) {
53+
// TODO 这个卡死bug难以解决
54+
try (ServletOutputStream outputStream = this.getResponse().getOutputStream()) {
55+
byte[] byteArray = cacheByteArray.toByteArray();
56+
if (Objects.equals(encoding, "gzip")) {
57+
byte[] compressBytes = GzipUtil.compress(byteArray);
58+
outputStream.write(compressBytes);
59+
this.getResponse().setContentLength(compressBytes.length);
60+
this.getResponse().setContentLength(compressBytes.length);
61+
setHeader("Content-Encoding", "gzip");
62+
} else {
63+
outputStream.write(byteArray);
64+
this.getResponse().setContentLength(byteArray.length);
65+
this.getResponse().setContentLength(byteArray.length);
66+
}
67+
} catch (IOException e) {
68+
throw new RuntimeException(e);
69+
}
70+
}
71+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package com.jinchanc.spring.gzip;
2+
3+
import jakarta.servlet.*;
4+
import jakarta.servlet.http.HttpServletRequest;
5+
import jakarta.servlet.http.HttpServletResponse;
6+
import lombok.extern.slf4j.Slf4j;
7+
import org.springframework.stereotype.Component;
8+
9+
import java.io.IOException;
10+
11+
/**
12+
13+
* @since 2024/12/12 18:02
14+
*/
15+
@Slf4j
16+
@Component
17+
public class WebServerFilter implements Filter {
18+
19+
@Override
20+
public void init(FilterConfig filterConfig) throws ServletException {
21+
Filter.super.init(filterConfig);
22+
log.info("Filter init");
23+
}
24+
25+
@Override
26+
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
27+
HttpServletRequest request = (HttpServletRequest) servletRequest;
28+
HttpServletResponse response = (HttpServletResponse) servletResponse;
29+
HttpRequestBodyUnzipWrapper requestWrapper = new HttpRequestBodyUnzipWrapper(request);
30+
// TODO response 卡死bug无法解决
31+
chain.doFilter(requestWrapper, response);
32+
}
33+
34+
@Override
35+
public void destroy() {
36+
Filter.super.destroy();
37+
log.info("Filter destroy");
38+
}
39+
}
Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
package com.jinchanc.spring;
22

3+
import com.jinchanc.spring.gzip.GzipUtil;
34
import org.junit.jupiter.api.Test;
45
import org.springframework.boot.test.context.SpringBootTest;
56

7+
import java.io.IOException;
8+
import java.nio.charset.StandardCharsets;
9+
610
@SpringBootTest
711
class ApplicationTests {
812

913
@Test
10-
void contextLoads() {
14+
void contextLoads() throws IOException {
15+
String str = "{\"id\":\"449898e5111c4bcd98ca54306c27be3b\",\"imps\":[{\"id\":\"testAdSlotId\",\"adSlotType\":5,\"bidFloor\":50,\"interactionTypes\":[1,2,3],\"video\":{\"w\":1080,\"h\":1920}}],\"app\":{\"id\":\"testAppId\",\"name\":\"testAppName\",\"bundle\":\"testAppBundle\",\"ver\":\"6.33.0\"},\"device\":{\"ua\":\"Mozilla/5.0 (Linux; Android 7.1.1; vivo Y75A Build/N6F26Q; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/43.0.2357.65 Mobile Safari/537.36\",\"geo\":{\"lat\":40.7127,\"lon\":74.0059,\"city\":\"GuangZhou\"},\"ipv4\":\"39.149.229.215\",\"deviceType\":1,\"brand\":\"vivo\",\"model\":\"s19\",\"os\":2,\"osv\":\"14.0\",\"screenWidth\":1080,\"screenHeight\":1920,\"screenOrientation\":1,\"connectionType\":7,\"ppi\":6,\"density\":1.2000000476837158,\"bootMark\":\"BootMark\",\"updateMark\":\"UpdateMark\",\"bootTime\":\"BootTime\",\"updateTime\":\"UpdateTime\",\"mac\":\"macmacmacmac\",\"oaid\":\"oaidoaidoaidoaid\",\"make\":\"vivo\",\"idfv\":\"idfv\"},\"user\":{\"gender\":1,\"age\":18,\"installedAppBundles\":[\"baidu.com\",\"jd.com\"]},\"secure\":true,\"apiVersion\":\"1.0.0\",\"tmax\":500,\"test\":1}";
16+
GzipUtil.saveToBinaryFile(GzipUtil.compress(str));
1117
}
1218

1319
}

0 commit comments

Comments
 (0)