java .lang.IllegalStateException: Невозможно вызвать getInputStream () после того, как getReader () уже был вызван для текущего запроса. - PullRequest
0 голосов
/ 23 марта 2020

Я написал перехватчик:

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    log.info("[pre-handle] method: {}\tURL: {}", request.getMethod(), request.getRequestURL());
    if (HttpMethod.POST.name().equals(request.getMethod())) {
        log.info(request.getReader().lines().collect(Collectors.joining()));
    }
    return true;
}

, но когда я пытаюсь вызвать контроллер, возникает исключение:

java .lang.IllegalStateException: Невозможно вызвать getInputStream () после getReader () уже был вызван для текущего запроса

, как я понимаю, вызов getReader () закрывает InputStream и ничего не поступает в контроллер. Как это исправить?

1 Ответ

1 голос
/ 23 марта 2020

Чтобы прочитать запрос несколько раз, вам нужно будет кэшировать ваш запрос, прежде чем он будет прочитан в первый раз. Дополнительную информацию можно прочитать здесь .

Spring MVC предоставляет класс ContentCachingRequestWrapper. Это обертка вокруг оригинального объекта HttpServletRequest.

Чтобы использовать его, мы должны сначала создать веб-фильтр, который оборачивает оригинальный запрос HttpServletRequest:

@Component
public class CachingRequestBodyFilter extends GenericFilterBean {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
      throws IOException, ServletException {
        HttpServletRequest currentRequest = (HttpServletRequest) servletRequest;
        ContentCachingRequestWrapper wrappedRequest = new ContentCachingRequestWrapper(currentRequest);
        chain.doFilter(wrappedRequest, servletResponse);
    }

После чего вы можете получить содержимое byte [] с помощью метода getContentAsByteArray ContentCachingRequestWrapper в вашем перехватчик.

...