All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.apexes.commons.net.HttpFileUploader Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2018, apexes.net. All rights reserved.
 *
 *         http://www.apexes.net
 *
 */
package net.apexes.commons.net;

import net.apexes.commons.lang.Checks;
import net.apexes.commons.lang.Networks;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSocketFactory;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * Http文件上传
 * 
 * @author HeDYn
 *
 */
public class HttpFileUploader {

    private static final String BOUNDARY = "---------7123a85b75f";

    private final String url;
    private final Map httpProperties;
    private final Map textParams;
    private final Map fileParams;
    
    private int connectTimeout = 6 * 1000;
    private int readTimeout = 10 * 1000;

    private SSLSocketFactory sslSocketFactory;
    private HostnameVerifier hostnameVerifier;
                                     
    public HttpFileUploader(String url) {
        this.url = url;
        httpProperties = new LinkedHashMap<>();
        textParams = new HashMap<>();
        fileParams = new HashMap<>();
    }

    public String getUrl() {
        return url;
    }

    /**
     * 设置连接超时时间
     * @param timeout 超时时间,单位ms
     */
    public void setConnectTimeout(int timeout) {
        this.connectTimeout = timeout;
    }
    
    /**
     * 设置读取超时时间
     * @param timeout 超时时间,单位ms
     */
    public void setReadTimeout(int timeout) {
        this.readTimeout = timeout;
    }
    
    public void setHttpProperty(String key, String value) {
        Checks.verifyNotNull(key, "key");
        Checks.verifyNotNull(value, "value");
        httpProperties.put(key, value);
    }

    public void exemptSSL() throws KeyManagementException, NoSuchAlgorithmException {
        this.sslSocketFactory = Networks.exemptSSLContext().getSocketFactory();
        this.hostnameVerifier = Networks.exemptHostnameVerifier();
    }

    public void setSSLSocketFactory(SSLSocketFactory sslSocketFactory) {
        this.sslSocketFactory = sslSocketFactory;
    }

    public void setHostnameVerifier(HostnameVerifier hostnameVerifier) {
        this.hostnameVerifier = hostnameVerifier;
    }

    /**
     * 增加一个普通字符串数据到表单数据中
     * @param name 名称
     * @param value 值
     */
    public void addTextParameter(String name, String value) {
        textParams.put(name, value);
    }
    
    /**
     * 增加一个文件到表单数据中
     * @param name 名称
     * @param file 文件
     */
    public void addFileParameter(String name, File file) {
        addFileParameter(name, file, "application/octet-stream");
    }

    /**
     * 增加一个文件到表单数据中
     * @param name 名称
     * @param file 文件
     * @param contentType 文件类型
     */
    public void addFileParameter(String name, File file, String contentType) {
        fileParams.put(name, new LocalFileParameter(file, contentType));
    }

    /**
     * 增加一个文件内容到表单数据中
     * @param name 名称
     * @param content 内容
     */
    public void addFileParameter(String name, byte[] content) {
        addFileParameter(name, name, content);
    }

    /**
     * 增加一个文件内容到表单数据中
     * @param name 名称
     * @param filename 文件名
     * @param content 内容
     */
    public void addFileParameter(String name, String filename, byte[] content) {
        addFileParameter(name, filename, content, "application/octet-stream");
    }

    /**
     * 增加一个文件内容到表单数据中
     * @param name 名称
     * @param content 内容
     * @param contentType 类型
     */
    public void addFileParameter(String name, byte[] content, String contentType) {
        addFileParameter(name, name, content, contentType);
    }

    /**
     * 增加一个文件内容到表单数据中
     * @param name 名称
     * @param filename 文件名
     * @param content 内容
     * @param contentType 类型
     */
    public void addFileParameter(String name, String filename, byte[] content, String contentType) {
        fileParams.put(name, new BytesFileParameter(filename, content, contentType));
    }
    
    /**
     * 清除所有表单数据
     */
    public void clearParameter() {
        textParams.clear();
        fileParams.clear();
    }
    
    public byte[] upload() throws Exception {
        HttpURLConnection conn = Networks.connect(new URL(url), sslSocketFactory, hostnameVerifier);
        conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
        conn.setRequestMethod("POST");
        conn.setDoOutput(true);
        conn.setUseCaches(false);
        conn.setConnectTimeout(connectTimeout);
        conn.setReadTimeout(readTimeout);

        for (Map.Entry entry : httpProperties.entrySet()) {
            conn.setRequestProperty(entry.getKey(), entry.getValue());
        }

        try {
            conn.connect();

            DataOutputStream ops = new DataOutputStream(conn.getOutputStream());
            writeFileParams(ops);
            writeTextParams(ops);
            
            ops.writeBytes("--" + BOUNDARY + "--" + "\r\n");
            ops.writeBytes("\r\n");
            ops.flush();
            
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            InputStream in = conn.getInputStream();
            byte[] buf = new byte[1024];
            int len;
            while ((len = in.read(buf)) != -1) {
                out.write(buf, 0, len);
            }
            return out.toByteArray();
        } finally {
            conn.disconnect();
        }
    }
    
    private void writeTextParams(DataOutputStream ops) throws Exception {
        for (Map.Entry entry : textParams.entrySet()) {
            String name = entry.getKey();
            String value = entry.getValue();
            ops.writeBytes("--" + BOUNDARY + "\r\n");
            ops.writeBytes("Content-Disposition: form-data; name=\"" + name + "\"\r\n");
            ops.writeBytes("\r\n");
            ops.writeBytes(URLEncoder.encode(value, "UTF-8") + "\r\n");
        }
    }

    private void writeFileParams(DataOutputStream ops) throws Exception {
        for (Map.Entry entry : fileParams.entrySet()) {
            String name = entry.getKey();
            FileParameter param = entry.getValue();
            ops.writeBytes("--" + BOUNDARY + "\r\n");
            ops.writeBytes("Content-Disposition: form-data; name=\"" + name + "\"; filename=\""
                    + URLEncoder.encode(param.getFilename(), "UTF-8") + "\"\r\n");
            ops.writeBytes("Content-Type: " + param.getContentType() + "\r\n");
            ops.writeBytes("\r\n");
            ops.write(param.getContent());
            ops.writeBytes("\r\n");
        }
    }
    
    /**
     * 
     * @author HeDYn
     *
     */
    public interface FileParameter {
        
        String getContentType();
        
        String getFilename();
        
        byte[] getContent() throws Exception;
        
    }
    
    /**
     * 
     * @author HeDYn
     *
     */
    private static class LocalFileParameter implements FileParameter {
        
        private final File file;
        private final String contentType;
        
        private LocalFileParameter(File file, String contentType) {
            this.file = file;
            this.contentType = contentType;
        }

        @Override
        public String getContentType() {
            return contentType;
        }

        @Override
        public String getFilename() {
            return file.getName();
        }

        @Override
        public byte[] getContent() throws Exception {
            ByteArrayOutputStream ops = new ByteArrayOutputStream();
            try (FileInputStream in = new FileInputStream(file)) {
                byte[] buf = new byte[1024];
                int len;
                while ((len = in.read(buf)) != -1) {
                    ops.write(buf, 0, len);
                }
            }
            return ops.toByteArray();
        }
    }
    
    /**
     * 
     * @author HeDYn
     *
     */
    private static class BytesFileParameter implements FileParameter {

        private final String filename;
        private final byte[] content;
        private final String contentType;
        
        private BytesFileParameter(String filename, byte[] content, String contentType) {
            this.filename = filename;
            this.content = content;
            this.contentType = contentType;
        }

        @Override
        public String getContentType() {
            return contentType;
        }

        @Override
        public String getFilename() {
            return filename;
        }

        @Override
        public byte[] getContent() throws Exception {
            return content;
        }
        
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy