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

top.jfunc.http.util.NativeUtil Maven / Gradle / Ivy

package top.jfunc.http.util;

import top.jfunc.http.base.FormFile;
import top.jfunc.http.base.HttpHeaders;
import top.jfunc.common.utils.ArrayListMultiValueMap;
import top.jfunc.common.utils.IoUtil;
import top.jfunc.common.utils.MapUtil;
import top.jfunc.common.utils.MultiValueMap;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSocketFactory;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.util.List;
import java.util.Map;

import static top.jfunc.common.utils.StrUtil.CRLF;
import static top.jfunc.common.utils.StrUtil.TWO_HYPHENS;

/**
 * @author xiongshiyan at 2019/7/12 , contact me with email [email protected] or phone 15208384257
 */
public class NativeUtil {
    private static final String BOUNDARY = "*****xsyloveyou******";
    /**
     * 数据开始标志
     */
    private static final String PART_BEGIN_LINE = TWO_HYPHENS + BOUNDARY + CRLF;
    /**
     * 数据结束标志
     */
    private static final String END_LINE = TWO_HYPHENS + BOUNDARY + TWO_HYPHENS + CRLF;


    public static void upload0(HttpURLConnection connection , Iterable formFiles) throws IOException {
        connection.setRequestProperty(HttpHeaders.CONTENT_LENGTH , String.valueOf(getFormFilesLen(formFiles) + END_LINE.length()));
        connection.setRequestProperty(HttpHeaders.CONTENT_TYPE , "multipart/form-data; boundary=" + BOUNDARY);

        try(DataOutputStream ds = new DataOutputStream(connection.getOutputStream())) {
            for (FormFile formFile : formFiles) {
                writeOneFile(ds, formFile);
            }
            ds.writeBytes(END_LINE);
            ds.flush();
        }
    }

    public static void upload0(HttpURLConnection connection , MultiValueMap params, String paramCharset, Iterable formFiles) throws IOException{
        int fileDataLength = getFormFilesLen(formFiles);

        String textEntity = getTextEntity(params);
        // 计算传输给服务器的实体数据总长度
        int dataLength = textEntity.getBytes(paramCharset).length + fileDataLength + END_LINE.length();

        connection.setRequestProperty(HttpHeaders.CONTENT_LENGTH , String.valueOf(dataLength));
        connection.setRequestProperty(HttpHeaders.CONTENT_TYPE , "multipart/form-data; boundary=" + BOUNDARY);

        try(DataOutputStream ds = new DataOutputStream(connection.getOutputStream())) {
            //写params数据
            ds.writeBytes(textEntity);
            //写文件
            for (FormFile formFile : formFiles) {
                writeOneFile(ds, formFile);
            }
            //写末尾行
            ds.writeBytes(END_LINE);
            ds.flush();
        }
    }

    /**
     * 写一个文件 , 必须保证和getFormFilesLen的内容一致
     * @see NativeUtil#getFormFilesLen(Iterable)
     */
    private static void writeOneFile(DataOutputStream ds, FormFile formFile) throws IOException {
        ds.writeBytes(PART_BEGIN_LINE);
        ds.writeBytes("Content-Disposition: form-data; name=\"" + formFile.getParameterName() + "\"; filename=\"" + formFile.getFilName() + "\"" + CRLF);
        ds.writeBytes("Content-Type: " + formFile.getContentType() + CRLF + CRLF);

        try(InputStream inStream = formFile.getInStream()){
            IoUtil.copy(inStream, ds);
            ds.writeBytes(CRLF);
        }
    }

    /**
     * 计算需要传输的字节数
     * @see NativeUtil#writeOneFile(DataOutputStream, FormFile)
     * @param formFiles FormFile
     * @return 总的字节数
     */
    private static int getFormFilesLen(Iterable formFiles){
        int fileDataLength = 0;
        for (FormFile formFile : formFiles) {
            StringBuilder fileExplain = new StringBuilder();
            fileExplain.append(PART_BEGIN_LINE);
            fileExplain.append("Content-Disposition: form-data; name=\"" + formFile.getParameterName() + "\";filename=\"" + formFile.getFilName() + "\"" + CRLF);
            fileExplain.append("Content-Type: " + formFile.getContentType() + CRLF + CRLF);
            fileDataLength += fileExplain.length();
            fileDataLength += formFile.getFileLen();
            fileDataLength += CRLF.length();
        }
        return fileDataLength;
    }

    private static String getTextEntity(MultiValueMap params) {
        StringBuilder textEntity = new StringBuilder();
        if(MapUtil.notEmpty(params)){
            params.forEachKeyValue((key,value)->{
                textEntity.append(PART_BEGIN_LINE);
                textEntity.append("Content-Disposition: form-data; name=\"" + key + "\"" + CRLF + CRLF);
                textEntity.append(value).append(CRLF);
            });
        }
        return textEntity.toString();
    }

    /**
     * @see top.jfunc.http.ssl.SSLSocketFactoryBuilder#build()
     * @see top.jfunc.http.ssl.SSLSocketFactoryBuilder#build(String, String)
     */
    public static void initSSL(HttpsURLConnection con , HostnameVerifier hostnameVerifier , SSLSocketFactory sslSocketFactory) {
        // 验证域
        if(null != hostnameVerifier){
            con.setHostnameVerifier(hostnameVerifier);
        }
        if(null != sslSocketFactory){
            con.setSSLSocketFactory(sslSocketFactory);
        }
    }

    public static void setRequestHeaders(HttpURLConnection connection, String contentType,
                                     MultiValueMap headers) {
        //add方式处理多值header
        if(MapUtil.notEmpty(headers)) {
            headers.forEachKeyValue(connection::addRequestProperty);
        }

        if(null != contentType){
            connection.setRequestProperty(HttpHeaders.CONTENT_TYPE, contentType);
        }
    }

    public static void writeContent(HttpURLConnection connect, String data, String bodyCharset) throws IOException {
        if (null == data) {
            return;
        }

        //!!!!!!设置ContentType非常重要,他写入的时候根据Content-Type的编码来写的!!!!!!!

        try(OutputStream outputStream = connect.getOutputStream()){
            outputStream.write(data.getBytes(bodyCharset));
        }
    }

    public static MultiValueMap parseHeaders(HttpURLConnection connection) {
        Map> headerFields = connection.getHeaderFields();
        if(MapUtil.isEmpty(headerFields)){
            return null;
        }
        return new ArrayListMultiValueMap<>(headerFields);
    }


    public static void closeQuietly(HttpURLConnection connect) {
        if(null != connect){
            try {
                connect.disconnect();
            } catch (Exception e) {}
        }
    }

    /**
     * form-data的格式为:
     */
    /*
    --*****xsyloveyou******
    Content-Disposition: form-data; name="k1"

    v1
    --*****xsyloveyou******
    Content-Disposition: form-data; name="k2"

    v2
    --*****xsyloveyou******
    Content-Disposition: form-data; name="filedata2"; filename="BugReport.png"
    Content-Type: application/octet-stream

            我是文本类容文件
    --*****xsyloveyou******
    Content-Disposition: form-data; name="filedata"; filename="838586397836550106.jpg"
    Content-Type: application/octet-stream

            我是文件内容2
    --*****xsyloveyou******--

    */
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy