[SPRING] Spring MVC에서 Gzip 압축 된 요청 바디를 디코딩하는 법
SPRINGSpring MVC에서 Gzip 압축 된 요청 바디를 디코딩하는 법
데이터를 보내는 클라이언트가 있습니다.
CONTENT-ENCODING deflate
나는 이와 같은 코드를 가지고있다.
@RequestMapping(value = "/connect", method = RequestMethod.POST)
@ResponseBody
public Map onConnect(@RequestBody String body){}
현재 '본문'은 왜곡되고 압축 된 데이터를 인쇄합니다. Spring MVC에서 자동으로 압축을 풀 수있는 방법이 있습니까?
해결법
-
==============================
1.당신은 봄에 그것을 처리하지 않습니다. 대신에 스프링에 도착한 데이터가 이미 수축되도록 필터를 사용합니다.
당신은 봄에 그것을 처리하지 않습니다. 대신에 스프링에 도착한 데이터가 이미 수축되도록 필터를 사용합니다.
다행히도이 두 링크가 당신을 시작할 수 있기를 바랍니다.
-
==============================
2.gzip으로 압축 된 요청의 본문을 압축 해제하려면 자체 필터를 작성해야합니다. 사인 (parine) 당신은 요청으로부터 전체 입력 스트림을 읽을 것입니다. 이것은 내 코드에서 사용하고있는 필터입니다. gzip으로 압축 된 POST 요청 만 지원하지만 필요할 경우 다른 유형의 요청을 사용하도록 업데이트 할 수 있습니다. 또한 구아바 라이브러리를 사용하는 매개 변수를 구문 분석 할 때주의하십시오. http://central.maven.org/maven2/com/google/guava/guava/ 여기에서 가져올 수 있습니다.
gzip으로 압축 된 요청의 본문을 압축 해제하려면 자체 필터를 작성해야합니다. 사인 (parine) 당신은 요청으로부터 전체 입력 스트림을 읽을 것입니다. 이것은 내 코드에서 사용하고있는 필터입니다. gzip으로 압축 된 POST 요청 만 지원하지만 필요할 경우 다른 유형의 요청을 사용하도록 업데이트 할 수 있습니다. 또한 구아바 라이브러리를 사용하는 매개 변수를 구문 분석 할 때주의하십시오. http://central.maven.org/maven2/com/google/guava/guava/ 여기에서 가져올 수 있습니다.
public class GzipBodyDecompressFilter extends Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } /** * Analyzes servlet request for possible gzipped body. * When Content-Encoding header has "gzip" value and request method is POST we read all the * gzipped stream and is it haz any data unzip it. In case when gzip Content-Encoding header * specified but body is not actually in gzip format we will throw ZipException. * * @param servletRequest servlet request * @param servletResponse servlet response * @param chain filter chain * @throws IOException throws when fails * @throws ServletException thrown when fails */ @Override public final void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse, final FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; boolean isGzipped = request.getHeader(HttpHeaders.CONTENT_ENCODING) != null && request.getHeader(HttpHeaders.CONTENT_ENCODING).contains("gzip"); boolean requestTypeSupported = HttpMethods.POST.equals(request.getMethod()); if (isGzipped && !requestTypeSupported) { throw new IllegalStateException(request.getMethod() + " is not supports gzipped body of parameters." + " Only POST requests are currently supported."); } if (isGzipped && requestTypeSupported) { request = new GzippedInputStreamWrapper((HttpServletRequest) servletRequest); } chain.doFilter(request, response); } /** * @inheritDoc */ @Override public final void destroy() { } /** * Wrapper class that detects if the request is gzipped and ungzipps it. */ final class GzippedInputStreamWrapper extends HttpServletRequestWrapper { /** * Default encoding that is used when post parameters are parsed. */ public static final String DEFAULT_ENCODING = "ISO-8859-1"; /** * Serialized bytes array that is a result of unzipping gzipped body. */ private byte[] bytes; /** * Constructs a request object wrapping the given request. * In case if Content-Encoding contains "gzip" we wrap the input stream into byte array * to original input stream has nothing in it but hew wrapped input stream always returns * reproducible ungzipped input stream. * * @param request request which input stream will be wrapped. * @throws java.io.IOException when input stream reqtieval failed. */ public GzippedInputStreamWrapper(final HttpServletRequest request) throws IOException { super(request); try { final InputStream in = new GZIPInputStream(request.getInputStream()); bytes = ByteStreams.toByteArray(in); } catch (EOFException e) { bytes = new byte[0]; } } /** * @return reproduceable input stream that is either equal to initial servlet input * stream(if it was not zipped) or returns unzipped input stream. * @throws IOException if fails. */ @Override public ServletInputStream getInputStream() throws IOException { final ByteArrayInputStream sourceStream = new ByteArrayInputStream(bytes); return new ServletInputStream() { public int read() throws IOException { return sourceStream.read(); } public void close() throws IOException { super.close(); sourceStream.close(); } }; } /** * Need to override getParametersMap because we initially read the whole input stream and * servlet container won't have access to the input stream data. * * @return parsed parameters list. Parameters get parsed only when Content-Type * "application/x-www-form-urlencoded" is set. */ @Override public Map getParameterMap() { String contentEncodingHeader = getHeader(HttpHeaders.CONTENT_TYPE); if (!Strings.isNullOrEmpty(contentEncodingHeader) && contentEncodingHeader.contains("application/x-www-form-urlencoded")) { Map params = new HashMap(super.getParameterMap()); try { params.putAll(parseParams(new String(bytes))); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return params; } else { return super.getParameterMap(); } } /** * parses params from the byte input stream. * * @param body request body serialized to string. * @return parsed parameters map. * @throws UnsupportedEncodingException if encoding provided is not supported. */ private Map<String, String[]> parseParams(final String body) throws UnsupportedEncodingException { String characterEncoding = getCharacterEncoding(); if (null == characterEncoding) { characterEncoding = DEFAULT_ENCODING; } final Multimap<String, String> parameters = ArrayListMultimap.create(); for (String pair : body.split("&")) { if (Strings.isNullOrEmpty(pair)) { continue; } int idx = pair.indexOf("="); String key = null; if (idx > 0) { key = URLDecoder.decode(pair.substring(0, idx), characterEncoding); } else { key = pair; } String value = null; if (idx > 0 && pair.length() > idx + 1) { value = URLDecoder.decode(pair.substring(idx + 1), characterEncoding); } else { value = null; } parameters.put(key, value); } return Maps.transformValues(parameters.asMap(), new Function<Collection<String>, String[]>() { @Nullable @Override public String[] apply(final Collection<String> input) { return Iterables.toArray(input, String.class); } }); } }
}
-
==============================
3.이것은 응용 프로그램이 아니라 서버에 의해 처리되어야합니다.
이것은 응용 프로그램이 아니라 서버에 의해 처리되어야합니다.
내가 아는 한, Tomcat은 그것을 지원하지 않지만 필터를 작성할 수는있다.
이것을 처리하는 일반적인 방법은 압축 된 요청 본문을 처리하도록 구성된 Apache 서버 뒤에 Tomcat (또는 사용중인 모든 Java 컨테이너)을 배치하는 것입니다.
from https://stackoverflow.com/questions/16638345/how-to-decode-gzip-compressed-request-body-in-spring-mvc by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] JAXB 주석이있는 Spring 3.1.2의 등록자 MappingJackson2HttpMessageConverter (0) | 2019.02.11 |
---|---|
[SPRING] spring-security-context.xml에서 사용자 이름 / 패스워드를 이동하는 방법? (0) | 2019.02.11 |
[SPRING] 전체 페이지를 가져 오려면 PageRequest에서 계산 쿼리를 비활성화하는 방법? (0) | 2019.02.11 |
[SPRING] RunWith 및 ContextConfiguration 이상한 동작 (0) | 2019.02.11 |
[SPRING] Spring Security는 인증 된 사용자 및 인증되지 않은 사용자를 위해, 휴식 서비스에서 사용자 정보를 얻습니다. (0) | 2019.02.11 |