0

If I have a servlet running JVM1.4.2, and it is receiving a POST request with form data fields. I use req.getParameterNames() to get, what I would expect, all the query string and form data. However, all I ever get are the querystring parameters.

Literature I am reading from various sources says that getParameterNames() and getParameterValues(String) should be the way to get all query string and posted form data sent by the browser for JDK 1.4. Here is the method I use to extract all the parameters, which I expect would include posted form data :

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;
    }

This question also agrees with my expectations, but the servlet is not picking up the form data. Obviously I am missing something....

Update: The post data is very straight forward and is not a Multipart form or rich media. Just plain'ol text submitted via an AJAX POST that looks like this in post body

c1=Value%20A&c2=Value%20B&c3=Value%20C

Community
  • 1
  • 1
angryITguy
  • 9,332
  • 8
  • 54
  • 82
  • What does the form look like? In particular, the `form` element itself, and an example of the `input` / `select` / `textarea` element(s) on it. – T.J. Crowder Aug 16 '11 at 05:10
  • To the downvoter. If you're gonna -1 it, please say why, and I might be able to improve the question.... :s – angryITguy Aug 16 '11 at 06:12
  • 1
    @TJ so are you saying that not all form data is "equal"? That the modern browsers make distinctions in the form data not detected by servlets under older JVM's ? – angryITguy Aug 16 '11 at 06:16
  • I'm saying that the encoding of the form data (which would be revealed by your `form` element) and various potential errors in the HTML markup could account for it, and we could help you with those if you showed them. And my JVM 1.4.2 comment, which some hyperactive moderator *completely inappropriately* deleted, is also germane: In this industry, using massively out-of-date technology will tend to cause you trouble. – T.J. Crowder Aug 16 '11 at 06:55
  • To the moderator who **completely** inappropriately deleted my earlier comment: The fact that JVM 1.4.2 was superceded seven years ago is relevant to the question, in that using outdated tech will tend to cause issues. – T.J. Crowder Aug 16 '11 at 07:10
  • 1
    As much as I would like to use a current JVM, business requirements dictate otherwise. Their lay the challenge for "correct answer" points. – angryITguy Aug 16 '11 at 08:04
  • `@giulio`: Understood. Good luck with it! I do tend to doubt that JVM 1.4.2 is the problem. Again, you'll post the relevant HTML of your form... – T.J. Crowder Aug 16 '11 at 08:12
  • 1
    @T.J. Crowder Try to not preface comments with 'off topic -' in the future, and they might not be deleted due to flags :) Comments are temporary, second class citizens when it comes to questions and answers. Don't get your feelings hurt if one is removed. – Tim Post Aug 16 '11 at 08:22
  • @Tim: Thanks. Did I do that? I shouldn't have, it wasn't off-topic. It's not a matter of hurt feelings, btw. It's a matter of not destroying SO with overactive moderation. – T.J. Crowder Aug 16 '11 at 08:59
  • 1
    @TJ. Well, there is not much difference between "over-moderation" and "off-topic" banter that does not work towards producing an answer – angryITguy Aug 16 '11 at 11:45

2 Answers2

0

That's true. The getParameterNames(), getParameterValues(), and getParameter() methods are the way to access form data unless it's a multipart form, in which case you'll have to use something like Commons Fileupload to parse the multipart request before all the parameters are accessible to you.

Edit: You're probably not encoding the POST data properly in your AJAX call. POST data must carry a Content-Type of application/x-www-form-urlencoded or else multipart/form-data. If you're sending it as something else, it doesn't qualify as a request parameter, and I expect you'd see the behavior you're describing. The solution you've engineered essentially consists of setting up custom parsing of custom content.

Ryan Stewart
  • 126,015
  • 21
  • 180
  • 199
  • ok.. this is a new avenue to investigate. I'll set the content-type and then re-run the original code for getParameterNames and try that. – angryITguy Aug 18 '11 at 04:31
  • I inspected the content-type and it comes back as "application/x-www.form-urlencoded" so the issue is not caused by content-type.Thanks for the thought. – angryITguy Aug 20 '11 at 05:59
  • application/x-www.form-urlencoded != application/x-www-form-urlencoded; Is that "." a typo? If you copy/pasted that value, then it's wrong. – Ryan Stewart Aug 20 '11 at 06:03
0

I managed to identify the problem. Because there is so much chatter from JDK 1.5+ and talk of getParameterMaps() method for 1.5, info on how 1.4 handles form post data was scarce and ambiguous. (Please post a comment if you find something that is specific for 1.4).

Pre-1.5 you have to manually get the form data via getInputStream, and then parse it out. I found this method, (posted below), from the java sun site that does a nice job using a Hashtable. I had to make a minor mod for deprecated methods. But seems to work quite robustly, "out of the box", so you should able to just cut-n-paste. I know it's "old tech" but I thought it worthwhile for those who may be in the same situation as me who are stuck on solving (what seems to be) straight forward problems.

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;
              }
angryITguy
  • 9,332
  • 8
  • 54
  • 82
  • 1
    That's not correct. First, you're confusing J2EE with J2SE. J2EE is versioned separately from the J2SE Development Kit. Second, the way post data is retrieved hasn't changed since at least version 1.3 of J2EE, which is some 8 or 10 years. Manually parsing the response will certainly work, but it's by no means either required or recommended. As others have mentioned, if you show the relevant HTML, you'll get better answers. – Ryan Stewart Aug 16 '11 at 13:00
  • 1
    Standard POST data. It's nothing exotic. Using Fiddler 2 I get some pretty straight forward post data like this c1=Value%20A&c2=Value%20B&c3=Value%20C . Happy to admit my ignorance of the J2SE/J2EE timelines and feature sets. So far everyone is saying what's wrong rather than how to do it. I have posted a solution that actually works. Sure it may not be "the best way" but it works and seems robust. Help me improve it.... – angryITguy Aug 16 '11 at 13:30
  • You still haven't shown the HTML. Request headers could help, too. All I can suggest is that you try something simpler--something like `Enumeration names = request.getParameterNames(); System.out.println("Param names:"); while (names.hasMoreElements()) System.out.println(names.nextElement());` If that doesn't give the expected output, try inspecting the request object in a debugger *after* calling one of the parameter-related methods. – Ryan Stewart Aug 17 '11 at 02:43
  • @Ryan. The code you have quoted is also the same as my original sample code listed in the question. The call is not from a HTML form. It's an AJAX call done as a "POST" transaction. I have managed to find a solution that is probably the long way of doing it. The remaining opportunity for respondents to this question is to point out a better way to do it for if using JDK 1.4. – angryITguy Aug 17 '11 at 05:19
  • Updated my answer. Check it out. – Ryan Stewart Aug 18 '11 at 02:41
  • To the downvoter on my answer. If I can confirm that it's a functioning solution. Why down vote it ? At least have the courtesy (and courage) to specify what makes this an in-effective solution. – angryITguy Aug 18 '11 at 07:11
  • 1
    +1 This guy just down voted you because he thinks he is so good and I think these people who have got huge ego should stick their repute where sun does not shine. – Shahzeb Sep 29 '11 at 03:40