java-通过-HttpURLConnection-上传文件

27次阅读

共计 6481 个字符,预计需要花费 17 分钟才能阅读完成。

直接用 jdk 的 HttpURLConnection 上传文件,通过模拟 post 提交方法

具体代码如下:

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.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

/**
 * http 网络访问工具
 *
 * @author wonderful.
 * @version 3.0.0
 */
public class HttpClient {private final static Logger LOGGER = Logger.getLogger(HttpClient.class);
    private String method = null;
    private String CONTENT_TYPE = null; // 默认
    
    /**
     * 默认 POST
     *
     * @return String
     */
    public String getMethod() {if (method == null) {return "POST";}
        return method;
    }

    /**
     *  POST 或 GET 
     *
     * @param method .
     */
    public void setMethod(String method) {this.method = method;}
    
    /**
     * 执行调用 serviceURL 地址 方法
     * @param serviceURL webService 地址.
     * @param param String.
     * @param ContentType 请求的与实体对应的 MIME 信息   如:Content-Type: application/x-www-form-urlencoded,application/json,application/xml  
     * @return String.
     */
    public String pub(String serviceURL, String param,String contentType) {
        CONTENT_TYPE = contentType;
        return pub(serviceURL,param);
    }
    /**
     * 执行调用 serviceURL 地址 方法
     * @param serviceURL webService 地址.
     * @param param String.
     * @return String.
     */
    public String pub(String serviceURL, String param) {
        URL url = null;
        HttpURLConnection connection = null;
        StringBuffer buffer = new StringBuffer();
        LOGGER.info("request:" + serviceURL + "?" + param);
        try {url = new URL(serviceURL);
            connection = (HttpURLConnection) url.openConnection();
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setUseCaches(false);
            connection.setRequestMethod(getMethod());
            connection.setConnectTimeout(5000);//30 秒连接
            connection.setReadTimeout(5*60*1000);// 5 分钟读数据
            connection.setRequestProperty("Content-Length", param.length() + "");
            if(CONTENT_TYPE != null){connection.setRequestProperty("Content-Type", CONTENT_TYPE);
            }           
            
            OutputStream outputStream = connection.getOutputStream();
            outputStream.write(param.getBytes("UTF-8"));

            BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
            String line = "";
            while ((line = reader.readLine()) != null) {buffer.append(line);
            }

            reader.close();} catch (IOException e) {LOGGER.error(e);
        } finally {if (connection != null) {connection.disconnect();
            }
        }

        LOGGER.info("response:" + buffer.toString());
        return buffer.toString();}

    /**
     * 上传文件
     * 
     * @param serviceURL
     * @param textMap
     *            表单参数
     * @param fileMap
     *            文件参数
     * @return
     * @throws IOException
     */
    public static String formUpload(String serviceURL, Map<String, String> textMap, Map<String, String> fileMap) throws IOException {Map<String, LinkedHashSet<String>> tempMap = new HashMap<>();
        if (!Objects.isNull(fileMap) && !fileMap.isEmpty()) {Iterator<Map.Entry<String, String>> iter = fileMap.entrySet().iterator();
            while (iter.hasNext()) {Map.Entry<String, String> entry = iter.next();
                String inputName = entry.getKey();
                String inputValue = entry.getValue();
                if (StringUtils.isAnyBlank(inputName, inputValue)) {continue;}
                LinkedHashSet<String> values = new LinkedHashSet<>();
                values.add(inputValue);
                tempMap.put(inputName, values);
            }
        }
        return formUploadMulti(serviceURL, textMap, tempMap);
    }

    /**
     * 上传文件, 允许同一个属性上传多个文件
     * 
     * @param serviceURL
     * @param textMap
     *            表单参数
     * @param fileMap
     *            文件参数
     * @return
     * @throws IOException
     */
    public static String formUploadMulti(String serviceURL, Map<String, String> textMap, Map<String, LinkedHashSet<String>> fileMap) throws IOException {LOGGER.trace(String.format("调用文件上传,传入参数:serviceURL=%s,textMap=%s,fileMap=%s", serviceURL, textMap, fileMap));
        String res = "";
        HttpURLConnection conn = null;
        OutputStream out = null;
        BufferedReader reader = null;
        String BOUNDARY = "---------------------------" + System.currentTimeMillis(); // boundary 就是 request 头和上传文件内容的分隔符
        try {URL url = new URL(serviceURL);
            conn = (HttpURLConnection) url.openConnection();
            conn.setConnectTimeout(5000);// 30 秒连接
            conn.setReadTimeout(5 * 60 * 1000);// 5 分钟读数据
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setUseCaches(false);
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);

            out = new DataOutputStream(conn.getOutputStream());
            // text
            if (!Objects.isNull(textMap) && !textMap.isEmpty()) {StringBuffer strBuf = new StringBuffer();
                Iterator<Map.Entry<String, String>> iter = textMap.entrySet().iterator();
                while (iter.hasNext()) {Map.Entry<String, String> entry = iter.next();
                    String inputName = entry.getKey();
                    String inputValue = entry.getValue();
                    if (StringUtils.isAnyBlank(inputName, inputValue)) {continue;}
                    strBuf.append("\r\n").append("--").append(BOUNDARY).append("\r\n");
                    strBuf.append("Content-Disposition: form-data; name=\"" + inputName + "\"\r\n\r\n");
                    strBuf.append(inputValue);
                }
                out.write(strBuf.toString().getBytes());
            }

            // file
            if (!Objects.isNull(fileMap) && !fileMap.isEmpty()) {Iterator<Entry<String, LinkedHashSet<String>>> iter = fileMap.entrySet().iterator();
                while (iter.hasNext()) {Entry<String, LinkedHashSet<String>> entry = iter.next();
                    String inputName = entry.getKey();
                    LinkedHashSet<String> inputValue = entry.getValue();
                    if (StringUtils.isAnyBlank(inputName) || inputValue.isEmpty()) {continue;}
                    for (String filePath : inputValue) {File file = new File(filePath);
                        String filename = file.getName();
                        Path path = Paths.get(filePath);
                        String contentType = Files.probeContentType(path);
                        StringBuffer strBuf = new StringBuffer();
                        strBuf.append("\r\n").append("--").append(BOUNDARY).append("\r\n");
                        strBuf.append("Content-Disposition: form-data; name=\"" + inputName + "\"; filename=\""+ filename +"\"\r\n");
                        strBuf.append("Content-Type:" + contentType + "\r\n\r\n");
                        LOGGER.trace(String.format("filename:%s,contentType:%s", filename, contentType));
                        out.write(strBuf.toString().getBytes());

                        DataInputStream in = new DataInputStream(new FileInputStream(file));
                        int bytes = 0;
                        byte[] bufferOut = new byte[1024];
                        while ((bytes = in.read(bufferOut)) != -1) {out.write(bufferOut, 0, bytes);
                        }
                        in.close();}
                }
            }

            byte[] endData = ("\r\n--" + BOUNDARY + "--\r\n").getBytes();
            out.write(endData);
            out.flush();

            // 读取返回数据
            LOGGER.trace(String.format("http 返回状态:ResponseCode=%s,ResponseMessage=%s", conn.getResponseCode(), conn.getResponseMessage()));
            StringBuffer strBuf = new StringBuffer();
            reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line = null;
            while ((line = reader.readLine()) != null) {strBuf.append(line).append("\n");
            }
            res = strBuf.toString();
            LOGGER.trace(String.format("http 返回数据:%s", res));
            reader.close();
            reader = null;
        } catch (IOException e) {throw e;} finally {if (!Objects.isNull(out)) {out.close();
                out = null;
            }
            if (!Objects.isNull(reader)) {reader.close();
                reader = null;
            }
            if (conn != null) {conn.disconnect();
                conn = null;
            }
        }
        return res;
    }
}

上面的两个方法有待优化,未处理

正文完
 0