http请求body内容压缩与解压

最近公司项目在做跨国数据同步,采用的方式是使用http请求进行数据同步,因为发送的请求body中内容可能比较多,所以在发送请求时对请求body进行了压缩,在获取到请求时再对body进行解压。

请求压缩

压缩与解压工具类

public class GZIPUtils {
	public static final String GZIP_ENCODE_UTF_8 = "UTF-8";
	
	public static byte[] compress(String str) {
		if (str == null || str.length() == 0) {
			return null;
		}
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		GZIPOutputStream gzip;
		try {
			gzip = new GZIPOutputStream(out);
			gzip.write(str.getBytes(GZIP_ENCODE_UTF_8));
			gzip.close();
		} catch ( Exception e) {
			e.printStackTrace();
		}
		return out.toByteArray();
	}
}

发送请求

public class HttpClientUtils {
	public static void main(String[] args) throw Exception{
		String body = "{\"name\":\"zhangsan\"}";
		HttpClient httpClient = HttpClients.createDefault();
		HttpPost post = new HttpPost(“http://localhost:8080/test”);
		post.setHeader("Content-Type", "application/json;charset=utf-8");
	    post.setHeader("Accept", "application/json");
	    post.setHeader("Content-Encoding", "gzip");
	    byte[] gzipEncrypt = GZIPUtils.compress(body);
	    post.setEntity(new InputStreamEntity(new ByteArrayInputStream(gzipEncrypt),gzipEncrypt.length));
	    HttpResponse httpResponse = httpClient.execute(post);
	    int code = httpResponse.getStatusLine().getStatusCode();
        HttpEntity response = httpResponse.getEntity();
	    System.out.println("请求状态码:" + code);
	    System.out.println("请求返回结果:" + EntityUtils.toString(response));
	}
}

接受请求(GZIPFilter )

@WebFilter(filterName = "GZIPFilter", urlPatterns = "*")
public class GZIPFilter implements Filter {
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
			chain.doFilter(new GZIPRequestWrapper((HttpServletRequest) request),response);
	}
	@Override
	public void destroy() {}
}

GZIPRequestWrapper

public class GZIPRequestWrapper extends HttpServletRequestWrapper {

	private HttpServletRequest request;
	private static final Logger LOGGER = LoggerFactory.getLogger(GZIPRequestWrapper.class);

	public GZIPRequestWrapper(HttpServletRequest request) {
		super(request);
		this.request = request;
	}


	@Override
	public ServletInputStream getInputStream() throws IOException {

		ServletInputStream stream = request.getInputStream();

		String contentEncoding = request.getHeader("Content-Encoding");
		// 如果对内容进行了压缩,则解压
		if (null != contentEncoding && contentEncoding.indexOf("gzip") != -1) {
			try {
				final GZIPInputStream gzipInputStream = new GZIPInputStream(
						stream); //将body的流通过GZIPInputStream解压
				// 因为请求body中的流已经被读完了,所以这里需要将流重新写回去,不然在Controller接收RequestBody时就因为流被读完获取不到数据
				ServletInputStream newStream = new ServletInputStream() {

					@Override
					public int read() throws IOException {
						return gzipInputStream.read();
					}

					@Override
					public boolean isFinished() {
						return false;
					}

					@Override
					public boolean isReady() {
						return false;
					}

					@Override
					public void setReadListener(ReadListener arg0) {
						// TODO Auto-generated method stub

					}
				};
				return newStream;
			} catch (Exception e) {
				LOGGER.debug("ungzip fail", e);
			}
		}
		return stream;
	}
}

这样就可以实现请求body内容的压缩与解压了

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值