I would like to get the XML data from request and response and use it into Rest controller. I tried this:
@RestController()
public class HomeController {
@PostMapping(value = "/v1")
public Response handleMessage(@RequestBody Transaction transaction, HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest request, HttpServletResponse response
System.out.println("!!!!!!! InputStream");
System.out.println(request.getInputStream());
System.out.println(response.getOutputStream());
InputStream in = request.getInputStream();
String readLine;
BufferedReader br = new BufferedReader(new InputStreamReader(in));
while (((readLine = br.readLine()) != null)) {
System.out.println(readLine);
}
}
}
But I get java.io.IOException: UT010029: Stream is closed
What is the proper way to get the content into String variable?
EDIT: I also tried solution with Filter but I'm not aware how to use the request payload into rest controller:
Read request payload:
@Component
public class HttpLoggingFilter implements Filter {
private static final Logger logger = LoggerFactory.getLogger(HttpLoggingFilter.class);
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
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());
System.out.println("!!!!!!!!!!!!!!!!!! " + body);
wrappedRequest.resetInputStream();
chain.doFilter(request, response);
}
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();
}
@Override
public boolean isFinished() {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean isReady() {
// TODO Auto-generated method stub
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
// TODO Auto-generated method stub
}
}
}
}
Rest endpoint:
@RestController()
public class HomeController {
@PostMapping(value = "/v1")
public Response handleMessage(@RequestBody Transaction transaction, HttpServletRequest request, org.zalando.logbook.HttpRequest requestv, HttpServletResponse response) throws Exception {
// Get here request and response and log it into DB
}
}
How I can call HttpLoggingFilter
into the Java method handleMessage and get the request as body String? Probably I can make it service and Inject it? Can you give me some advice how I can assess the code?