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

com.yutils.http.YHttpBase Maven / Gradle / Ivy

There is a newer version: 1.1.4
Show newest version
package com.yutils.http;

import com.yutils.http.contract.YHttpProgressListener;
import com.yutils.http.contract.YSessionListener;
import com.yutils.http.model.Upload;

import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 网络请求基础类,柱塞式
 *
 * @author yujing 2020年7月28日10:22:35
 */
public class YHttpBase {
    protected String contentType = null;// "application/x-www-form-urlencoded;charset=utf-8";//"application/json;charset=utf-8"
    protected int connectTimeout = 1000 * 20;
    //userAgent,Android     ---->   Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Mobile Safari/537.36
    //userAgent,iPhoneX     ---->   Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1
    //userAgent,iPad        ---->   Mozilla/5.0 (iPad; CPU OS 11_0 like Mac OS X) AppleWebKit/604.1.34 (KHTML, like Gecko) Version/11.0 Mobile/15A5341f Safari/604.1 Edg/85.0.4183.83
    //userAgent,windows10   ---->   Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36
    protected String userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36";
    /**
     * boundary就是request头和上传文件内容的分隔符
     */
    protected static final String BOUNDARY = "------------YuJing---------------";
    /**
     * session获取监听
     */
    protected YSessionListener sessionListener;
    /**
     * SessionId
     */
    protected String sessionId;
    /**
     * 下载是否停止
     */
    protected boolean downLoadStop = false;

    //立即终止当前文件下载
    public void downloadFileStop() {
        downLoadStop = true;
    }

    //ContentType
    public String getContentType() {
        return contentType;
    }

    public YHttpBase setContentType(String contentType) {
        this.contentType = contentType;
        return this;
    }

    //Timeout
    public int getConnectTimeout() {
        return connectTimeout;
    }

    public YHttpBase setConnectTimeout(int connectTimeout) {
        this.connectTimeout = connectTimeout;
        return this;
    }

    //crt证书
    protected String crtSSL;

    public String getCrtSSL() {
        return crtSSL;
    }

    public YHttpBase setCrtSSL(String crtSSL) {
        this.crtSSL = crtSSL;
        return this;
    }

    //RequestProperty,请求头
    protected Map mapSetRequestProperty;
    protected Map mapAddRequestProperty;

    public YHttpBase setRequestProperty(String key, String value) {
        if (mapSetRequestProperty == null)
            mapSetRequestProperty = new HashMap<>();
        mapSetRequestProperty.put(key, value);
        return this;
    }

    @SuppressWarnings("StringOperationCanBeSimplified")
    public YHttpBase addRequestProperty(String key, String value) {
        //可以重复key的map,但是key的内存地址要不一样
        if (mapAddRequestProperty == null)
            mapAddRequestProperty = new IdentityHashMap<>();
        mapAddRequestProperty.put(new String(key), value);
        return this;
    }

    //session监听
    public YHttpBase setSessionListener(YSessionListener ySessionListener) {
        this.sessionListener = ySessionListener;
        return this;
    }

    //setSessionId
    public YHttpBase setSessionId(String sessionId) {
        this.sessionId = sessionId;
        return this;
    }

    /**
     * get请求,同步柱塞试
     *
     * @param requestUrl url
     * @return 请求结果
     * @throws Exception 异常
     */
    public byte[] get(String requestUrl) throws Exception {
        return request(requestUrl, null, "GET");
    }

    /**
     * post请求,同步柱塞试
     *
     * @param requestUrl   rul
     * @param requestBytes 请求内容
     * @return 请求结果
     * @throws Exception 异常
     */
    public byte[] post(String requestUrl, byte[] requestBytes) throws Exception {
        return request(requestUrl, requestBytes, "POST");
    }

    /**
     * put请求,同步柱塞试
     *
     * @param requestUrl   rul
     * @param requestBytes 请求内容
     * @return 请求结果
     * @throws Exception 异常
     */
    public byte[] put(String requestUrl, byte[] requestBytes) throws Exception {
        return request(requestUrl, requestBytes, "PUT");
    }

    /**
     * delete请求,同步柱塞试
     *
     * @param requestUrl   rul
     * @param requestBytes 请求内容
     * @return 请求结果
     * @throws Exception 异常
     */
    public byte[] delete(String requestUrl, byte[] requestBytes) throws Exception {
        return request(requestUrl, requestBytes, "DELETE");
    }

    /**
     * delete请求,同步柱塞试
     *
     * @param requestUrl    rul
     * @param requestBytes  请求内容
     * @param requestMethod 请求方式,只能是 "GET", "POST", "HEAD", "OPTIONS", "PUT", "DELETE", "TRACE"
     * @return 请求结果
     * @throws Exception 异常
     */
    public byte[] request(String requestUrl, byte[] requestBytes, String requestMethod) throws Exception {
        // 打开一个HttpURLConnection连接
        HttpURLConnection urlConn = YHttpURLConnectionFactory.create(requestUrl, crtSSL);
        //设置从主机读取数据超时
        urlConn.setReadTimeout(connectTimeout);
        setHttpURLConnection(urlConn, requestMethod);
        if ("GET".equals(requestMethod)) {
            // 设置session
            setSession(urlConn);
            // 开始连接
            urlConn.connect();
            // 获取session
            getSession(urlConn);
            // 判断请求是否成功
            int responseCode = urlConn.getResponseCode();
            if (responseCode != HttpURLConnection.HTTP_OK) {
                throw new Exception("错误码:" + responseCode);
            }
            // 关闭连接
        } else {
            // 发送POST请求必须设置如下两行
            urlConn.setDoOutput(true);
            urlConn.setDoInput(true);
            // 设置session
            setSession(urlConn);
            // 开始连接
            urlConn.connect();
            // 发送请求参数
            DataOutputStream dos = new DataOutputStream(urlConn.getOutputStream());
            dos.write(requestBytes);
            dos.flush();
            dos.close();
            // 获取session
            getSession(urlConn);
            // 判断请求是否成功
            int responseCode = urlConn.getResponseCode();
            if (responseCode != HttpURLConnection.HTTP_OK) {
                throw new Exception("错误码:" + responseCode);
            }
        }
        // 关闭连接
        byte[] bytes = YHttpUtils.inputStreamToBytes(urlConn.getInputStream());
        urlConn.disconnect();
        return bytes;
    }

    /**
     * 文件下载,同步柱塞试
     *
     * @param requestUrl url
     * @param file       下载的文件
     * @param listener   进度监听
     * @throws Exception 异常
     */
    @SuppressWarnings("ResultOfMethodCallIgnored")
    public void downloadFile(String requestUrl, File file, YHttpProgressListener listener) throws Exception {
        File parent = file.getParentFile();
        if (!Objects.requireNonNull(parent).exists()) parent.mkdirs();
        if (file.exists()) file.delete();// 删除存在文件
        // 打开一个HttpURLConnection连接
        HttpURLConnection urlConn = YHttpURLConnectionFactory.create(requestUrl, crtSSL);
        setHttpURLConnection(urlConn, "GET");
        // 设置session
        setSession(urlConn);
        // 开始连接
        urlConn.connect();
        // 获取session
        getSession(urlConn);
        // 判断请求是否成功
        int responseCode = urlConn.getResponseCode();
        if (responseCode != HttpURLConnection.HTTP_OK) {
            throw new Exception("错误码:" + responseCode);
        }
        int downloadSize = 0;
        int fileSize = urlConn.getContentLength(); // 获取不到文件大小时候fileSize=-1
        int len;
        byte[] buffer = new byte[1024 * 8];
        FileOutputStream fos = new FileOutputStream(file);
        InputStream inputStream = urlConn.getInputStream();
        downLoadStop = false;//这设置成false,在下载过程中downLoadIsStop的值可能会被改变
        while (!downLoadStop && (len = inputStream.read(buffer)) != -1) {
            // 写到本地
            fos.write(buffer, 0, len);
            downloadSize += len;
            listener.progress(downloadSize, fileSize);
        }
        if (downLoadStop) throw new Exception("终止下载");
        // 关闭连接
        urlConn.disconnect();
    }

    /**
     * 加载,同步柱塞试
     *
     * @param requestUrl url
     * @param listener   进度监听
     * @return 结果
     * @throws Exception 异常
     */
    public byte[] load(String requestUrl, YHttpProgressListener listener) throws Exception {
        // 打开一个HttpURLConnection连接
        HttpURLConnection urlConn = YHttpURLConnectionFactory.create(requestUrl, crtSSL);
        urlConn.setAllowUserInteraction(true);
        setHttpURLConnection(urlConn, "GET");
        // 设置session
        setSession(urlConn);
        // 开始连接
        urlConn.connect();
        // 获取session
        getSession(urlConn);
        // 判断请求是否成功
        int responseCode = urlConn.getResponseCode();
        if (responseCode != HttpURLConnection.HTTP_OK) {
            throw new Exception("错误码:" + responseCode);
        }
        int downloadSize = 0;
        int fileSize = urlConn.getContentLength(); // 获取不到文件大小时候fileSize=-1
        int len;
        byte[] buffer = new byte[1024 * 8];
        ByteArrayOutputStream bs = new ByteArrayOutputStream();
        InputStream inputStream = urlConn.getInputStream();
        while ((len = inputStream.read(buffer)) != -1) {
            bs.write(buffer, 0, len);
            downloadSize += len;
            listener.progress(downloadSize, fileSize);
        }
        bs.flush();
        byte[] bytes = bs.toByteArray();
        // 关闭连接
        urlConn.disconnect();
        return bytes;
    }

    /**
     * 文件上传,同步柱塞试
     *
     * @param requestUrl   url
     * @param requestBytes 请求内容
     * @param fileMap      key,文件
     * @return 请求结果
     * @throws Exception 异常
     */
    public byte[] upload(String requestUrl, byte[] requestBytes, Map fileMap) throws Exception {
        List uploads = new ArrayList<>();
        for (Map.Entry entry : fileMap.entrySet()) {
            if (entry.getValue() == null) continue;
            uploads.add(new Upload(entry.getKey(), entry.getValue()));
        }
        return upload(requestUrl, requestBytes, uploads);
    }

    /**
     * 文件上传,同步柱塞试
     *
     * @param requestUrl   url
     * @param requestBytes 请求内容
     * @param uploads      上传的key,内容,文件名,contentType
     * @return 请求结果
     * @throws Exception 异常
     */
    public byte[] upload(String requestUrl, byte[] requestBytes, List uploads) throws Exception {
        // 打开一个HttpURLConnection连接
        HttpURLConnection urlConn = YHttpURLConnectionFactory.create(requestUrl, crtSSL);
        //设置从主机读取数据超时
        urlConn.setReadTimeout(connectTimeout);
        setContentType("multipart/form-data; boundary=" + BOUNDARY);
        setHttpURLConnection(urlConn, "POST");
        // 设置session
        setSession(urlConn);
        // 发送POST请求必须设置如下两行
        urlConn.setDoOutput(true);
        urlConn.setDoInput(true);
        // 开始连接
        urlConn.connect();
        // 发送请求参数
        send(urlConn, requestBytes, uploads);
        // 获取session
        getSession(urlConn);
        // 判断请求是否成功
        int responseCode = urlConn.getResponseCode();
        if (responseCode != HttpURLConnection.HTTP_OK) {
            throw new Exception("错误码:" + responseCode);
        }
        byte[] bytes = YHttpUtils.inputStreamToBytes(urlConn.getInputStream());
        // 关闭连接
        urlConn.disconnect();
        return bytes;
    }

    /**
     * 发送文件的数据组装
     *
     * @param httpURLConnection 连接对象
     * @param requestBytes      请求的参数
     * @param uploads           上传的文件
     * @throws IOException 异常
     */
    protected void send(HttpURLConnection httpURLConnection, byte[] requestBytes, List uploads) throws IOException {
        OutputStream out = new DataOutputStream(httpURLConnection.getOutputStream());
        // 文本参数
        if (requestBytes != null) out.write(requestBytes);
        // 文件
        if (uploads != null) {
            for (Upload item : uploads) {
                if (item.getBytes() != null) {
                    StringBuilder strBuf = new StringBuilder();
                    strBuf.append("\r\n--").append(BOUNDARY).append("\r\n")
                            .append("Content-Disposition: form-data; name=\"")
                            .append(item.getKey())
                            .append("\"; filename=\"")
                            .append(item.getFilename())
                            .append("\"\r\n");
                    strBuf.append("Content-Type:").append(item.getContentType()).append("\r\n\r\n");
                    out.write(strBuf.toString().getBytes());
                    out.write(item.getBytes());
                } else if (item.getFile() != null) {
                    StringBuilder strBuf = new StringBuilder();
                    strBuf.append("\r\n--").append(BOUNDARY).append("\r\n")
                            .append("Content-Disposition: form-data; name=\"")
                            .append(item.getKey())
                            .append("\"; filename=\"")
                            .append(item.getFilename())
                            .append("\"\r\n");
                    strBuf.append("Content-Type:").append(item.getContentType()).append("\r\n\r\n");
                    out.write(strBuf.toString().getBytes());
                    DataInputStream in = new DataInputStream(new FileInputStream(item.getFile()));
                    int bytes;
                    byte[] bufferOut = new byte[1024 * 8];
                    while ((bytes = in.read(bufferOut)) != -1)
                        out.write(bufferOut, 0, bytes);
                    in.close();
                } else {
                    try {
                        Class.forName("android.graphics.Bitmap");
                        if (item.getBitmap() != null) {
                            StringBuilder strBuf = new StringBuilder();
                            strBuf.append("\r\n--").append(BOUNDARY).append("\r\n")
                                    .append("Content-Disposition: form-data; name=\"")
                                    .append(item.getKey())
                                    .append("\"; filename=\"")
                                    .append(item.getFilename())
                                    .append("\"\r\n");
                            strBuf.append("Content-Type:").append(item.getContentType()).append("\r\n\r\n");
                            out.write(strBuf.toString().getBytes());
                            // bitmap转Bytes
                            byte[] bytes = Android.bitmapToByteArray(item.getBitmap());
                            out.write(bytes);
                        }
                    } catch (Exception e) {
                        System.err.println("上传Bitmap异常:" + e.getMessage());
                    }
                }
            }
        }
        out.write(("\r\n--" + BOUNDARY + "--\r\n").getBytes());// 结束标记
        out.flush();
        out.close();
    }

    /**
     * HttpURLConnection 的一些基础设置
     *
     * @param urlConn       连接
     * @param requestMethod 请求类型
     * @throws Exception Exception
     */
    private void setHttpURLConnection(HttpURLConnection urlConn, String requestMethod) throws Exception {
        // 设置连接超时时间
        urlConn.setConnectTimeout(connectTimeout);
        //设置请求允许输入 默认是true
        urlConn.setDoInput(true);
        // Post请求不能使用缓存
        urlConn.setUseCaches(false);
        // 设置为请求类型
        if (requestMethod != null)
            urlConn.setRequestMethod(requestMethod);
        //设置本次连接是否自动处理重定向
        urlConn.setInstanceFollowRedirects(true);
        // 配置请求Content-Type
        urlConn.setRequestProperty("accept", "*/*");
        urlConn.setRequestProperty("connection", "Keep-Alive");
        urlConn.setRequestProperty("Charset", "utf-8");
        urlConn.setRequestProperty("Content-Type", contentType == null ? "application/x-www-form-urlencoded;charset=utf-8" : contentType);
        urlConn.setRequestProperty("User-Agent", userAgent);
        if (mapSetRequestProperty != null)
            for (Map.Entry entry : mapSetRequestProperty.entrySet())
                urlConn.setRequestProperty(entry.getKey(), entry.getValue());
        if (mapAddRequestProperty != null)
            for (Map.Entry entry : mapAddRequestProperty.entrySet())
                urlConn.addRequestProperty(entry.getKey(), entry.getValue());
    }

    /**
     * 设置session,把JSESSIONID变量的值设置成session
     *
     * @param httpURLConnection httpURLConnection
     */
    public void setSession(HttpURLConnection httpURLConnection) {
        if (sessionId != null && !sessionId.isEmpty()) {
            httpURLConnection.setRequestProperty("Cookie", "JSESSIONID=" + sessionId);
        }
    }

    /**
     * 获取session 并保存到JSESSIONID变量
     *
     * @param httpURLConnection httpURLConnection
     */
    public void getSession(HttpURLConnection httpURLConnection) {
        Map> map = httpURLConnection.getHeaderFields();
        if (map != null) {
            List list = map.get("Set-Cookie");
            if (list != null) {
                for (int i = 0; i < list.size(); i++) {
                    //System.out.println("Set-Cookie:"+list.get(i));
                    int start = list.get(i).indexOf("JSESSIONID");
                    if (start != -1) {
                        int idStart = start + 10 + 1;
                        int idEnd = start + 10 + 1 + 32;
                        if (list.get(i).length() >= idEnd) {
                            String JSESSIONID = list.get(i).substring(idStart, idEnd);// 如:list.get(i)="JSESSIONID=743D39694F006763220CA0CA63FE8978";
                            if (sessionListener != null)
                                Android.runOnUiThread(() -> sessionListener.sessionId(JSESSIONID));
                            sessionId = JSESSIONID;
                        }
                    }
                }
            }
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy