Как вы получаете доступ к опубликованным данным формы в сервлете?

Если у меня есть сервлет с JVM1.4.2, и он получает запрос POST с полями данных формы. Я использую req.getParameterNames(), чтобы получить, как я и ожидал, всю строку запроса и данные формы. Однако все, что я когда-либо получаю, это параметры строки запроса.

Литература Я читаю различные sources говорит, что getParameterNames() и getParameterValues(String) должны быть способом получения всей строки запроса и опубликованных данных формы, отправленных браузером для JDK 1.4. Вот метод, который я использую для извлечения всех параметров, которые, как я ожидаю, будут включать опубликованные данные формы:

public Map getParameterMap(HttpServletRequest req) {
        Map params= new HashMap();
        String name = null;
        System.out.println("<< Getting Parameter Map.>>");
        Enumeration enumParams = req.getParameterNames();
        for (; enumParams.hasMoreElements(); ) {
            // Get the name of the request parameter
            name = (String)enumParams.nextElement();

            // Get the value of the request parameters

            // If the request parameter can appear more than once 
            //   in the query string, get all values
            String[] values = req.getParameterValues(name);
            params.put(name, values);
            String sValues = "";
            for(int i=0;i<values.length;i++){
                if(0<i) {
                    sValues+=",";
                }
                sValues +=values[i];
            }
            System.out.println("Param " + name + ": " + sValues);
        }
        System.out.println("<< END >>");
        return params;
    }

Этот вопрос также соответствует моим ожиданиям, но сервлет не улавливает данные формы. Явно что-то упускаю....

Обновление: данные поста очень прямолинейны и не являются составной формой или мультимедиа. Просто обычный текст, отправленный через AJAX POST, который выглядит так в теле сообщения

c1=значение%20A&c2=значение%20B&c3=значение%20C


person angryITguy    schedule 16.08.2011    source источник
comment
Как выглядит форма? В частности, сам элемент form и пример элементов input / select / textarea на нем.   -  person T.J. Crowder    schedule 16.08.2011
comment
Для минусующего. Если вы собираетесь -1, пожалуйста, скажите, почему, и я мог бы улучшить вопрос.... :s   -  person angryITguy    schedule 16.08.2011
comment
@TJ, так ты говоришь, что не все данные формы равны? Что современные браузеры делают различия в данных формы, которые не обнаруживаются сервлетами под старыми JVM?   -  person angryITguy    schedule 16.08.2011
comment
Я говорю, что это может быть связано с кодировкой данных формы (которые будут раскрыты вашим элементом form) и различными потенциальными ошибками в разметке HTML, и мы могли бы помочь вам с ними, если бы вы их показали. И мой комментарий о JVM 1.4.2, который какой-то гиперактивный модератор совершенно неуместно удалил, также уместен: В этой отрасли использование сильно устаревших технологий, как правило, вызывает у вас проблемы.   -  person T.J. Crowder    schedule 16.08.2011
comment
Модератору, который полностью неправомерно удалил мой предыдущий комментарий: Тот факт, что JVM 1.4.2 была заменена семь лет назад, имеет отношение к вопросу, поскольку использование устаревших технологий, как правило, вызывает проблемы.   -  person T.J. Crowder    schedule 16.08.2011
comment
Как бы я ни хотел использовать текущую JVM, бизнес-требования диктуют иное. В них заложена задача на правильные ответы.   -  person angryITguy    schedule 16.08.2011
comment
@giulio: Понятно. Удачи! Я склонен сомневаться, что проблема заключается в JVM 1.4.2. Опять же, вы опубликуете соответствующий HTML-код вашей формы...   -  person T.J. Crowder    schedule 16.08.2011
comment
@Т.Дж. Crowder Постарайтесь впредь не начинать комментарии с «не по теме -», и они могут не быть удалены из-за флажков :) Комментарии временны, граждане второго сорта, когда дело доходит до вопросов и ответов. Не обижайте свои чувства, если один из них будет удален.   -  person Tim Post♦    schedule 16.08.2011
comment
@ Тим: Спасибо. Это я сделал? Я не должен был, это было не по теме. Дело не в обиде, кстати. Вопрос в том, чтобы не уничтожить SO сверхактивной модерацией.   -  person T.J. Crowder    schedule 16.08.2011
comment
@TJ. Ну, нет большой разницы между чрезмерной модерацией и стебом не по теме, который не способствует получению ответа.   -  person angryITguy    schedule 16.08.2011


Ответы (2)


Мне удалось выявить проблему. Поскольку вокруг JDK 1.5+ много болтовни и разговоров о методе getParameterMaps() для версии 1.5, информация о том, как версия 1.4 обрабатывает данные из сообщений, была скудной и неоднозначной. (Пожалуйста, оставьте комментарий, если вы найдете что-то конкретное для 1.4).

До версии 1.5 вам необходимо вручную получить данные формы через getInputStream, а затем проанализируйте его. Я нашел этот метод (опубликован ниже) из сайт java sun, который отлично справляется с использованием Hashtable. Мне пришлось сделать небольшой мод для устаревших методов. Но, кажется, работает довольно надежно, «из коробки», поэтому вы должны просто копировать и вставлять. Я знаю, что это «старая технология», но я подумал, что это полезно для тех, кто может оказаться в той же ситуации, что и я, кто застрял в решении (казалось бы) прямых проблем.

public Hashtable parsePostData(int length, ServletInputStream instream) {
                String valArray[] = null;
                int inputLen, offset;
                byte[] postedBytes = null;
                boolean dataRemaining=true;
                String postedBody;
                Hashtable ht = new Hashtable();
                //Vector paramOrder = new Vector(10);
                StringBuffer sb = new StringBuffer();

                if (length <=0) {
                  return null;
                }
                postedBytes = new byte[length];
                try {
                   offset = 0;
                   while(dataRemaining) {
                     inputLen = instream.read (postedBytes, offset, length - offset);
                     if (inputLen <= 0) {
                       throw new IOException ("read error");
                     }
                     offset += inputLen;
                     if((length-offset) ==0) {
                       dataRemaining=false;
                     }
                   }
                } catch (IOException e) {
                  System.out.println("Exception ="+e);
                  return null;
                }

                postedBody = new String (postedBytes);
                StringTokenizer st = new StringTokenizer(postedBody, "&");

                String key=null;
                String val=null;

                while (st.hasMoreTokens()) {
                  String pair = (String)st.nextToken();
                  int pos = pair.indexOf('=');
                  if (pos == -1) {
                    throw new IllegalArgumentException();
                  }
                  try {
                     key = URLDecoder.decode(pair.substring(0, pos),"UTF8");
                     val = java.net.URLDecoder.decode(pair.substring(pos+1,pair.length()),"UTF8");
                  } catch (Exception e) {
                     throw new IllegalArgumentException();
                  }
                  if (ht.containsKey(key)) {
                    String oldVals[] = (String []) ht.get(key);
                    valArray = new String[oldVals.length + 1];
                    for (int i = 0; i < oldVals.length; i++) {
                       valArray[i] = oldVals[i];
                    }
                    valArray[oldVals.length] = val;
                  } else {
                    valArray = new String[1];
                    valArray[0] = val;
                  }
                  ht.put(key, valArray);
                  String sValues = "";
                  for(int i=0;i<valArray.length;i++) {
                      if (0<i) {
                          sValues+=",";
                      }
                      sValues = valArray[i];
                  }
                  System.out.println("Form data field " + key + ":" +sValues); 
                  //paramOrder.addElement(key);
                }
                return ht;
              }
person angryITguy    schedule 16.08.2011
comment
Это неправильно. Во-первых, вы путаете J2EE с J2SE. Версия J2EE создается отдельно от J2SE Development Kit. Во-вторых, способ извлечения почтовых данных не изменился, по крайней мере, с версии 1.3 J2EE, то есть около 8 или 10 лет. Ручной разбор ответа, безусловно, сработает, но это ни в коем случае не требуется и не рекомендуется. Как уже упоминалось, если вы покажете соответствующий HTML, вы получите лучшие ответы. - person Ryan Stewart; 16.08.2011
comment
Стандартные POST-данные. Ничего экзотического. Используя Fiddler 2, я получаю довольно простые данные поста, такие как c1=Value%20A&c2=Value%20B&c3=Value%20C . Рад признать свое незнание временных рамок и наборов функций J2SE/J2EE. Пока все говорят, что не так, а не как это сделать. Я опубликовал решение, которое действительно работает. Конечно, это может быть не лучший способ, но он работает и кажется надежным. Помогите улучшить.... - person angryITguy; 16.08.2011
comment
Вы все еще не показали HTML. Заголовки запросов тоже могут помочь. Все, что я могу предложить, это попробовать что-то более простое, например Enumeration names = request.getParameterNames(); System.out.println("Param names:"); while (names.hasMoreElements()) System.out.println(names.nextElement());. Если это не дает ожидаемого результата, попробуйте проверить объект запроса в отладчике после вызова одного из методов, связанных с параметрами. - person Ryan Stewart; 17.08.2011
comment
@Райан. Код, который вы указали, также совпадает с моим исходным образцом кода, указанным в вопросе. Вызов не из HTML-формы. Это вызов AJAX, выполненный как транзакция POST. Мне удалось найти решение, которое, вероятно, является долгим путем. Оставшаяся возможность для респондентов на этот вопрос — указать лучший способ сделать это при использовании JDK 1.4. - person angryITguy; 17.08.2011
comment
Обновил мой ответ. Проверьте это. - person Ryan Stewart; 18.08.2011
comment
Для downvoter на мой ответ. Если я могу подтвердить, что это рабочее решение. Зачем голосовать против? По крайней мере, имейте любезность (и смелость) указать, что делает это решение неэффективным. - person angryITguy; 18.08.2011
comment
+1 Этот парень только что проголосовал за вас, потому что он думает, что он такой хороший, и я думаю, что эти люди с огромным эго должны держать свою репутацию там, где не светит солнце. - person Shahzeb; 29.09.2011

Это правда. Методы getParameterNames(), getParameterValues() и getParameter() — это способ доступа к данным формы, если это не составная форма, и в этом случае вам придется использовать что-то вроде Commons Fileupload, чтобы проанализировать составной запрос до того, как вам станут доступны все параметры.

Изменить: вы, вероятно, неправильно кодируете данные POST в своем вызове AJAX. Данные POST должны иметь Content-Type application/x- www-form-urlencoded или multipart/form-data. Если вы отправляете его как что-то другое, он не квалифицируется как параметр запроса, и я ожидаю, что вы увидите поведение, которое описываете. Разработанное вами решение по существу состоит из настройки пользовательского анализа пользовательского содержимого.

person Ryan Stewart    schedule 16.08.2011
comment
хорошо .. это новый путь для расследования. Я установлю тип содержимого, а затем повторно запущу исходный код для getParameterNames и попробую это. - person angryITguy; 18.08.2011
comment
Я проверил тип контента, и он возвращается как application/x-www.form-urlencoded, поэтому проблема не вызвана типом контента. Спасибо за мысль. - person angryITguy; 20.08.2011
comment
приложение/x-www.form-urlencoded != приложение/x-www.form-urlencoded; В том, что . опечатка? Если вы скопировали/вставили это значение, то оно неверно. - person Ryan Stewart; 20.08.2011