http上传文件c
A. Java利用HttpURLConnection发送post请求上传文件
在页面里实现上传文件不是什么难事 写个form 加上enctype = multipart/form data 在写个接收的就可以了 没租裤什么难的 如果要用 HttpURLConnection来实现文件上传 还真有点搞头 : )
先写个servlet把接收到的 HTTP 信息保存在一个文件中 看一下 form 表单到底封装了什么样的信息
Java代码
public void doPost(HttpServletRequest request HttpServletResponse response)
throws ServletException IOException {
//获取输入流 是HTTP协议中的实体内容
ServletInputStream in=request getInputStream();
//缓冲区
byte buffer[]=new byte[ ];
FileOutputStream out=new FileOutputStream( d:\test log );
int len=sis read(buffer );
//把流里的信息循环读入到file log文件中
while( len!= ){
out write(buffer len);
len=in readLine(buffer );
}
out close();
in close();
}
来一个form表单
<form name= upform action= upload do method= POST
enctype= multipart/form data >
参数<input type= text name= username /><br/>
文件 <input type= file name= file /><br/>
文件 <input type= file name= file /><br/>
<input type= submit value= Submit />
<br />
</form>
假如我参数写的内容是hello word 然后二个文件是二个简单的txt文件梁誉 上传后test log里如下
Java代码
da e c
Content Disposition: form data; name= username
hello word
da e c
Content Disposition: form data; name= file ; filename= D:haha txt
Content Type: text/plain
haha
hahaha
da e c
Content Disposition: form data; name= file ; filename= D:huhu txt
Content Type: text/plain
messi
huhu
da e c
研究下规律发现有如下几点特征
第一行是 d b bc 作为分隔符 然后是 回车换行符 这个 d b bc 分隔符浏览器是随机生成的
第二行是Content Disposition: form data; name= file ; filename= D:huhu txt ;name=对应input的name值 filename对应要上传的文件名(包括路径在内)
第三行如果是文件就有Content Type: text/plain 这里上传的是txt文件所以是text/plain 如果上穿的是jpg图片的话就是image/jpg了 可以自己试试看看
然后就是回弊渣简车换行符
在下就是文件或参数的内容或值了 如 hello word
最后一行是 da e c 注意最后多了二个 ;
有了这些就可以使用HttpURLConnection来实现上传文件功能了
Java代码 public void upload(){
List<String> list = new ArrayList<String>(); //要上传的文件名 如 d:haha doc 你要实现自己的业务 我这里就是一个空list
try {
String BOUNDARY = d a d c ; // 定义数据分隔线
URL url = new URL( );
HttpURLConnection conn = (HttpURLConnection) url openConnection();
// 发送POST请求必须设置如下两行
conn setDoOutput(true);
conn setDoInput(true);
conn setUseCaches(false);
conn setRequestMethod( POST );
conn setRequestProperty( connection Keep Alive );
conn setRequestProperty( user agent Mozilla/ (patible; MSIE ; Windows NT ; SV ) );
conn setRequestProperty( Charsert UTF );
conn setRequestProperty( Content Type multipart/form data; boundary= + BOUNDARY);
OutputStream out = new DataOutputStream(conn getOutputStream());
byte[] end_data = ( + BOUNDARY + ) getBytes();// 定义最后数据分隔线
int leng = list size();
for(int i= ;i<leng;i++){
String fname = list get(i);
File file = new File(fname);
StringBuilder *** = new StringBuilder();
*** append( );
*** append(BOUNDARY);
*** append( );
*** append( Content Disposition: form data;name= file +i+ ;filename= + file getName() + );
*** append( Content Type:application/octet stream );
byte[] data = *** toString() getBytes();
out write(data);
DataInputStream in = new DataInputStream(new FileInputStream(file));
int bytes = ;
byte[] bufferOut = new byte[ ];
while ((bytes = in read(bufferOut)) != ) {
out write(bufferOut bytes);
}
out write( getBytes()); //多个文件时 二个文件之间加入这个
in close();
}
out write(end_data);
out flush();
out close();
// 定义BufferedReader输入流来读取URL的响应
BufferedReader reader = new BufferedReader(new InputStreamReader(conn getInputStream()));
String line = null;
while ((line = reader readLine()) != null) {
System out println(line);
}
} catch (Exception e) {
System out println( 发送POST请求出现异常! + e);
e printStackTrace();
}
lishixin/Article/program/Java/hx/201311/27114
B. HTTP 的 POST 参数提交和上传的不同与 Mojolicious 的实现
对于 HTTP 协议, 我们在使用 POST 上传的时候, 其实是有好几种不同的处理方式的, 所以对于客户端和服务器端, 也分别都有不同的处理. 正常普通的网页在提交参数上传到服务器的时候, 主要会根据内容的不同来使用不同的处理. 所体现在不同的地方在 Content-Type 的类型.
比如我们常常用 Mojolicious 处理这类接收到的参数和内容的时候, 会让很多人晕掉, 所以我在这, 基于协议的头, 来给大家介绍一下在参数和上传的时候有什么不同.
客户端, 比如浏览器网页中的 form 的表格的参数的不同, 客户端比如 Linux 命令行的 curl 的参数的不同和程序接口提交参数的不同, HTTP 协议在上传的时候, 大约会有三种不同, 这些体现在 Content-Type 的三种类型:
application/x-www-form-urlencoded
multipart/form-data
post 的 body 的内容
下面我们来详细介绍
1. application/x-www-form-urlencoded 默认
浏览器: 在 HTML 中 form 有个参数是 enctype 属性用于指定编码方式, 常用有前面讲的两种: application/x-www-form-urlencoded 和 multipart/form-data. 但默认的时候, 我们并不指定. 不指定的时候, 默认是 "application/x-www-form-urlencoded" , 所以其实, 我们平时都是使用的这种格式来提交数据. 因为是默认就不写出来了. 注意, 这个会对空格和特别的符号进行 url 的 encode.
程序: 我们现在以 Mojo::UserAgent 这个模块为例子, 我们提交一个参数 args 值为 test.
$ua->post('ht tp:/ /w ww.php-oa.co m/a/b' => form => { args => 'test'});
命令:
$curl -svo /dev/null -d "args=test" htt p:/ /w ww.php-oa.co m/a/b
HTTP 协议状态
这个时候所发送的 HTTP 的头和内容分别如下. body 中会存着参数, 会有一个特别的 Header.
-- Blocking request (ht tp:/ /w ww.php-oa.co m/a/b)
-- Connect (ht tp:ww w.php-oa.c om:80)
-- Client >>> Server (htt p://w ww.php-oa.c om/a/b)
POST /a/b HTTP/1.1
User-Agent: Mojolicious (Perl)
Connection: keep-alive
Content-Type: application/x-ww w-form-urlencoded
Accept-Encoding: gzip
Content-Length: 9
Host: www.php-oa.com
args=test
服务端接收方式
这个时候, 服务器会根据因为是 POST 的方法, 并且头部的 Content-Type: application/x-www-form-urlencoded 会去解析 body 的参数. 这样在 Mojolicious 服务器
post '/a/b' => sub {
my $self = shift;
my $foo = $self->param('args');
$self->render(text => "Hello from $foo.");
}
2. multipart/form-data 大文件, 媒体文件
对于比较大的, 有一些二进制数据和象视频文件之类大文件, 建议使用这种方式上传.
浏览器:
普通的 HTTP 的写法如果要使用 enctype 的话, 只要象下面一样就行.
<form action="/path/to/login" enctype="multipart/form-data">
<input disabled="disabled" name="first_name" type="text" />
<input value="Ok" type="submit" />
</form>
客户端:
在 Mojo::UserAgent 考虑得非常周全, 当你提交的内容中包含二进制文件之类时, 就会自动帮你转换成 "multipart/form-data" 格式提交. 这个格式会生成一个随机字符来分割不同参数. 区分是否使用这种格式主要是, 当你提交的参数中, 又是一个引用, 并且引中可以使用 content 来指定内容或者 file 来指定路径.
$ua->post('htt p:/ /w ww.php-oa.c om/a/b' => form => { args => 'test', args_file => { file => '/root/.bash_history' } });
# or
$ua->post('ht tp://w ww.php-oa.c om/a/b' => form => { args => 'test', args_file => { content => 'test' } });
HTTP 协议状态
这个地方我们可以见到 Content-Type: multipart/form-data 的请求头, 告诉文件和参数是这种格式上传过来的.并且 boundary 用于指定一个参数之间的分割符.
-- Blocking request (ht tp://w ww.php-oa.c om/a/b)
-- Connect (ht tp:w ww.php-oa.co m:80)
-- Client >>> Server (ht p://ww w.php-oa.co m/a/b)
POST /a/b HTTP/1.1
User-Agent: Mojolicious (Perl)
Content-Type: multipart/form-data; boundary=WRoHX
Connection: keep-alive
Accept-Encoding: gzip
Content-Length: 14428
Host: www.php-oa.com
--WRoHX
Content-Disposition: form-data; name="args"
test
--WRoHX
Content-Disposition: form-data; name="args_file"; filename=".bash_history"
........文件本身
服务器接收方式
在后端的服务器接收的时候 Mojolicious 想得非常周到. 对于这种格式能自动解析, 并且全程异步.不会多占内存. 这个会自动给大的文件使用一个叫 Mojo::Upload 的对象来处理, 我们可以通过 $self->req->upload('args_file'); 这个方法取得这个内容的对象, 这个内容的对象是Mojo::Asset::File 这个对象, 存文件和取大文件之类可以直接调用.
post '/a/b' => sub {
my $self = shift;
my $upload = $self->req->upload('args_file');
my $foo = $self->param('args');
$self->render(text => "Hello from $foo.");
}
3. POST 的 body 的内容
最后一种, 是有时我们做大文件上传, 和提交内容之类.这个时候, 整个 body 都是文件本体. 参数象 get 一样通过 url 传过去.
这个就不用抓头了, 没任何转换, 直接整个 body 是个大文件.
客户端提交:
我们来看看客户端在这个时候怎么上传送. 同样, 我们使用 Mojo::UserAgent 为例子.
my $ua = Mojo::UserAgent->new;
$ua->transactor->add_generator(stream => sub {
my ($transactor, $tx, $path) = @_;
$tx->req->content->asset(Mojo::Asset::File->new(path => $path));
});
$ua->post('ht tp://w ww.php-oa.co m/a/b' => stream => '/root/.bash_history' );
服务器接收
这个时候, 在服务器端怎么接收啦?
post '/a/b' => sub {
my $self = shift;
my $body = $self->req->body;
my $foo = $self->param('args');
$self->render(text => "Hello from $foo.");
}
这个, 我们直接取请求的 body 就可以了, 但这有个小问题, 这是这个文件上传完, 这个 body 会存着所有的文件, 比如这个上传的文件有 1G , 这个 1G 就都会占着内存. 这个情况, Mojolicious 并没有实现事件来根据块取文件. 晚点, 我有个有于大文件上传的文章, 会分享我在 Mojolicious 中实现异步以块方式存储文件. 这样用户上传多少, 我存多少, 并不会占用更多的内存.
好了整个三种方式都介绍完了, 大家一定注意区分哦 .
C. http中上传文件的原理
http中上传文件的原理如下:
在最初的http协议中,没有上传文件方面的功能。 rfc1867 ( http://www.ietf.org/rfc/rfc1867.txt ) 为 http 协议添加了这个功能。客户端的浏览器,如 Microsoft IE, Mozila, Opera 等,按照此规范将用户指定的文件发送到服务器。服务器端的网页程序,如 php, asp, jsp 等,可以按照此规范,解析出用户发送来的文件。Microsoft IE, Mozila, Opera 已经支持此协议,在网页中使用一个特殊的 form 就可以发送文件。绝大部分 http server ,包括 tomcat ,已经支持此协议,可接受发送来的文件。各种网页程序,如 php, asp, jsp 中,对于上传文件已经做了很好的封装。
超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议。所有的WWW文件都必须遵守这个标准。设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。1960年美国人Ted Nelson构思了一种通过计算机处理文本信息的方法,并称之为超文本(hypertext),这成为了HTTP超文本传输协议标准架构的发展根基。
D. 怎么用http上传一个文件到服务器 python
首先,标准HTTP协议对上传文件等表单的定义在这里:wwwietforg/rfc/rfc1867txt 大概数据包格式如下:
单文件:
Content-type: multipart/form-data, boundary=AaB03x
--AaB03x
content-disposition: form-data; name="field1"
Joe Blow
--AaB03x
content-disposition: form-data; name="pics"; filename="file1.txt"
Content-Type: text/plain
... contents of file1.txt ...
--AaB03x--
多文件:
Content-type: multipart/form-data, boundary=AaB03x
--AaB03x
content-disposition: form-data; name="field1"
Joe Blow
--AaB03x
content-disposition: form-data; name="pics"
Content-type: multipart/mixed, boundary=BbC04y
--BbC04y
Content-disposition: attachment; filename="file1.txt"
其次,python上传文件的几种方法:
1 自己封装HTTP的POST数据包:http//stackoverflowcom/questions/680305/using-multipartposthandler-to-post-form-data-with-python
import httplibimport mimetypesdef post_multipart(host, selector, fields, files): content_type, body = encode_multipart_formdata(fields, files) h = httplib.HTTP(host) h.putrequest('POST', selector) h.putheader('content-type', content_type) h.putheader('content-length', str(len(body))) h.endheaders() h.send(body) errcode, errmsg, headers = h.getreply() return h.file.read() def encode_multipart_formdata(fields, files): LIMIT = '----------lImIt_of_THE_fIle_eW_$' CRLF = '\r\n' L = [] for (key, value) in fields: L.append('--' + LIMIT) L.append('Content-Disposition: form-data; name="%s"' % key) L.append('') L.append(value) for (key, filename, value) in files:
E. http文件上传的原理是什么请问向qq邮箱这类可以上传文件的网页,他们上传文件的原理是不是,当用
有个误区:
在上传插件中,用户点击提交(确认)后,文件才开始上传,这时候,会上传到服务器的某个目录(不是临时目录,一般是服务器按照管理用户文件的规则所建立的文件夹),服务器会返回一个指针,这个指针指向了你上传的文件。当你发送邮件后,邮件中也会包含这个指针。不管你把这个文件放到哪个文件夹,实际上都只是存放的这个指针而已。如非管理需要,这个文件应该会永久保存,任何转发,转储的行为,其实也只是操作的这个指针而不是文件本身。
即使你删除文件,也只是在你的文件夹中删除这个指针。所以,很多“极速秒传”实际上是先判断你要上传的文件的MD5值是否已经在服务器中存在,如果存在,就把已存在的文件的指针放上去,是不是很快?
F. 用浏览器上传文件显示http请求错误是怎么回事
上传文件显示http请求错误的原因:
1、网络问题,可能当前的网络不好,可以尝试重新上传;或者检查一下路由器。
2、浏览器的问题,可以尝试换个浏览器。
3、防火墙,有可能被设置到了吧。
4、网页问题,可能停留时间太长导致和后端的服务改帆滚器断开连接,刷新一下。
5、文档的格式问题。
此错误表明传输给服务器的证书与登录服务器所需的证书不匹配。
请与 Web 服务器的管理员联系,以确认您是否具有访问所请求资源核余的权限。 401.2 未授权:服务器的配置导致登录失败。
此错误表明传输给服务器的证书与登录服务器所需的证书不匹配。此错误通常由未发送正确的 WWW 验证表头字段所致。
请与 Web 服务轿羡器的管理员联系,以确认您是否具有访问所请求资源的权限。 401.3 未授权:由于资源中的 ACL 而未授权。
此错误表明客户所传输的证书没有对服务器中特定资源的访问权限。此资源可能是客户机中的地址行所列出的网页或文件,也可能是处理客户机中的地址行所列出的文件所需服务器上的其他文件。
请记录试图访问的完整地址,并与 Web 服务器的管理员联系以确认您是否具有访问所请求资源的权限。
错误解释:
此错误表明 Web 服务器已经安装了筛选程序,用以验证连接到服务器的用户。此筛选程序拒绝连接到此服务器的真品证书的访问。 请记录试图访问的完整地址,并与 Web 服务器的管理员联系以确认您是否具有访问所请求资源。