application/x-www-form-urlencoded和multipart/form-data


1.使用POST发送数据   

 以POST方式发送数据主要是为了向服务器发送较大量的客户端的数据,它不受URL的长度限制。POST请求将

数据以URL编码的形式放在HTTP正文中,字段形式为fieldname=value,用&分隔每个字段。注意所有的字段都

被作为字符串处理。实际上我们要做的就是模拟浏览器POST 一个表单。以下是IE发送一个登陆表单的POST请

求:

POST http://127.0.0.1/login.do HTTP/1.0


Accept: image/gif, image/jpeg, image/pjpeg, */*


Accept-Language: en-us,zh-cn;q=0.5


Content-Type: application/x-www-form-urlencoded


User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)


Content-Length: 28

username=admin&password=1234

要在MIDP应用程序中模拟浏览器发送这个POST请求,首先设置HttpConnection的请求方式为POST:

hc.setRequestMethod(HttpConnection.POST);

然后构造出HTTP正文:

byte[] data = "username=admin&password=1234".getBytes();

并计算正文长度,填入Content-Type和Content-Length:

hc.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");


hc.setRequestProperty("Content-Length", String.valueOf(data.length));

然后打开OutputStream将正文写入:

OutputStream output = hc.openOutputStream();


output.write(data);

需要注意的是,数据仍需要以URL编码格式编码,由于MIDP库中没有J2SE中与之对应的URLEncoder类,因此,

需要自己动手编写这个 encode()方法,可以参考java.net.URLEncoder.java的源码。剩下的便是读取服务器响

应,代码与GET一致,这里就不再详述。

2.使用multipart/form-data发送文件

最早的HTTP POST是不支持文件上传的,给编程开发带来很多问题。但是在1995年,ietf出台了rfc1867,也就是《RFC 1867 -Form-based File Upload in HTML》,用以支持文件上传。所以Content-Type的类型扩充了multipart/form-data用以支持向服务器发送二进制数据。因此发送post请求时候,表单<form>属性enctype共有二个值可选,这个属性管理的是表单的MIME编码:

 ①application/x-www-form-urlencoded(默认值)
 ②multipart/form-data
其实form表单在你不写enctype属性时,也默认为其添加了enctype属性值,默认值是enctype="application/x- www-form-urlencoded".



以multipart/form-data编码的POST请求格式与application/x-www-form-urlencoded完全不同,multipart/form-

data需要首先在HTTP请求头设置一个分隔符,例如ABCD:


hc.setRequestProperty("Content-Type", "multipart/form-data; boundary=ABCD");


然后,将每个字段用“--分隔符”分隔,最后一个“--分隔符--”表示结束。例如,要上传一个title字段"Today"和一

个文件C:\1.txt,HTTP正文如下:

--ABCD

Content-Disposition: form-data; name="title"

\r\n

Today

--ABCD

Content-Disposition: form-data; name="1.txt"; filename="C:\1.txt"

Content-Type: text/plain

\r\n

<这里是1.txt文件的内容>

--ABCD--

\r\n


浏览器将会发送以下数据:

POST /t2/upload.do HTTP/1.1

User-Agent: SOHUWapRebot

Accept-Language: zh-cn,zh;q=0.5

Accept-Charset: GBK,utf-8;q=0.7,*;q=0.7

Connection: keep-alive

Content-Length: 60408

Content-Type:multipart/form-data; boundary=ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC

Host: w.sohu.com

 

--ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC

Content-Disposition: form-data;name="desc"

Content-Type: text/plain; charset=UTF-8

Content-Transfer-Encoding: 8bit

 

[......][......][......][......]...........................

--ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC

Content-Disposition: form-data;name="pic"; filename="photo.jpg"

Content-Type: application/octet-stream

Content-Transfer-Encoding: binary


选择了这个边界之后,浏览器便把它放在Content-Type 里面传递给服务器,服务器根据此边界解析数据。下面的数据便根据boundary划分段,每一段便是一项数据。(每个field被分成小部分,而且包含一个value是"form-data"的"Content-Disposition"的头部;一个"name"属性对应field的ID,等等,文件的话包括一个filename)

  • IE和Chrome在filename的选择策略上有所不同,前者是文件的完整路径,而后者则仅仅是文件名。
  • 数据内容以两条横线结尾,并同样以一个换行结束。在网络协议中一般都以连续的CR、LF(即\r、\n,或0x0D、Ox0A)字符作为换行,这与Windows的标准一致。如果您使用其他操作系统,则需要考虑它们的换行符

 另外Content-length 指的是所用数据的长度。


httpClient4使用http-mime.jar包的MultipartEntity实现,代码如下(为了简洁,处理了异常处理代码):
                           
HttpPost httpPost = newHttpPost(url);
Log.debug("post url:"+url);
httpPost.setHeader("User-Agent","SOHUWapRebot");
httpPost.setHeader("Accept-Language","zh-cn,zh;q=0.5");
httpPost.setHeader("Accept-Charset","GBK,utf-8;q=0.7,*;q=0.7");
httpPost.setHeader("Connection","keep-alive");
 
MultipartEntity mutiEntity = newMultipartEntity();
File file = new File("d:/photo.jpg");
mutiEntity.addPart("desc",new StringBody("美丽的西双版纳", Charset.forName("utf-8")));
mutiEntity.addPart("pic", newFileBody(file));
 
 
httpPost.setEntity(mutiEntity);
HttpResponse  httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity =  httpResponse.getEntity();
String content = EntityUtils.toString(httpEntity);


/**
	 * 向服务器上传文件
	 * 
	 * @param urls
	 * @param path
	 * @param fileKey
	 *            文件键值
	 * @param fileType
	 *            文件类型
	 * @param file
	 *            提供的文件
	 * @param param
	 * @return
	 * @throws Exception
	 */
	public static String uploadFile(String urls, String path, String fileKey, String fileType, File file,
			Map<String, Object> param) throws Exception {
		String result = "";
		if (urls == null || "".equals(urls) || path == null || "".equals(path)) {
			return result;
		}
		String boundary = "---------------------------7db1c523809b2";
		String end = "\r\n";
		String twoHyphens = "--";
		String newName = path.substring(path.lastIndexOf("/") + 1, path.length());

		Logger.e("请求url:" + urls);
		Logger.e("上传的文件名:" + newName);
		URL url = new URL(urls);

		HttpURLConnection http = (HttpURLConnection) url.openConnection();
		http.setDoInput(true);
		http.setDoOutput(true);
		http.setUseCaches(false);
		http.setRequestMethod(HTTP_POST);
		http.setConnectTimeout(10 * 1000);
		http.setRequestProperty("Charset", "UTF-8");
		http.setRequestProperty("connection", "keep-alive");
		http.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);

		// 构建参数
		DataOutputStream data = new DataOutputStream(http.getOutputStream());
		if (param != null && param.size() > 0) {
			Set<String> set = param.keySet();
			for (String string : set) {
				data.writeBytes(twoHyphens + boundary + end + "Content-Disposition: form-data; name=\"" + string + "\""
						+ end + end + param.get(string) + end);
			}
		}
		// 构建文件
		data.writeBytes(twoHyphens + boundary + end);
		data.writeBytes(
				"Content-Disposition: form-data; " + "name=\"" + fileKey + "\";filename=\"" + newName + "\"" + end);
		data.writeBytes("Content-Type: " + fileType + end);
		data.writeBytes(end);

		/* 取得文件的FileInputStream */
		if (file == null) {
			file = new File(path);
		}
		FileInputStream fStream = new FileInputStream(file);
		/* 设置每次写入1024bytes */
		int bufferSize = 1024;
		byte[] buffer = new byte[bufferSize];

		int length = -1;
		int count = 0;
		/* 从文件读取数据至缓冲区 */
		while ((length = fStream.read(buffer)) != -1) {
			/* 将资料写入DataOutputStream中 */
			data.write(buffer, 0, length);
			count = count + length;
			if (updataNum != null) {
				updataNum.updataNum(count);
			}
			// Logger.e("上传大小:" + count);
		}
		data.writeBytes(end);
		data.writeBytes(twoHyphens + boundary + twoHyphens + end);

		/* close streams */
		fStream.close();
		data.flush();

		/* 取得Response内容 */
		InputStream is = http.getInputStream();
		int ch;
		StringBuffer buff = new StringBuffer();
		while ((ch = is.read()) != -1) {
			buff.append((char) ch);
		}
		/* 关闭DataOutputStream */
		data.close();
		result = buff.toString();

		return result;
	}




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值