对Request进行包装UnZipRequestWrapper 读取输入流,然进行解压;解压完后,再把解压出来的数据封装到输入流中 。
package com.olive.filter;import com.olive.utils.GzipUtils;import lombok.extern.slf4j.Slf4j;import javax.servlet.ReadListener;import javax.servlet.ServletInputStream;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletRequestWrapper;import java.io.*;/** *Json String 经过压缩后保存为二进制文件 -> 解压缩后还原成 Jso nString转换成byte[]写回body中 */@Slf4jpublic class UnZipRequestWrapper extends HttpServletRequestWrapper {private final byte[] bytes;public UnZipRequestWrapper(HttpServletRequest request) throws IOException {super(request);try (BufferedInputStream bis = new BufferedInputStream(request.getInputStream());ByteArrayOutputStream baos = new ByteArrayOutputStream()) {final byte[] body;byte[] buffer = new byte[1024];int len;while ((len = bis.read(buffer)) > 0) {baos.write(buffer, 0, len);}body = baos.toByteArray();if (body.length == 0) {log.info("Body无内容,无需解压");bytes = body;return;}this.bytes = GzipUtils.uncompressToByteArray(body);} catch (IOException ex) {log.error("解压缩步骤发生异常!", ex);throw ex;}}@Overridepublic ServletInputStream getInputStream() throws IOException {final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);return new ServletInputStream() {@Overridepublic boolean isFinished() {return false;}@Overridepublic boolean isReady() {return false;}@Overridepublic void setReadListener(ReadListener readListener) {}public int read() throws IOException {return byteArrayInputStream.read();}};}@Overridepublic BufferedReader getReader() throws IOException {return new BufferedReader(new InputStreamReader(this.getInputStream()));}}
定义GzipFilter对请求进行拦截GzipFilter 拦截器根据请求头是否包含Content-Encoding=application/gzip
,如果包含就对数据进行解压;否则就直接放过 。
package com.olive.filter;import lombok.extern.slf4j.Slf4j;import org.springframework.stereotype.Component;import javax.servlet.*;import javax.servlet.http.HttpServletRequest;import java.io.IOException;/** * 解压filter */@Slf4j@Componentpublic class GzipFilter implements Filter {private static final String CONTENT_ENCODING = "Content-Encoding";private static final String CONTENT_ENCODING_TYPE = "application/gzip";@Overridepublic void init(FilterConfig filterConfig) throws ServletException {log.info("init GzipFilter");}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {long start = System.currentTimeMillis();HttpServletRequest httpServletRequest = (HttpServletRequest)request;String encodeType = httpServletRequest.getHeader(CONTENT_ENCODING);if (encodeType!=null && CONTENT_ENCODING_TYPE.equals(encodeType)) {log.info("请求:{} 需要解压", httpServletRequest.getRequestURI());UnZipRequestWrapper unZipRequest = new UnZipRequestWrapper(httpServletRequest);chain.doFilter(unZipRequest, response);}else {log.info("请求:{} 无需解压", httpServletRequest.getRequestURI());chain.doFilter(request,response);}log.info("耗时:{}ms", System.currentTimeMillis() - start);}@Overridepublic void destroy() {log.info("destroy GzipFilter");}}
注册 GzipFilter 拦截器package com.olive.config;import com.olive.filter.GzipFilter;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.web.servlet.FilterRegistrationBean;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;/** * 注册filter */@Configurationpublic class FilterRegistration {@Autowiredprivate GzipFilter gzipFilter;@Beanpublic FilterRegistrationBean<GzipFilter> gzipFilterRegistrationBean() {FilterRegistrationBean<GzipFilter> registration = new FilterRegistrationBean<>();//Filter可以new,也可以使用依赖注入Beanregistration.setFilter(gzipFilter);//过滤器名称registration.setName("gzipFilter");//拦截路径registration.addUrlPatterns("/*");//设置顺序registration.setOrder(1);return registration;}}
定义 Controller该 Controller 非常简单,主要是输入请求的数据
package com.olive.controller;import java.util.HashMap;import java.util.Map;import com.alibaba.fastjson2.JSON;import com.olive.vo.ArticleRequestVO;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@RestControllerpublic class TestController { @RequestMapping("/getArticle") public Map<String, Object> getArticle(@RequestBody ArticleRequestVO articleRequestVO){Map<String, Object> result = new HashMap<>();result.put("code", 200);result.put("msg", "success");System.out.println(JSON.toJSONString(articleRequestVO));return result; }}
Controller 参数接收VO
推荐阅读
- .NET 开源项目推荐之 直播控制台解决方案 Macro Deck
- 空之要塞:启航游戏要怎么玩
- 云顶之弈手游芬妮水炮怎么玩
- JavaScript之无题之让人烦躁的模块化
- 条件期望:Conditional Expectation 举例详解之入门之入门之草履虫都说听懂了
- 分布式存储系统之Ceph集群存储池操作
- 咸鱼之王赌狗控制流阵容怎么玩
- 金铲铲之战2.20b最强阵容有哪些
- 明日方舟异客皮肤今昔须臾之梦怎么样
- 原神妮露命之座抽取哪个好