Avoid loss of body content in AbstractRequestLoggingFilter
Prior to this commit, the `ContentCachingRequestWrapper` class would cache the response content only if the reponse would be consumed using its InputStream. In case of a Form request, Spring MVC consumes the response using the `getParameter*` Servlet API methods. This causes the cached content to never be written. This commit makes the `ContentCachingResponseWrapper` write the request body to the cache buffer by using the `getParameter*` API, thus avoiding those issues. Issue: SPR-7913
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,6 +20,14 @@ import java.io.BufferedReader;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Arrays;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletInputStream;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletRequestWrapper;
|
||||
@@ -36,6 +44,10 @@ import javax.servlet.http.HttpServletRequestWrapper;
|
||||
*/
|
||||
public class ContentCachingRequestWrapper extends HttpServletRequestWrapper {
|
||||
|
||||
private static final String FORM_CONTENT_TYPE = "application/x-www-form-urlencoded";
|
||||
|
||||
private static final String METHOD_POST = "POST";
|
||||
|
||||
private final ByteArrayOutputStream cachedContent;
|
||||
|
||||
private ServletInputStream inputStream;
|
||||
@@ -80,9 +92,46 @@ public class ContentCachingRequestWrapper extends HttpServletRequestWrapper {
|
||||
* Return the cached request content as a byte array.
|
||||
*/
|
||||
public byte[] getContentAsByteArray() {
|
||||
if(this.cachedContent.size() == 0 && isFormPost()) {
|
||||
writeRequestParamsToContent();
|
||||
}
|
||||
return this.cachedContent.toByteArray();
|
||||
}
|
||||
|
||||
private boolean isFormPost() {
|
||||
return (getContentType() != null && getContentType().contains(FORM_CONTENT_TYPE) &&
|
||||
METHOD_POST.equalsIgnoreCase(getMethod()));
|
||||
}
|
||||
|
||||
private void writeRequestParamsToContent() {
|
||||
try {
|
||||
if (this.cachedContent.size() == 0) {
|
||||
String requestEncoding = getCharacterEncoding();
|
||||
Map<String, String[]> form = getParameterMap();
|
||||
for (Iterator<String> nameIterator = form.keySet().iterator(); nameIterator.hasNext(); ) {
|
||||
String name = nameIterator.next();
|
||||
List<String> values = Arrays.asList(form.get(name));
|
||||
for (Iterator<String> valueIterator = values.iterator(); valueIterator.hasNext(); ) {
|
||||
String value = valueIterator.next();
|
||||
cachedContent.write(URLEncoder.encode(name, requestEncoding).getBytes());
|
||||
if (value != null) {
|
||||
cachedContent.write('=');
|
||||
cachedContent.write(URLEncoder.encode(value, requestEncoding).getBytes());
|
||||
if (valueIterator.hasNext()) {
|
||||
cachedContent.write('&');
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nameIterator.hasNext()) {
|
||||
cachedContent.write('&');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private class ContentCachingInputStream extends ServletInputStream {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user