Параметр POST пуст, но присутствует в теле - PullRequest
0 голосов
/ 28 октября 2019

У меня есть приложение, которое прекрасно работает на локальном компьютере, но на клиенте оно падает, потому что параметр POST имеет значение null.

((HttpServletRequest)request).getParameter("dtid");

Это возвращает значение NULL.

Итак, я добавилфильтр для входа GET / POST / BODY запроса. Локально журнал выглядит так:

[МЕТОД: POST] [URI ЗАПРОСА: / peps / zkau] [REQUEST ПАРАМЕТРЫ: {dtid = z_0n8, uuid_0 = x38Pz,data_0 = {"pageX": 372, "pageY": 103, "which": 1, "x": 40.79998779296875, "y": 4}, cmd_0 = onClick}] [ REQUEST BODY :][УДАЛЕННЫЙ АДРЕС: 0: 0: 0: 0: 0: 0: 0: 1]

У меня есть dtid в параметре запроса, и тело пусто. На клиенте тот же журнал выглядит так:

[МЕТОД: POST] [URI ЗАПРОСА: / peps / zkau] [REQUEST ПАРАМЕТРЫ: {} ] [REQUESTBODY * тысяча двадцать две *: dtid = z_cb50 & cmd_0 = OnOpen & uuid_0 = l2sT30 & data_0 =% 7B% 22open% 22% 3Atrue% 2C% 22reference% 22% 3A% 22l2sT20% 22% 7D & cmd_1 = OnClick & uuid_1 = l2sT40 & данные_1 =% 7B% 22pageX% 22% 3A323% 2C% 22pageY% 22% 3A138% 2C% 22, которые% 22% 3A1% 2C% 22x% 22% 3A323% 2C% 22y% 22% 3A138% 7D & cmd_2 = onOpen & uuid_2 = l2sT30 & data_2 =% 7B% 22open% 22% 3AEsese 7DАДРЕС: xxxx]

Параметры - пустая карта, но тело заполнено. Тело кажется необработанным, что может вызвать это? Почему тело не анализируется и не вводится в карту параметров?

Спасибо

Вот мой фильтр:

public class PepsParamFilter implements Filter {

    private static final Logger LOG = Logger.getLogger(PepsParamFilter.class.getName());

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        try {
            HttpServletRequest httpServletRequest = (HttpServletRequest) request;

            Map<String, String> requestMap = this.getTypesafeRequestMap(httpServletRequest);
            BufferedRequestWrapper bufferedReqest = new BufferedRequestWrapper(httpServletRequest);            

            chain.doFilter(bufferedReqest, response);

             //Request
                final StringBuilder reqMessage = new StringBuilder("").append("[METHOD:")
                        .append(httpServletRequest.getMethod())                        
                        .append("] [REQUEST URI:")
                        .append(httpServletRequest.getRequestURI())                        
                        .append("] [REQUEST PARAMETERS:").append(requestMap)
                        .append("] [REQUEST BODY:")
                        .append(bufferedReqest.getRequestBody())
                        .append("] [REMOTE ADDRESS:")
                        .append(httpServletRequest.getRemoteAddr()).append("]");
                if(!httpServletRequest.getRequestURI().endsWith(".gif")
                    && !httpServletRequest.getRequestURI().endsWith(".png")
                    && !httpServletRequest.getRequestURI().endsWith(".css")
                    ) {
                    LOG.info(reqMessage);
                }



        } catch (Throwable a) {
            LOG.error(a.getMessage(),a);
        }
    }

    private Map<String, String> getTypesafeRequestMap(HttpServletRequest request) {
        Map<String, String> typesafeRequestMap = new HashMap<String, String>();
        Enumeration<?> requestParamNames = request.getParameterNames();
        while (requestParamNames.hasMoreElements()) {
            String requestParamName = (String) requestParamNames.nextElement();
            String requestParamValue = request.getParameter(requestParamName);
            typesafeRequestMap.put(requestParamName, requestParamValue);
        }
        return typesafeRequestMap;
    }

    @Override
    public void destroy() {
    }

    private static final class BufferedRequestWrapper extends
            HttpServletRequestWrapper {

        private ByteArrayInputStream bais = null;
        private ByteArrayOutputStream baos = null;
        private BufferedServletInputStream bsis = null;
        private byte[] buffer = null;

        public BufferedRequestWrapper(HttpServletRequest req)
                throws IOException {
            super(req);
            // Read InputStream and store its content in a buffer.
            InputStream is = req.getInputStream();
            this.baos = new ByteArrayOutputStream();
            byte buf[] = new byte[1024];
            int letti;
            while ((letti = is.read(buf)) > 0) {
                this.baos.write(buf, 0, letti);
            }
            this.buffer = this.baos.toByteArray();
        }

        @Override
        public ServletInputStream getInputStream() {
            this.bais = new ByteArrayInputStream(this.buffer);
            this.bsis = new BufferedServletInputStream(this.bais);

            return this.bsis;
        }

        @Override
        public BufferedReader getReader() throws IOException {
            return new BufferedReader(new InputStreamReader(this.getInputStream()));
        }

        String getRequestBody() throws IOException {
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    this.getInputStream()));
            String line = null;
            StringBuilder inputBuffer = new StringBuilder();
            do {
                line = reader.readLine();
                if (null != line) {
                    inputBuffer.append(line.trim());
                }
            } while (line != null);
            reader.close();
            return inputBuffer.toString().trim();
        }

    }

    private static final class BufferedServletInputStream extends
            ServletInputStream {

        private ByteArrayInputStream bais;

        public BufferedServletInputStream(ByteArrayInputStream bais) {
            this.bais = bais;
        }

        @Override
        public int available() {
            return this.bais.available();
        }

        @Override
        public int read() {
            return this.bais.read();
        }

        @Override
        public int read(byte[] buf, int off, int len) {
            return this.bais.read(buf, off, len);
        }

    }

    public class TeeServletOutputStream extends ServletOutputStream {

        private final TeeOutputStream targetStream;

        public TeeServletOutputStream(OutputStream one, OutputStream two) {
            targetStream = new TeeOutputStream(one, two);
        }

        @Override
        public void write(int arg0) throws IOException {
            this.targetStream.write(arg0);
        }

        public void flush() throws IOException {
            super.flush();
            this.targetStream.flush();
        }

        public void close() throws IOException {
            super.close();
            this.targetStream.close();
        }
    }


}

Ответы [ 2 ]

1 голос
/ 01 ноября 2019

Раздел 3.1.1 Servlet-spec сообщает:

3.1.1, когда доступны параметры

Следующееусловия, которые должны быть выполнены, прежде чем данные формы будут заполнены набором параметров:

  1. Запрос является запросом HTTP или HTTPS.
  2. Метод HTTP - POST.
  3. Тип содержимого - application / x-www-form-urlencoded.
  4. Сервлет сделал начальный вызов любого из методов семейства getParameter для объекта запроса.

Если условия не выполняются и данные формы сообщения не включены в набор параметров, данные публикации все еще должны быть доступны сервлету через поток ввода объекта запроса. Если условия соблюдены, данные почтовой формы больше не будут доступны для чтения непосредственно из входного потока объекта запроса.

Необходимо проверить, по-разному ли какое-либо из этих условий применяется к вашей локальной или клиентской системе. .

Могут быть другие фильтры (в цепочке фильтров перед вами), которые уже обрабатывают тело запроса, или изменяют тип содержимого, или ранее обращались к одному из методов getParameter *, или переносили запрос .. . (Вы получаете точку)

По сути, оба состояния действительны в зависимости от того, что произошло с вашим запросом ранее.

Первое, что нужно проверить, будет ли браузер отправлять одно и то жезапрос (/ тело) и заголовки. Например, в инструментах разработчика браузера. Если они идентичны, проверьте в своем файле web.xml дополнительные фильтры (например, фильтры безопасности часто различаются в локальной среде разработки и в рабочей среде).

0 голосов
/ 28 октября 2019

При вызове POST параметры будут отправлены в теле запроса, которое происходит в журналах с вашего сервера. Поэтому вам нужно получить тело запроса для доступа к нужным параметрам, см. Этот вопрос о том, как получить данные поста.

...