java boundary_上传文件multipart form-data boundary 说明

含义 ENCTYPE="multipart/form-data" 说明:

通过 http 协议上传文件 rfc1867协议概述,客户端发送内容构造。

概述

在最初的 http 协议中,没有上传文件方面的功能。 rfc1867为 http 协议添加了这个功能。客户端的浏览器,如 Microsoft IE, Mozila, Opera 等,按照此规范将用户指定的文件发送到服务器。服务器端的网页程序,如 php, asp, jsp 等,可以按照此规范,解析出用户发送来的文件。Microsoft IE, Mozila, Opera 已经支持此协议,在网页中使用一个特殊的 form 就可以发送文件。绝大部分 http server ,包括 tomcat ,已经支持此协议,可接受发送来的文件。各种网页程序,如 php, asp, jsp 中,对于上传文件已经做了很好的封装。

实例

注意 enctype="multipart/form-data", method=post, type="file" 。根据 rfc1867, 这三个属性是必须的。multipart/form-data 是新增的编码类型,以提高二进制文件的传输效率。

数据传输

3451720

格式 必须一字不差,包括最后的回车。

注意:Content-Length: 226 这里的226是红色内容的总长度(包括最后的回车)

注意这一行:

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

根据 rfc1867, multipart/form-data是必须的.---------------------------7d33a816d302b6 是分隔符,分隔多个文件、表单项。

其中7d33a816d302b6 是即时生成的字符串,用以确保整个分隔符不会在文件或表单项的内容中出现。

使用POST发送数据

以POST方式发送数据主要是为了向服务器发送较大量的客户端的数据,它不受URL的长度限制。POST请求将数据以URL编码的形式放在HTTP正文中,字段形式为fieldname=value,用&分隔每个字段。注意所有的字段都被作为字符串处理。实际上我们要做的就是模拟浏览器POST 一个表单。以下是IE发送一个登陆表单的POST请求:

935e2fea26aa045249261dbd9f401cf4.gif

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

fc83d59df1530f8708e6596245f62868.gif

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

// 使用POST方法

httpURLConnection.setRequestMethod("POST");

然后构造出HTTP正文:

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

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

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

httpURLConnection.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一致,这里就不再详述。

使用multipart/form-data发送文件

如果要在MIDP客户端向服务器上传文件,我们就必须模拟一个POST multipart/form-data类型的请求,Content-Type必须是multipart/form-data。

以multipart/form-data编码的POST请求格式与application/x-www-form-urlencoded完全不同,multipart/form-data需要首先在HTTP请求头设置一个分隔符,例如ABCD:

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

然后,将每个字段用“--分隔符”分隔,最后一个“--分隔符--”表示结束。例如,要上传一个title字段"Today"和一个文件C:\1.txt,HTTP正文如下:

5af0258781e9dabc63949ce13ba784a9.gif

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

--ABCD--

\r\n

9556bdbd44d32365cc872fdb314f0e11.gif

请注意,每一行都必须以\r\n结束,包括最后一行。如果用Sniffer程序检测IE发送的POST请求,可以发现IE的分隔符类似于 ---------------------------7d4a6d158c9,这是IE产生的一个随机数,目的是防止上传文件中出现分隔符导致服务器无法正确识别文件起始位置。我们可以写一个固定的分隔符,只要足够复杂即可。

发送文件的POST代码如下:

f3127c9afca185c7966e6c37b5dc447f.gif

String[] props = ... // 字段名

String[] values = ... // 字段值

byte[] file = ... // 文件内容

String BOUNDARY = "---------------------------7d4a6d158c9"; // 分隔符

StringBuffer sb = new StringBuffer();

// 发送每个字段:

for(int i=0; i

sb = sb.append("--");

sb = sb.append(BOUNDARY);

sb = sb.append("\r\n");

sb = sb.append("Content-Disposition: form-data; name=\""+ props[i] + "\"\r\n\r\n");

sb = sb.append(URLEncoder.encode(values[i]));

sb = sb.append("\r\n");

}

// 发送文件:

sb = sb.append("--");

sb = sb.append(BOUNDARY);

sb = sb.append("\r\n");

sb = sb.append("Content-Disposition: form-data; name=\"1\"; filename=\"1.txt\"\r\n");

sb = sb.append("Content-Type: application/octet-stream\r\n\r\n");

byte[] data = sb.toString().getBytes();

byte[] end_data = ("\r\n--" + BOUNDARY + "--\r\n").getBytes();

// 设置HTTP头:

hc.setRequestProperty("Content-Type", MULTIPART_FORM_DATA + "; boundary=" + BOUNDARY);

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

// 输出:

output = hc.openOutputStream();

output.write(data);

output.write(file);

output.write(end_data);

// 读取服务器响应:

// TODO...

53c8e6540017afcaaf6fa34cd54e6e64.gif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中实现文件的常用方式是使用HTTP协议的`multipart/form-data`格式,具体实现步骤如下: 1. 创建一个`HttpURLConnection`连接对象,设置请求方法为POST,并设置连接超时时间和读取超时时间。 2. 设置请求头信息,包括`Content-Type`、`User-Agent`、`Accept-Language`等,其中`Content-Type`设置为`multipart/form-data`。 3. 创建输出流,并将需要上文件写入到输出流中。在写入文件之前需要设置一个分隔符,用于分隔不同字段的内容。 4. 在输出流的末尾写入分隔符,表示文件结束。 5. 发送HTTP请求,并读取服务器返回的响应结果。 下面是一个Java实现文件的示例代码: ```java public static void uploadFile(String url, File file) throws IOException { String boundary = "---------------------------" + System.currentTimeMillis(); //设置分隔符 HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection(); //创建连接对象 conn.setRequestMethod("POST"); //设置请求方法为POST conn.setConnectTimeout(5000); //设置连接超时时间 conn.setReadTimeout(30000); //设置读取超时时间 conn.setDoOutput(true); //允许输出 conn.setDoInput(true); //允许输入 conn.setUseCaches(false); //不使用缓存 conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary); //设置请求头信息 conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3"); conn.setRequestProperty("Accept-Language", "zh-CN,zh;q=0.8"); OutputStream out = new DataOutputStream(conn.getOutputStream()); //创建输出流 FileInputStream fileInputStream = new FileInputStream(file); //创建文件输入流 byte[] buffer = new byte[1024]; int len = 0; out.write(("--" + boundary + "\r\n").getBytes()); //写入分隔符 out.write(("Content-Disposition: form-data; name=\"file\"; filename=\"" + file.getName() + "\"\r\n").getBytes()); out.write(("Content-Type: application/octet-stream\r\n\r\n").getBytes()); while ((len = fileInputStream.read(buffer)) != -1) { out.write(buffer, 0, len); //写入文件数据 } out.write(("\r\n--" + boundary + "--\r\n").getBytes()); //写入分隔符 out.flush(); //清空缓存 fileInputStream.close(); //关闭文件输入流 out.close(); //关闭输出流 int responseCode = conn.getResponseCode(); //获取响应码 if (responseCode == 200) { InputStream inputStream = conn.getInputStream(); //获取响应输入流 BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); //创建读取响应结果的缓冲流 String line; while ((line = bufferedReader.readLine()) != null) { System.out.println(line); //输出响应结果 } bufferedReader.close(); //关闭缓冲流 inputStream.close(); //关闭输入流 } else { System.out.println("文件失败,响应码为:" + responseCode); } } ``` 其中,`url`为上文件的URL,`file`为需要上文件。在实际使用时,需要根据实际情况更改请求头信息、分隔符和文件字段名等参数。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值