-
-
Save calo81/2071634 to your computer and use it in GitHub Desktop.
package com.paddypower.financials.market.management.rest.logging; | |
import java.io.BufferedReader; | |
import java.io.ByteArrayInputStream; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import java.io.InputStreamReader; | |
import javax.servlet.Filter; | |
import javax.servlet.FilterChain; | |
import javax.servlet.FilterConfig; | |
import javax.servlet.ServletException; | |
import javax.servlet.ServletInputStream; | |
import javax.servlet.ServletRequest; | |
import javax.servlet.ServletResponse; | |
import javax.servlet.http.HttpServletRequest; | |
import javax.servlet.http.HttpServletRequestWrapper; | |
import org.apache.commons.io.IOUtils; | |
public class LoggerFilter implements Filter { | |
private Auditor auditor; | |
public void destroy() { | |
// Nothing to do | |
} | |
public void doFilter(ServletRequest request, ServletResponse response, | |
FilterChain chain) throws IOException, ServletException { | |
ResettableStreamHttpServletRequest wrappedRequest = new ResettableStreamHttpServletRequest( | |
(HttpServletRequest) request); | |
// wrappedRequest.getInputStream().read(); | |
String body = IOUtils.toString(wrappedRequest.getReader()); | |
auditor.audit(wrappedRequest.getRequestURI(),wrappedRequest.getUserPrincipal(), body); | |
wrappedRequest.resetInputStream(); | |
chain.doFilter(wrappedRequest, response); | |
} | |
public void init(FilterConfig arg0) throws ServletException { | |
// Nothing to do | |
} | |
private static class ResettableStreamHttpServletRequest extends | |
HttpServletRequestWrapper { | |
private byte[] rawData; | |
private HttpServletRequest request; | |
private ResettableServletInputStream servletStream; | |
public ResettableStreamHttpServletRequest(HttpServletRequest request) { | |
super(request); | |
this.request = request; | |
this.servletStream = new ResettableServletInputStream(); | |
} | |
public void resetInputStream() { | |
servletStream.stream = new ByteArrayInputStream(rawData); | |
} | |
@Override | |
public ServletInputStream getInputStream() throws IOException { | |
if (rawData == null) { | |
rawData = IOUtils.toByteArray(this.request.getReader()); | |
servletStream.stream = new ByteArrayInputStream(rawData); | |
} | |
return servletStream; | |
} | |
@Override | |
public BufferedReader getReader() throws IOException { | |
if (rawData == null) { | |
rawData = IOUtils.toByteArray(this.request.getReader()); | |
servletStream.stream = new ByteArrayInputStream(rawData); | |
} | |
return new BufferedReader(new InputStreamReader(servletStream)); | |
} | |
private class ResettableServletInputStream extends ServletInputStream { | |
private InputStream stream; | |
@Override | |
public int read() throws IOException { | |
return stream.read(); | |
} | |
} | |
} | |
public void setAuditor(Auditor auditor) { | |
this.auditor = auditor; | |
} | |
} |
Thank you so much for this!
And hope my version is helpful to someone
public class ResponseFilter implements Filter{
public ResponseFilter() {
super();
}
private static class ResettableStreamHttpServletResponse extends HttpServletResponseWrapper {
private HttpServletResponse response;
public ResettableStreamHttpServletResponse(HttpServletResponse response) {
super(response);
this.response = response;
}
}
@Override public void init(FilterConfig config) throws ServletException{}
@Override public void destroy(){}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{
ResettableStreamHttpServletResponse wrappedResponse = new ResettableStreamHttpServletResponse((HttpServletResponse) response);
wrappedResponse.addHeader("Access-Control-Allow-Origin", "*");
wrappedResponse.addHeader("Access-Control-Allow-Headers", "origin, content-type, accept, authorization");
wrappedResponse.addHeader("Access-Control-Allow-Credentials", "true");
wrappedResponse.addHeader("Access-Control-Allow-Methods", "GET, POST");
chain.doFilter(request, wrappedResponse);
}
}
Concerning the encoding problem, this might work, but I haven't tried it:
public class ResettableStreamHttpServletRequest extends HttpServletRequestWrapper {
private byte[] rawData;
private HttpServletRequest request;
private ResettableServletInputStream servletStream;
ResettableStreamHttpServletRequest(HttpServletRequest request) {
super(request);
this.request = request;
this.servletStream = new ResettableServletInputStream();
}
void resetInputStream() {
servletStream.stream = new ByteArrayInputStream(rawData);
}
@Override
public ServletInputStream getInputStream() throws IOException {
if (rawData == null) {
rawData = IOUtils.toByteArray(this.request.getInputStream());
servletStream.stream = new ByteArrayInputStream(rawData);
}
return servletStream;
}
@Override
public BufferedReader getReader() throws IOException {
if (rawData == null) {
rawData = IOUtils.toByteArray(this.request.getInputStream());
servletStream.stream = new ByteArrayInputStream(rawData);
}
String encoding = getCharacterEncoding();
if (encoding != null) {
return new BufferedReader(new InputStreamReader(servletStream, encoding));
} else {
return new BufferedReader(new InputStreamReader(servletStream));
}
}
private class ResettableServletInputStream extends ServletInputStream {
private InputStream stream;
@Override
public int read() throws IOException {
return stream.read();
}
}
}
This is awesome !!
Thanks. The following code with some changes from your code works for me :
private static class ResettableStreamHttpServletRequest extends HttpServletRequestWrapper {
private byte[] rawData;
private HttpServletRequest request;
private ResettableServletInputStream servletStream;
private ResettableStreamHttpServletRequest(HttpServletRequest request) {
super(request);
this.request = request;
servletStream = new ResettableServletInputStream();
}
public void resetInputStream() {
servletStream.stream = new ByteArrayInputStream(rawData);
}
@Override
public ServletInputStream getInputStream() throws IOException {
if (rawData == null) {
rawData = IOUtils.toByteArray(request.getReader());
servletStream.stream = new ByteArrayInputStream(rawData);
}
return servletStream;
}
@Override
public BufferedReader getReader() throws IOException {
if (rawData == null) {
rawData = IOUtils.toByteArray(request.getReader());
servletStream.stream = new ByteArrayInputStream(rawData);
}
return new BufferedReader(new InputStreamReader(servletStream));
}
}
private static class ResettableServletInputStream extends ServletInputStream {
private InputStream stream;
@Override
public int read() throws IOException {
return stream.read();
}
@Override
public boolean isFinished() {
try {
int available = stream.available();
return available == 0;
} catch (IOException e) {
return true;
}
}
@Override
public boolean isReady() {
return true;
}
@Override
public void setReadListener(ReadListener readListener) { }
}
Thanks ! Really useful !!! 😄
I am calling Http POST to the REST endpoint, but making XML request, in my case 3rd party system can only make the SOAP request, now I need to remove soapenv:Envelope from the request and only pass the xml tags. I am using Spring Boot application.
Is there any way to read the request and update the POST data?
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:wer.com:dms:wsdls:organization">
<soapenv:Header/>
<soapenv:Body>
<urn:getProfile>
<getProfileRequest>
<patientId>160166</patientId>
</getProfileRequest>
</urn:getProfile>
</soapenv:Body>
</soapenv:Envelope>
Thank you.
It was really helpful.
Here is my working solution, that is up-to-date with packages' versions.
private static final class CopyableHttpServletRequestWrapper extends HttpServletRequestWrapper {
private byte[] rawData;
private HttpServletRequest request;
private CopyableServletInputStream servletInputStream;
private static final class CopyableServletInputStream extends ServletInputStream {
private InputStream stream;
public CopyableServletInputStream(InputStream stream) {
this.stream = stream;
}
@Override
public boolean isFinished() {
try {
int remainingBytes = stream.available();
return 0 == remainingBytes;
} catch (IOException ex) {
return false;
}
}
@Override
public boolean isReady() {
return true;
}
@Override
public void setReadListener(ReadListener listener) { }
@Override
public int read() throws IOException {
return stream.read();
}
}
private CopyableHttpServletRequestWrapper(HttpServletRequest request) {
super(request);
this.request = request;
}
@Override
public ServletInputStream getInputStream() throws IOException {
copyBodyDataIfNecessary();
return servletInputStream;
}
@Override
public BufferedReader getReader() throws IOException {
copyBodyDataIfNecessary();
return new BufferedReader(new InputStreamReader(servletInputStream));
}
public void copyBodyDataIfNecessary() throws IOException {
if(null == rawData) {
rawData = IOUtils.toByteArray(request.getReader(), "utf-8");
servletInputStream = new CopyableServletInputStream(new ByteArrayInputStream(rawData));
}
}
public void resetStream() throws IOException {
this.servletInputStream = new CopyableServletInputStream(new ByteArrayInputStream(rawData));
}
}
very good!!!
Thank you every one, a little change because not working in my project by a cast wrong
private static final class CopyableHttpServletRequestWrapper extends HttpServletRequestWrapper {
private byte[] rawData;
private final HttpServletRequest request;
private CopyableServletInputStream servletInputStream;
private static final class CopyableServletInputStream extends ServletInputStream {
private final InputStream stream;
public CopyableServletInputStream(InputStream stream) {
this.stream = stream;
}
@Override
public boolean isFinished() {
try {
int remainingBytes = stream.available();
return 0 == remainingBytes;
} catch (IOException ex) {
return false;
}
}
@Override
public boolean isReady() {
return true;
}
@Override
public void setReadListener(ReadListener listener) {
}
@Override
public int read() throws IOException {
return stream.read();
}
}
private CopyableHttpServletRequestWrapper(HttpServletRequest request) {
super(request);
this.request = request;
}
@Override
public ServletInputStream getInputStream() throws IOException {
copyBodyDataIfNecessary();
return servletInputStream;
}
@Override
public BufferedReader getReader() throws IOException {
copyBodyDataIfNecessary();
return new BufferedReader(new InputStreamReader(servletInputStream));
}
public void copyBodyDataIfNecessary() throws IOException {
if (null == rawData) {
rawData = IOUtils.toByteArray(this.request.getInputStream());
servletInputStream = new CopyableServletInputStream(new ByteArrayInputStream(rawData));
}
}
public void resetStream() throws IOException {
this.servletInputStream = new CopyableServletInputStream(new ByteArrayInputStream(rawData));
}
}
what about response filter, i want to catch or log all the data of webservice's response before it reach to client