当前位置:编程学习 > 网站相关 >>

构造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请求有些繁琐,分隔符间空格很重要,如过看不明白可以用抓包工具传两个小文件 然后看看浏览器构造的请求体是什么格式,然后我们用字符串片接方式构造相同的结构,发送给服务器。

补充:综合编程 , 其他综合 ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,