构造HTTP消息体采用HttpConnection实现文件上传
自己构造http消息体,用HttpConnection实现文件上传, 后台用的是Sinatra框架搞定服务端,很简洁,几行代码,比起servlet快捷不少
package com.hoot.regx;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
public class Regx {
private static final String BOUNDARY = "-----------------7d4a6d158c9";
private static final String TWO_HYPHENS = "--";
private static final String END = "\r\n";
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
URL url = new URL("http://localhost:4567/upload");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Charset", "UTF-8");
conn.setRequestProperty("Content-Type",
"multipart/form-data;boundary=" + BOUNDARY);
StringBuffer sb = new StringBuffer();
//分解符
sb.append(TWO_HYPHENS + BOUNDARY + END);
//设置与上次文件相关信息
sb.append("Content-Disposition: form-data; name=\"myfile\"; filename=\"test.txt\""
+ END);
//上传文件信息和文件的内容间必须有一个空行
sb.append(END);
// Map<String, List<String>> props = conn.getRequestProperties();
// for(Entry<String, List<String>> prop : props.entrySet()){
// System.out.println(prop.getKey() + ":" );
// for(String str : prop.getValue()){
// System.out.print(str);
// }
// System.out.println();
// }
System.out.println(sb.toString());
byte[] data = sb.toString().getBytes();
OutputStream os = conn.getOutputStream();
os.write(data);
//一下是文件数据
FileInputStream fis = new FileInputStream(new File("test.txt"));
byte[] buf = new byte[1024];
int len = 0;
while ((len = fis.read(buf)) > 0) {
os.write(buf, 0, len);
}
String endStr = END + TWO_HYPHENS + BOUNDARY + TWO_HYPHENS + END;
byte[] end_data = endStr.getBytes();
System.out.println("<this is file content>");
System.out.println(endStr);
os.write(end_data);
os.flush();
os.close();
fis.close();
InputStream is = conn.getInputStream();
while ((len = is.read(buf)) > 0) {
System.out.write(buf, 0, len);
}
is.close();
}
}
服务器端:
需要安装几个gem
sinatra haml
require 'rubygems'
require 'sinatra'
require 'haml'
get '/' do
'Hello world'
end
# Handle GET-request (Show the upload form)
get "/upload" do
haml :upload
end
# Handle POST-request (Receive and save the uploaded file)
post "/upload" do
logger.info "#{params}"
unless params[:myfile] &&
(tmpfile = params[:myfile][:tempfile]) &&
(name = params[:myfile][:filename])
@error = "No file selected"
logger.info "params #{@error} file: #{tmpfile} name: #{name} #{params}"
return haml(:error)
end
directory = 'uploads'
path = File.join(directory, name)
File.open(path, "wb") do |f|
f.write(tmpfile.read)
end
#File.copy(tempfile.path, path)
@msg = "#{name}The file was successfully uploaded!"
end够简洁吧,下面我吧两个haml文件也贴一下(haml文件放在在同级目录的views目录下)
upload.haml
%html
%body
%h1 File uploader!
%form(method="post" enctype='multipart/form-data')
%input(type='file' name='myfile')
%br
%input(type='submit' value='Upload!')error.haml
%html
%body
%h1 File uploader error!
总结:自己构造Post请求有些繁琐,分隔符间空格很重要,如过看不明白可以用抓包工具传两个小文件 然后看看浏览器构造的请求体是什么格式,然后我们用字符串片接方式构造相同的结构,发送给服务器。
补充:综合编程 , 其他综合 ,