Использование ContentCachingRequestWrapper вызывает пустую карту параметров

Я реализовал фильтр, в котором я хочу сначала прочитать содержимое запроса для некоторых проверок, а затем я хотел бы продолжить.

Но проблема в том, что в следующем фильтре из цепочки фильтров вызывается метод getParameters() из class Request (org.eclipse.jetty.server.Request), а не метод getParameters() из class ContentCachingRequestWrapper. Значит, parametersMap не заполняется и всегда пуст.

Вот как выглядит мой код:

@Component
@Order(1)
public class EncodingFilter extends GenericFilterBean {

private static final Logger LOG = 
LoggerFactory.getLogger(EncodingFilter.class);

@Override
public void doFilter(ServletRequest request, ServletResponse response, 
FilterChain chain) throws IOException, ServletException {

final HttpServletRequest req = (HttpServletRequest) request;
HttpServletRequest servletRequest = new ContentCachingRequestWrapper(req);

String read = ByteSource.wrap(ByteStreams.toByteArray(servletRequest.getInputStream()))
        .asCharSource(StandardCharsets.UTF_8).read();
// Doing analysis .....
// last step call filter chain
chain.doFilter(servletRequest, response);
}
}

И в контроллере:

@PostMapping(
    value = Endpoints.Janus.INIT,
    produces = MediaType.TEXT_HTML_VALUE
)
public ModelAndView controller(
    @RequestParam LinkedCaseInsensitiveMap<String> params,
    HttpServletRequest servletRequest
) {
 ....  
}

В контроллере карта параметров всегда пуста. Если я не вызываю servletRequest.getInputStream () в моем фильтре, карта параметров заполняется.

Я работаю с Spring Boot 1.5.6 с Jetty в качестве сервера приложений

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
3
0
12 187
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Попробуйте два предлагаемых решения, упомянутых ниже:
1. HttpServletRequestWrapper servletRequest = new ContentCachingRequestWrapper(req);
OR
2. ContentCachingRequestWrapper servletRequest = new ContentCachingRequestWrapper(req);
Вместо HttpServletRequest servletRequest = new ContentCachingRequestWrapper(req);
Как вы можете проверьте здесь, этот класс ContentCachingRequestWrapperрасширяетHttpServletRequestWrapper, который расширяетServletRequestWrapper и орудияHttpServletRequest.
Итак, здесь, выполнив восходящий, вы столкнетесь с этой проблемой. Пожалуйста, проверьте и дайте мне знать, если это не так, я буду отлаживать его дальше.

Спасибо за поддержку, Виктор. К сожалению, ни одно из обоих решений не решило мою проблему.

Michael Kronberger 13.03.2018 08:49

ОК, буду смотреть дальше.

VijayD 13.03.2018 09:20

Это не имеет смысла.

MiraGe 08.04.2021 12:40
Ответ принят как подходящий

ContentCachingRequestWrapper так не работает и имеет некоторые ограничения. Насколько я помню, только запрос POST и тип содержимого должны быть application/x-www-form-urlencoded. Если это вам подходит, вот что вам следует сделать:

final HttpServletRequest req = (HttpServletRequest) request;
HttpServletRequest servletRequest = new ContentCachingRequestWrapper(req);
servletRequest.getParameterMap(); // needed for caching!!

String read = ByteSource.wrap(servletRequest.getContentAsByteArray())
    .asCharSource(StandardCharsets.UTF_8).read(); // Please note that we're not touching input stream!!

Надеюсь это поможет.

Большое спасибо. Это было решение

Michael Kronberger 13.03.2018 10:09

@MichaelKronberger, пожалуйста, примите этот ответ, если он был полезен. заранее спасибо

Leffchik 13.03.2018 10:19

Красиво объяснено! за ответ!

VijayD 13.03.2018 10:20

Примечание: multipart/form-data также имеет отношение к request.getParameter, вызывающим а также многокомпонентные методы request.getPart.

Joakim Erdfelt 13.03.2018 15:36

Что такое ByteSource?

Rohit Salecha 14.02.2020 10:45

Другие вопросы по теме