最近對接銀聯需求,為了節省頻寬,需要對封包進行壓縮處理。但使用springboot自帶的壓縮設定不起作用:
server.compression.enabled=true server.compression.mime-types=application/javascript,text/css,application/json,application/xml,text/html,text/xml,text/plain server.compression.compressionMinSize=10
server.compression.enabled:表示是否開啟壓縮,預設開啟,true:開啟,false:不開啟
server.compression .mime-types:壓縮的內容的類型,有xml,json,html等格式
server.compression.compressionMinSize:開啟壓縮資料最小長度,單位為字節,預設是2048位元組
原始碼如下:
public class Compression { private boolean enabled = false; private String[] mimeTypes = new String[]{"text/html", "text/xml", "text/plain", "text/css", "text/javascript", "application/javascript", "application/json", "application/xml"}; private String[] excludedUserAgents = null; private int minResponseSize = 2048; }
tomcat壓縮是對回應封包進行壓縮,當請求頭中存在accept-encoding時,如果Tomcat設定了壓縮,則會在響應時對資料進行壓縮。
tomcat壓縮原始碼是在Http11Processor中設定的:
public class Http11Processor extends AbstractProcessor { private boolean useCompression() { // Check if browser support gzip encoding MessageBytes acceptEncodingMB = request.getMimeHeaders().getValue("accept-encoding"); if ((acceptEncodingMB == null)-->当请求头没有这个字段是不进行压缩 || (acceptEncodingMB.indexOf("gzip") == -1)) { return false; } // If force mode, always compress (test purposes only) if (compressionLevel == 2) { return true; } // Check for incompatible Browser if (noCompressionUserAgents != null) { MessageBytes userAgentValueMB = request.getMimeHeaders().getValue("user-agent"); if(userAgentValueMB != null) { String userAgentValue = userAgentValueMB.toString(); if (noCompressionUserAgents.matcher(userAgentValue).matches()) { return false; } } } return true; } }
作為發卡機構,銀聯封包請求封包是壓縮的,且封包頭中不存在accept-encoding字段,無法直接使用tomcat配置進行壓縮解壓縮。
需要單獨處理這種請求
@RestController @RequestMapping("/user") public class UserController { private static final Logger logger = LoggerFactory.getLogger(UserController.class); /** * * application/xml格式报文 * */ @PostMapping(path = "/test", produces = MediaType.APPLICATION_XML_VALUE, consumes = MediaType.APPLICATION_XML_VALUE) public void getUserInfoById(HttpServletRequest request, HttpServletResponse response) throws IOException { String requestBody; String resultBody="hello,wolrd"; byte[] returnByte; if (StringUtils.isNoneEmpty(request.getHeader("Content-encoding"))) { logger.info("报文压缩,需要进行解压"); //业务处理 //返回报文也同样需要进行压缩处理 assemleResponse(request,response,resultBody); } } public static void assemleResponse(HttpServletRequest request, HttpServletResponse response,String resultBody) throws IOException { response.setHeader("Content-Type","application/xml;charset=UTF-8"); response.setHeader("Content-Encoding","gzip"); byte[] returnByte=GzipUtil.compress(resultBody); OutputStream outputStream=response.getOutputStream(); outputStream.write(returnByte); } }
public class GzipUtil { public static String uncompress(byte[] bytes){ if (bytes == null || bytes.length == 0) { return null; } String requestBody=null; ByteArrayInputStream byteArrayInputStream=new ByteArrayInputStream(bytes); GZIPInputStream gzipInputStream = null; try { gzipInputStream = new GZIPInputStream(byteArrayInputStream); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int temp; while ((temp = gzipInputStream.read(buffer)) != -1) { byteArrayOutputStream.write(buffer, 0, temp); } requestBody = new String(byteArrayOutputStream.toByteArray(), StandardCharsets.UTF_8); } catch (IOException e) { e.printStackTrace(); } return requestBody; } public static String uncompress(HttpServletRequest request){ String requestBody=null; int length = request.getContentLength(); try { BufferedInputStream bufferedInputStream = new BufferedInputStream(request.getInputStream()); GZIPInputStream gzipInputStream = new GZIPInputStream(bufferedInputStream); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int temp; while ((temp = gzipInputStream.read(buffer)) != -1) { byteArrayOutputStream.write(buffer, 0, temp); } requestBody = new String(byteArrayOutputStream.toByteArray(), StandardCharsets.UTF_8); } catch (IOException e) { e.printStackTrace(); } return requestBody; } public static byte[] compress(String src){ if (src == null || src.length() == 0) { return null; } ByteArrayOutputStream byteArrayOutputStream=new ByteArrayOutputStream(); try { GZIPOutputStream gzipOutputStream=new GZIPOutputStream(byteArrayOutputStream); gzipOutputStream.write(src.getBytes(StandardCharsets.UTF_8)); gzipOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } byte[] bytes=byteArrayOutputStream.toByteArray(); return bytes; } }
import lombok.extern.slf4j.Slf4j; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; /** * effect:压缩/解压 字符串 */ @Slf4j public class CompressUtils { /** * effect 使用gzip压缩字符串 * @param str 要压缩的字符串 * @return */ public static String compress(String str) { if (str == null || str.length() == 0) { return str; } ByteArrayOutputStream out = new ByteArrayOutputStream(); GZIPOutputStream gzip = null; try { gzip = new GZIPOutputStream(out); gzip.write(str.getBytes()); } catch (IOException e) { log.error("",e); } finally { if (gzip != null) { try { gzip.close(); } catch (IOException e) { log.error("",e); } } } return new sun.misc.BASE64Encoder().encode(out.toByteArray()); // return str; } /** * effect 使用gzip解压缩 * * @param str 压缩字符串 * @return */ public static String uncompress(String str) { if (str == null) { return null; } ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayInputStream in = null; GZIPInputStream ginzip = null; byte[] compressed = null; String decompressed = null; try { compressed = new sun.misc.BASE64Decoder().decodeBuffer(str); in = new ByteArrayInputStream(compressed); ginzip = new GZIPInputStream(in); byte[] buffer = new byte[1024]; int offset = -1; while ((offset = ginzip.read(buffer)) != -1) { out.write(buffer, 0, offset); } decompressed = out.toString(); } catch (IOException e) { log.error("",e); } finally { if (ginzip != null) { try { ginzip.close(); } catch (IOException e) { } } if (in != null) { try { in.close(); } catch (IOException e) { } } if (out != null) { try { out.close(); } catch (IOException e) { } } } return decompressed; } }
以上是springboot對壓縮請求的處理方法是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!