【原】Http-用getInputStream()或者getParameterMap()获得Post请求的数据

【前言】

最近在写一个接口,写好以后想测试,自己写ajax(Post方法)来调用接口倒是可以用action所在类的属性的get/set方法获得数据。但是不只是页面的ajax会调用这个接口,还有外系统会调用,所以我就自己写普通的Java代码(不是web项目)来调用,之后我就瞎了,因为收不到传来的参数啊!!【万一连不通怎么办?各种找原因以及看项目里其他的代码,我发现了一些细节。。项目里其他的代码有的是使用httpServletRequest的实例用getParameterMap()来获得信息内容的,但是我用的是getInputStream(),这之中到底有什么玄机?

【获得的知识】

其实之前还经过了很多迷糊的时刻,才终于知道应该查什么知识了,中间的曲折因为没有学到什么就不扯淡了。直奔主题。
搜了这两种方法名,看到了csdn上面一个帖子有人问了这个问题,回答中有一个比较清晰的(我在这直接就抄过来了):

根据Servlet规范,如果同时满足下列条件,则请求体(Entity)中的表单数据,将被填充到request的parameter集合中(request.getParameter系列方法可以读取相关数据):
1 这是一个HTTP/HTTPS请求
2 请求方法是POST(querystring无论是否POST都将被设置到parameter中)
3 请求的类型(Content-Type头)是application/x-www-form-urlencoded
4 Servlet调用了getParameter系列方法

如果上述条件没有同时满足,则相关的表单数据不会被设置进request的parameter集合中,相关的数据可以通过request.getInputStream()来访问。反之,如果上述条件均满足,相关的表单数据将不能再通过request.getInputStream()来读取。

Servlet Specifiaction 3.0:
3.1.1 When Parameters Are Available
The following are the conditions that mustbe met before post form data will be
populated to the parameter set:
1. The request is an HTTP or HTTPS request.
2. The HTTP method is POST.
3. The content type is application/x-www-form-urlencoded.
4. The servlet has made an initial call of any of the getParameterfamily of methods
on the request object.
If the conditions are not met and the post form data is not included in the parameter
set, the post data must still be available to the servlet via the request object’s input
stream. If the conditions are met, post form data will no longer be available for
reading directly from the request object’s input stream.

类似的例子,还有response.getOutputStream和getWriter,它们往往也是一对矛盾体 。

从这可以看出是四个条件缺一不可的时候才能使用getParameterMap()方法来获得内容的,如果有一条不满足,就不能用这个方法。
然后我查了一下”请求的类型Content-Type“是个什么东东。于又找到一个帖子 还有很多哈,但是大概了解了一些就是:
form 中Enctype=multipart/form-data 的作用
表单中enctype=”multipart/form-data”的意思,是设置表单的MIME编码。默认情况,这个编码格式是application/x-www-form-urlencoded,不能用于文件上传;
只有使用了multipart/form-data,才能完整的传递文件数据,进行下面的操作.
在Form元素的语法中,EncType表明提交数据的格式,用 Enctype 属性指定将数据回发到服务器时浏览器使用的编码类型。
下边是说明:
(1) application/x-www-form-urlencoded:窗体数据被编码为名称/值对。这是标准的编码格式,具体的数据例子如下所示。

custname=苏林&elecontid=elecontid0001&idtype=0&idno=411303198802190512&custage=30&education=20

(2) multipart/form-data:窗体数据被编码为一条消息,页上的每个控件对应消息中的一个部分。
(3) text/plain:窗体数据以纯文本形式进行编码,其中不含任何控件或格式字符。

ENCTYPE=”multipart/form-data”用于表单里有图片上传。

<form name="userInfo" method="post" action="first_submit.jsp" ENCTYPE="multipart/form-data">

表单标签中设置enctype=”multipart/form-data”来确保匿名上载文件的正确编码。
如下

<tr>
<td height="30" align="right">上传企业营业执照图片:</td>
<td><INPUT TYPE="FILE" NAME="uploadfile" SIZE="34"    onChange="checkimage()"></td>
</tr>

就得加ENCTYPE=”multipart/form-data”。

表单中enctype=”multipart/form-data”的意思,是设置表单的MIME编码。默认情况,
这个编码格式是application/x-www-form-urlencoded,不能用于文件上传;
只有使用了multipart/form-data,才能完整的传递文件数据,进行下面的操作。
enctype=”multipart/form-data”是上传二进制数据; form里面的input的值以2进制的方式传过去。
form里面的input的值以2进制的方式传过去,所以request就得不到值了。

也就是说加了这段代码,用request就会传递不成功,取表单值加入数据库时,用到下面的:

SmartUpload su = new SmartUpload();//新建一个SmartUpload对象
su.getRequest().getParameterValues();取数组值
su.getRequest().getParameter( );取单个参数单个值

后来又查才发现如果是指上传数据的内容的话,对于不同的文件,有很多种文件,会对应各种不同的类型。只是request默认的是application/x-www-form-urlencoded,所以用getParameterMap()能获得,用getInputStream()获得不了。

【还没解决的问题】

其实还有一个问题就是用项目里封装的httpClient传过来的数据,是能够用get流的方式接收到的,但是我没看懂httpClient的工作原理。。。还得接着学。

时间: 2024-10-20 11:44:53

【原】Http-用getInputStream()或者getParameterMap()获得Post请求的数据的相关文章

[原][osgearth]设置OE的高程,高度场的数据。修改设置高度值

for( unsigned int row=0; row < hf->getNumRows(); ++row ) { for( unsigned int col=0; col < hf->getNumColumns(); ++col ) { float val = hf->getHeight(col, row); if ( !isNoData( val ) ) { continue; } if ( col > 0 ) val = hf->getHeight(col

使用原app接口进行微信公众号开发

1.跨域问题 原来的app项目已经上线,然而接下来就有意思了,突然上头说要把app的发件功能复制到微信公众号里.那么问题来了,微信公众号的页面是前端和交互式h5大哥写的. 那么就将页面丢微信里,请求我原来app的接口不就好了? 然后问题是微信请求我原来的接口是能请求到数据啊,但是,浏览器出于安全根本就不会让你使用这些数据,这就产生了跨域的问题了. 解决办法一 我学长说让我在原接口中使用jsonp来支持跨域(额),这个就意味着每个接口还得改,改错了原来的app很有可能就崩了,想想都可怕 解决办法二

深入理解HTTP协议(转)原出处已不明

http协议学习系列---我从这里转来的http://www.blogjava.net/zjusuyong/articles/304788.html 1. 基础概念篇 1.1 介绍 HTTP是Hyper Text Transfer Protocol(超文本传输协议)的缩写.它的发展是万维网协会(World Wide Web Consortium)和Internet工作小组IETF(Internet Engineering Task Force)合作的结果,(他们)最终发布了一系列的RFC,RFC

C语言原码反码补码与位运算.

目录: 一.机器数和真值     二.原码,反码和补码的基础概念     三.为什么要使用原码,反码和补码     四.原码,补码,反码再深入     五.数据溢出测试     六.位运算的运算说明     七.位运算的简单应用   一.机器数和真值 机器数(computer number)是数字在计算机中的二进制表示形式 机器数有2个特点:一是符号数字化,二是其数的大小受机器字长的限制 比如:十进制中的+6,计算机字长为8位,转换成二进制就是00000110,如果是-6,就是10000110

[原]MySQL日志

0x01.About MySQL有四种类型的日志:Error Log.General Query Log.Binary Log 和 Slow Query Log. 第一种错误日志,记录MySQL运行过程ERROR,WARNING,NOTE等信息,系统出错或者某条记录出问题可以查看ERROR日志. 第二种日常运行日志,记录MySQL运行中的每条请求数据. 第三种二进制日志,包含了一些事件,这些事件描述了数据库的改动,如建表.数据改动等,也包括一些潜在改动,主要用于备份恢复.回滚等操作. 第四种慢查

getParameter() getInputStream()和getReader() 区别

我们经常用servlet和jsp, 经常用request.getParameter() 来得到数据. request.getParameter() request.getInputStream() request.getReader() 这三个方法都是从request对象中得到提交的数据,但是用途不同. 要根据<form>表单提交数据的编码方式选择不同的方法. HTML中的form表单的一个关键属性 enctype: 1. enctype=application/x- www-form-url

给 string 添加一个 GetInputStream 扩展方法

有时候,我们须要读取一些数据,而无论这数据来源于磁盘上的数据文件,还是来源于网络上的数据.于是.就有了以下的 StringExtensions.cs: 1 using System; 2 using System.IO; 3 using System.Net; 4 5 namespace Skyiv 6 { 7 public static class StringExtensions 8 { 9 public static Stream GetInputStream(this string fi

request getParameter(),getInputStream()

我们经常用servlet和jsp, 经常用request.getParameter() 来得到数据. request.getParameter()  request.getInputStream()  request.getReader() 这三个方法都是从request对象中得到提交的数据,但是用途不同. 要根据<form>表单提交数据的编码方式选择不同的方法. HTML中的form表单的一个关键属性 enctype: 1. enctype=application/x- www-form-u

【比原链】如何从比原节点拿到区块数据?

作者:freewind在前一篇中,我们已经知道如何连上一个比原节点的p2p端口,并与对方完成身份验证.此时,双方结点已经建立起来了信任,并且连接也不会断开,下一步,两者就可以继续交换数据了. 那么,我首先想到的就是,如何才能让对方把它已有的区块数据全都发给我呢? 这其实可以分为三个问题: 我需要发给它什么样的数据? 它在内部由是如何应答的呢? 我拿到数据之后,应该怎么处理? 由于这一块的逻辑还是比较复杂的,所以在本篇我们先回答第一个问题: 我们要发送什么样的数据请求,才能让比原节点把它持有的区块