Java 如何在servlet中访问已发布的表单数据?
如果我有一个运行JVM1.4.2的servlet,它正在接收带有表单数据字段的POST请求。我使用req.getParameterNames获得我所期望的所有查询字符串和表单数据。然而,我得到的只是查询字符串参数 我来自不同的文献说,和getParameterValuesString应该是获取JDK1.4浏览器发送的所有查询字符串和发布表单数据的方法。以下是我用来提取所有参数的方法,我希望这些参数包括已发布的表单数据:Java 如何在servlet中访问已发布的表单数据?,java,forms,servlets,post,jdk1.4,Java,Forms,Servlets,Post,Jdk1.4,如果我有一个运行JVM1.4.2的servlet,它正在接收带有表单数据字段的POST请求。我使用req.getParameterNames获得我所期望的所有查询字符串和表单数据。然而,我得到的只是查询字符串参数 我来自不同的文献说,和getParameterValuesString应该是获取JDK1.4浏览器发送的所有查询字符串和发布表单数据的方法。以下是我用来提取所有参数的方法,我希望这些参数包括已发布的表单数据: public Map getParameterMap(HttpServlet
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;
}
这个问题也符合我的期望,但servlet并没有拾取表单数据。很明显,我错过了什么
更新:post数据非常直截了当,不是多部分形式或富媒体。只是通过一篇AJAX文章提交的纯文本,在文章正文中看起来像这样
c1=值%20A&c2=值%20B&c3=值%20C没错。getParameterNames、getParameterValues和getParameter方法是访问表单数据的方法,除非它是一个多部分表单,在这种情况下,您必须在访问所有参数之前使用类似于解析多部分请求的方法
编辑:您可能没有在AJAX调用中正确编码POST数据。POST数据必须包含内容类型或多部分/表单数据。如果您将其作为其他内容发送,则它不符合请求参数的条件,并且我希望您能够看到所描述的行为。您设计的解决方案基本上包括设置自定义内容的自定义解析。我设法找到了问题所在。由于JDK1.5+中有太多的闲话和1.5中的getParameterMaps方法,关于1.4如何处理表单post数据的信息非常稀少,而且模棱两可。如果您发现1.4中有特定内容,请发表评论 在1.5之前,您必须通过手动获取表单数据,然后将其解析出来。我从JavaSun站点找到了下面发布的方法,它使用哈希表做得很好。我不得不为不推荐的方法做一个小的修改。但它似乎非常有效,开箱即用,所以你应该可以直接剪切粘贴。我知道这是一项古老的技术,但我认为对于那些可能与我处于相同处境的人来说,这是值得的,因为他们一直在解决看似直截了当的问题
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;
}
表格是什么样子的?特别是表单元素本身,以及其中的一个输入/选择/文本区域元素的示例。@TJ那么你是说并非所有表单数据都是相等的吗?现代浏览器对旧JVM下的Servlet未检测到的表单数据进行区分?尽管我很想使用当前JVM,但业务需求要求不同。他们的评论对正确答案提出了挑战。@T.J.Crowder今后尽量不在评论前加上“离题-”,而且这些评论可能不会因为标志而被删除:当涉及到问题和答案时,评论是临时的二等公民。如果一个被移除,不要让你的感情受到伤害。@TJ。好吧,过度节制和离题玩笑之间并没有太大区别,因为离题玩笑不利于产生不正确的答案。首先,您混淆了J2EE和J2SE。J2EE的版本与J2SE开发工具包是分开的。其次,从J2EE的1.3版开始,post数据的检索方式就没有改变过,大约有8到10年了。手动解析响应肯定会起作用,但决不是必需的或推荐的。正如其他人所提到的,如果你显示相关的HTML,你会得到更好的答案。没有什么异国情调。使用Fiddler 2,我得到了一些非常直接的post数据,比如c1=Value%20A&c2=Value%20B&c3=Value%20C。很高兴承认我对J2SE/J2EE时间表和功能集一无所知。到目前为止,每个人都在说什么不对,而不是怎么做。我发布了一个实际可行的解决方案。当然,这可能不是最好的方法,但它很有效,而且看起来很健壮。帮我改进一下……你还没有显示HTML。请求头也会有所帮助。我建议您尝试一些更简单的方法,比如枚举名称=request.getParameterNames;System.out.printlnParam名称:;而names.hasMoreElements System.out.printlnnames.nextElement;如果这不能提供预期的输出,请在调用一个与参数相关的方法后,尝试在调试器中检查请求对象。@Ryan。您引用的代码与问题中列出的原始示例代码相同。调用不是来自HTML表单。这是一个作为POST事务完成的AJAX调用。我已经设法找到了一个解决方案,这可能是一个漫长的过程。对于这个问题的回答者来说,剩下的机会是指出一个更好的方法,如果使用JDK 1.4.+1,那么这个家伙刚刚否决了你,因为他认为自己很好,我认为这些有着巨大自我的人应该把他们的名声保持在阳光不照的地方。好的。。这是一个新的a
调查地点。我将设置内容类型,然后重新运行getParameterNames的原始代码并进行尝试。我检查了内容类型,它返回为application/x-www.form-urlencoded,因此问题不是由内容类型引起的。感谢您的思考。application/x-www.form-urlencoded!=application/x-www-form-urlencoded;是的。打字错误?如果复制/粘贴该值,则该值是错误的。