Есть ли какой-либо способ получить тело запроса в перехватчике, но контроллеры все равно могут получить к нему доступ?JAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Есть ли какой-либо способ получить тело запроса в перехватчике, но контроллеры все равно могут получить к нему доступ?

Сообщение Anonymous »

Я хочу получить доступ к HttpServletRequestBody в перехватчике, чтобы к нему по-прежнему могли обращаться нижестоящие контроллеры моего приложения, поскольку request.getInputStream(); можно использовать только один раз.
Я попытался реализовать собственный класс 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();
}
}
Здесь, в перехватчике, к нему осуществляется доступ и он успешно добавляется в диапазоне Opentelemtery (фактическая цель доступа к нему в перехватчике). Но после этого мой контроллер не сможет получить к нему доступ. Я столкнулся с ошибкой "Тело запроса пусто".
Я даже переопределяю метод getInputStream(), но все равно что-то важное упущено. Может ли кто-нибудь мне помочь в этом отношении?

Подробнее здесь: https://stackoverflow.com/questions/788 ... till-be-ac
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»