文件上传和下载

简单说下原理:
看看当网页上传文件时,到底发送了什么,文件是如何在报文中表示的

这是一个上传文件的网页
这里写图片描述

这是提交之后的报文
这里写图片描述

最重要的是下面这个

这里写图片描述

我们只要按着这个格式发送文件就行了
比如说要发送两个文件就这样写
------WebKitFormBoundaryUS75AnTOrrFe3vU2
Content-Disposition: form-data; name="userfile1"; filename="lantern.exe"
Content-Type: application/x-msdownload


------WebKitFormBoundaryUS75AnTOrrFe3vU2
Content-Disposition: form-data; name="userfile2"; filename="BaiduYunGuanjia.exe"
Content-Type: application/x-msdownload

------WebKitFormBoundaryUS75AnTOrrFe3vU2--

下面有代码

更新下HttpClient上传文件的代码,jar包去官网下载,原理还和之前的一样

package servlet;

import java.util.ArrayList;
import java.util.List;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;

import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.CharsetUtils;
import org.apache.http.util.EntityUtils;

public class HttpClientUploadFile {

    @SuppressWarnings("deprecation")
    public static void uploadFile(String url, List<String> uploadFiles) {

        HttpClient httpClient = new DefaultHttpClient();// 开启一个客户端 HTTP 请求
        HttpPost httpPost = new HttpPost(url);// 创建 HTTP POST 请求

        MultipartEntityBuilder builder = MultipartEntityBuilder.create();

        builder.setCharset(Charset.forName("utf-8"));//设置请求的编码格式
        builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);// 设置浏览器兼容模式
        builder.addTextBody("method", "POST");// 设置请求参数
        builder.addTextBody("connection", "Keep-Alive");;// 设置请求参数

        for (String uploadFile : uploadFiles) {
            File file = new File(uploadFile);
            if (file.exists()) {
                //获得文件名
                String fileName = uploadFile.substring(uploadFile.lastIndexOf(File.separator)+1);
                builder.addBinaryBody(fileName, file);
            }
        }
        HttpEntity entity = builder.build();// 生成 HTTP POST 实体
        httpPost.setEntity(entity);// 设置请求参数
        try {
            HttpResponse response = httpClient.execute(httpPost);

            System.out.println("发起请求的页面地址 " + httpPost.getRequestLine());
            // 发起请求 并返回请求的响应

            if (response != null) {
                System.out.println("----------------------------------------");
                // 打印响应状态
                System.out.println(response.getStatusLine());
                // 获取响应对象
                HttpEntity resEntity = response.getEntity();
                if (resEntity != null) {
                    // 打印响应长度
                    System.out.println("Response content length: "
                            + resEntity.getContentLength());
                    // 打印响应内容
                    System.out.println(EntityUtils.toString(resEntity,
                            Charset.forName("UTF-8")));
                    // 销毁
                    EntityUtils.consume(resEntity);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
              // 关闭连接,释放资源
              httpClient.getConnectionManager().shutdown();
        }
    }

    public static void main(String[] args) {
        // 建立上传文件链表
        List<String> uploadFiles = new ArrayList<String>();
        uploadFiles.add("D://apache-tomcat-7.0.70-windows-x64.zip");
        uploadFiles.add("D://mysql-installer-community-5.6.26.0.msi");
        // 上传文件
        HttpClientUploadFile.uploadFile("http://localhost:8080/web/UploadFile",
                uploadFiles);
    }
}

—–分割线—–

原理和web端一样,解析下web端的request报文,解析一下就明白了
上传代码

package com.zzu.cameratest;

import android.widget.Toast;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * Created by Coder on 2017/2/21.
 */

public class FileUpload {
    // 换行符
    private static final String newLine = "\r\n";
    private static final String boundaryPrefix = "--";
    // 定义数据分隔线
    private static final String BOUNDARY = "----7d4a6d158c9";

    private final static boolean isExited = false;


    public static void uploadFile(String urlStr, String filePath) {
        //获取文件名
        String fileName = filePath.substring(filePath.lastIndexOf('/')+1);
        File file = new File(filePath);
        //如果要上传的文件不存在
        if(!file.exists()){
            return;
        }

        DataOutputStream out = null;
        DataInputStream in = null;
        BufferedReader reader = null;
        try {
            // 服务器的域名
            URL url = new URL(urlStr);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            // 设置为POST请求
            conn.setRequestMethod("POST");
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setUseCaches(false);

            // 设置请求头参数
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("Charsert", "UTF-8");
            conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
            out = new DataOutputStream(conn.getOutputStream());

            // 上传文件
            StringBuilder sb = new StringBuilder();
            sb.append(boundaryPrefix);
            sb.append(BOUNDARY);
            sb.append(newLine);
            // 文件参数,photo参数名可以随意修改
            sb.append("Content-Disposition: form-data;name=\"photo\";filename=\"" + filePath
                    + "\"" + newLine);
            sb.append("Content-Type:application/octet-stream");
            // 参数头设置完以后需要两个换行,然后才是参数内容
            sb.append(newLine);
            sb.append(newLine);
            // 将参数头的数据写入到输出流中
            out.writeBytes(sb.toString());
            // 数据输入流,用于读取文件数据
            in = new DataInputStream(new FileInputStream(
                    file));
            byte[] bufferOut = new byte[1024 * 4];
            int len = -1;
            // 每次读4KB数据,并且将文件数据写入到输出流中
            while ((len = in.read(bufferOut)) != -1) {
                out.write(bufferOut, 0, len);
                System.out.println("uploading!!!!!!!");
            }
            // 最后添加换行
            out.writeBytes(newLine);

            // 定义最后数据分隔线,即--加上BOUNDARY再加上-- 写上结尾标识
            out.writeBytes(newLine + boundaryPrefix + BOUNDARY + boundaryPrefix + newLine);
            out.flush();

            System.out.println("成功!!!!!!!");
            // 定义BufferedReader输入流来读取URL的响应
            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();
        }finally {

            try {
                if(in != null){
                    in.close();
                }
                if(out != null){
                    out.close();
                }
                if(reader != null){
                    reader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }


}
package servlet;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

public class UploadFile extends HttpServlet {
    private String uploadDir = "D://temp";

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        doPost(request, response);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        getHeadersInfo(request);

        System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!");
        try {
            ServletFileUpload upload = new ServletFileUpload();
            // set max file size to 100 MB:
            upload.setFileSizeMax(100 * 1024 * 1024);
            FileItemIterator it = upload.getItemIterator(request);
            // handle with each file:
            while (it.hasNext()) {
                FileItemStream item = it.next();
                if (! item.isFormField()) {
                    // it is a file upload:
                    handleFileItem(item);
                }
            }
        }
        catch(FileUploadException e) {
            throw new ServletException("Cannot upload file.", e);
        }

    }

    void handleFileItem(FileItemStream item) throws IOException {
        System.out.println("upload file: " + item.getName());
        String fileType = item.getName().substring(item.getName().lastIndexOf('.')+1);
        File path = new File(uploadDir);
        if(!path.exists()){
            path.mkdir();
        }
        File newUploadFile = new File(uploadDir + "/" + UUID.randomUUID().toString()+"."+fileType);
        byte[] buffer = new byte[4 * 1024];
        InputStream input = null;
        BufferedOutputStream output = null;
        try {
            input = item.openStream();
            output = new BufferedOutputStream(new FileOutputStream(newUploadFile));
            int len = -1;
            while((len = input.read(buffer)) != -1) {
                output.write(buffer, 0, len);
            }
        }
        finally {
            if (input!=null) {
                try {
                    input.close();
                }
                catch (IOException e) {}
            }
            if (output!=null) {
                try {
                    output.close();
                }
                catch (IOException e) {}
            }
        }
    }

    private Map<String, String> getHeadersInfo(HttpServletRequest request) {
        Map<String, String> map = new HashMap<String, String>();
        Enumeration<String> headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String key = (String) headerNames.nextElement();
            String value = request.getHeader(key);
            map.put(key, value);
            System.out.println(key+" "+value);
        }
        return map;
      }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值