Я попытался реализовать собственный класс ClonedServletRequestWrapper, расширив HttpServletRequestWrapper следующим образом.
Код: Выделить всё
public class ClonedHttpServletRequest extends HttpServletRequestWrapper {
private final byte[] body;
private final Map customHeaders = new HashMap();
public ClonedHttpServletRequest(HttpServletRequest request) throws IOException {
super(request);
// deep cloning request body
try (InputStream requestInputStream = request.getInputStream()) {
this.body = requestInputStream.readAllBytes();
}
// deep cloning headers
Collections.list(request.getHeaderNames()).forEach( headerName ->
customHeaders.put(headerName, request.getHeader(headerName))
);
}
@Override
public ServletInputStream getInputStream() throws IOException {
return new ClonedServletInputStream(this.body);
}
public byte[] getBody() {
return body;
}
public Map getCustomHeaders() {
return customHeaders;
}
public String getHeader(String name) {
return customHeaders.get(name);
}
public Enumeration getHeaderNames() {
return Collections.enumeration(customHeaders.keySet());
}
public Enumeration getHeaders(String name) {
return Collections.enumeration(Collections.singleton(customHeaders.get(name)));
}
}
class ClonedServletInputStream extends ServletInputStream {
private final InputStream cachedBodyInputStream;
public ClonedServletInputStream(byte[] cachedBody) {
this.cachedBodyInputStream = new ByteArrayInputStream(cachedBody);
}
@Override
public boolean isFinished() {
try {
return cachedBodyInputStream.available() == 0;
} catch (IOException e) {
return true;
}
}
@Override
public boolean isReady() {
return true;
}
@Override
public void setReadListener(ReadListener readListener) {
}
@Override
public int read() throws IOException {
return cachedBodyInputStream.read();
}
}
Код: Выделить всё
@Component
public class IncomingRequestsAttributesInterceptor implements HandlerInterceptor {
private static final ThreadLocal currentResponse = new ThreadLocal();
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
ClonedHttpServletRequest clonedHttpServletRequest = new ClonedHttpServletRequest(request);
ClonedHttpServletResponse clonedHttpServletResponse = new ClonedHttpServletResponse(response);
Span span = Span.current();
span.setAttribute("request.payload",new String(clonedHttpServletRequest.getBody()));
currentResponse.set(clonedHttpServletResponse);
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
Span span = Span.current();
Optional optionalClonedHttpServletResponse = Optional.ofNullable(currentResponse.get());
optionalClonedHttpServletResponse.ifPresent(servletResponse -> span.setAttribute("response.payload", new String(servletResponse.getBody())));
currentResponse.remove();
}
}
Я даже переопределяю метод getInputStream(), но все равно что-то важное упущено. Может ли кто-нибудь мне помочь в этом отношении?
Подробнее здесь: https://stackoverflow.com/questions/788 ... till-be-ac
Мобильная версия