HttpUtils

Tips: post 提交表单的时候需要注意content 的编码 ,一般约定使用UTF-8 ,系统默认编码时gb2312

如需调试,需要添加日志配置文件,级别调至 debug ,可以很方便排查乱码问题 

有时候诡异的问题会出现,org.apache.commons.httpclient.HttpClient 的日志无法打印,尽管已经配置了 logback.xml 

解决方法摸索出了一个,但还了解真正引发问题的原因

通过调整某些依赖的先后顺序,比如把 spring-context-support 放到最前面 

 DEBUG org.apache.commons.httpclient.HttpClient - Java version: 1.8.0_191
 DEBUG org.apache.commons.httpclient.HttpClient - Java vendor: Oracle Corporation
 DEBUG org.apache.commons.httpclient.HttpClient - Java class path: ...
 DEBUG org.apache.commons.httpclient.HttpClient - Operating system name: Windows 10
 DEBUG org.apache.commons.httpclient.HttpClient - Operating system architecture: amd64
 DEBUG org.apache.commons.httpclient.HttpClient - Operating system version: 10.0
 DEBUG org.apache.commons.httpclient.HttpClient - SUN 1.8: SUN (DSA key/parameter generation; DSA signing; SHA-1, MD5 digests; SecureRandom; X.509 certificates; JKS & DKS keystores; PKIX CertPathValidator; PKIX CertPathBuilder; LDAP, Collection CertStores, JavaPolicy Policy; JavaLoginConfig Configuration)
 DEBUG org.apache.commons.httpclient.HttpClient - SunRsaSign 1.8: Sun RSA signature provider
 DEBUG org.apache.commons.httpclient.HttpClient - SunEC 1.8: Sun Elliptic Curve provider (EC, ECDSA, ECDH)
 DEBUG org.apache.commons.httpclient.HttpClient - SunJSSE 1.8: Sun JSSE provider(PKCS12, SunX509/PKIX key/trust factories, SSLv3/TLSv1/TLSv1.1/TLSv1.2)
 DEBUG org.apache.commons.httpclient.HttpClient - SunJCE 1.8: SunJCE Provider (implements RSA, DES, Triple DES, AES, Blowfish, ARCFOUR, RC2, PBE, Diffie-Hellman, HMAC)
 DEBUG org.apache.commons.httpclient.HttpClient - SunJGSS 1.8: Sun (Kerberos v5, SPNEGO)
 DEBUG org.apache.commons.httpclient.HttpClient - SunSASL 1.8: Sun SASL provider(implements client mechanisms for: DIGEST-MD5, GSSAPI, EXTERNAL, PLAIN, CRAM-MD5, NTLM; server mechanisms for: DIGEST-MD5, GSSAPI, CRAM-MD5, NTLM)
 DEBUG org.apache.commons.httpclient.HttpClient - XMLDSig 1.8: XMLDSig (DOM XMLSignatureFactory; DOM KeyInfoFactory; C14N 1.0, C14N 1.1, Exclusive C14N, Base64, Enveloped, XPath, XPath2, XSLT TransformServices)
 DEBUG org.apache.commons.httpclient.HttpClient - SunPCSC 1.8: Sun PC/SC provider
 DEBUG org.apache.commons.httpclient.HttpClient - SunMSCAPI 1.8: Sun's Microsoft Crypto API provider
 DEBUG org.apache.commons.httpclient.HttpClient - BC 1.46: BouncyCastle Security Provider v1.46
 DEBUG o.a.commons.httpclient.params.DefaultHttpParams - Set parameter http.useragent = Jakarta Commons-HttpClient/3.1
 DEBUG o.a.commons.httpclient.params.DefaultHttpParams - Set parameter http.protocol.version = HTTP/1.1
 DEBUG o.a.commons.httpclient.params.DefaultHttpParams - Set parameter http.connection-manager.class = class org.apache.commons.httpclient.SimpleHttpConnectionManager
 DEBUG o.a.commons.httpclient.params.DefaultHttpParams - Set parameter http.protocol.cookie-policy = default
 DEBUG o.a.commons.httpclient.params.DefaultHttpParams - Set parameter http.protocol.element-charset = US-ASCII
 DEBUG o.a.commons.httpclient.params.DefaultHttpParams - Set parameter http.protocol.content-charset = ISO-8859-1
 DEBUG o.a.commons.httpclient.params.DefaultHttpParams - Set parameter http.method.retry-handler = org.apache.commons.httpclient.DefaultHttpMethodRetryHandler@1623b78d
 DEBUG o.a.commons.httpclient.params.DefaultHttpParams - Set parameter http.dateparser.patterns = [EEE, dd MMM yyyy HH:mm:ss zzz, EEEE, dd-MMM-yy HH:mm:ss zzz, EEE MMM d HH:mm:ss yyyy, EEE, dd-MMM-yyyy HH:mm:ss z, EEE, dd-MMM-yyyy HH-mm-ss z, EEE, dd MMM yy HH:mm:ss z, EEE dd-MMM-yyyy HH:mm:ss z, EEE dd MMM yyyy HH:mm:ss z, EEE dd-MMM-yyyy HH-mm-ss z, EEE dd-MMM-yy HH:mm:ss z, EEE dd MMM yy HH:mm:ss z, EEE,dd-MMM-yy HH:mm:ss z, EEE,dd-MMM-yyyy HH:mm:ss z, EEE, dd-MM-yyyy HH:mm:ss z]
 DEBUG o.a.commons.httpclient.params.DefaultHttpParams - Set parameter http.method.retry-handler = org.apache.commons.httpclient.DefaultHttpMethodRetryHandler@59474f18
 DEBUG o.a.commons.httpclient.params.DefaultHttpParams - Set parameter http.protocol.content-charset = UTF-8
 DEBUG org.apache.commons.httpclient.HttpConnection - Open connection to xlapi-es.test.etcsd.cn:80
 DEBUG httpclient.wire.header - >> "POST /xl-api/common/gateway HTTP/1.1[
][
]"
 DEBUG org.apache.commons.httpclient.HttpMethodBase - Adding Host request header
 DEBUG org.apache.commons.httpclient.HttpMethodBase - Default charset used: UTF-8
 DEBUG org.apache.commons.httpclient.HttpMethodBase - Default charset used: UTF-8
 DEBUG httpclient.wire.header - >> "User-Agent: Jakarta Commons-HttpClient/3.1[
][
]"
 DEBUG httpclient.wire.header - >> "Host: xlapi-es.test.etcsd.cn[
][
]"
 DEBUG httpclient.wire.header - >> "Content-Length: 596[
][
]"
 DEBUG httpclient.wire.header - >> "Content-Type: application/x-www-form-urlencoded[
][
]"
 DEBUG httpclient.wire.header - >> "[
][
]"
 DEBUG httpclient.wire.content - >> "versions=1.0&data=%7B%22waste_sn%22%3A%221584006449329%22%2C%22biz_id%22%3A%22etc.dc.order.query%22%2C%22params%22%3A%7B%22plate_no%22%3A%22%E9%B2%81AA4040%22%2C%22mobile%22%3A%2218768468011%22%7D%7D&sign=Xna2z%2FlzrnCArkrp%2BaY3RVEzlo1rKyGlaS0P1%2FMZyXSir2efTq1sGap3EI4HHdd5%2BXiUdeF0s9fIvM%2Bvx3UtqxKTRKothBG%2BLRdjK5JAlTPBHlHZdTxykOgkkqRVCVEpD2fwzPteqiEWk2LK9inkFL9ZAyqfWjjJw%2FF2gWZ26TtDJbvHgCeATZ%2Boh7%2B6sK6JoyK%2B8g5VhHhMdWiCtu9ttwbEZbcElnG9qU82qt99uDa%2FkVlKPwdTO34cnRa2SxmLVZ30ZlRSXw32nsHVLQ6LrJIFibNi8yKneffUn3QiXoxvtXZjGVJ58CDVe83tzt73%2FQJjkamdGbBWDFI%2B%2FWavdg%3D%3D&appid=ALITEST1"
 DEBUG o.a.c.httpclient.methods.EntityEnclosingMethod - Request body sent
 DEBUG httpclient.wire.header - << "HTTP/1.1 200 OK[
][
]"
 DEBUG httpclient.wire.header - << "HTTP/1.1 200 OK[
][
]"
 DEBUG httpclient.wire.header - << "Content-Length: 415[
][
]"
 DEBUG httpclient.wire.header - << "Content-Type: application/json;charset=utf-8[
][
]"
 DEBUG httpclient.wire.header - << "Date: Thu, 12 Mar 2020 09:47:32 GMT[
][
]"
 DEBUG httpclient.wire.header - << "Server: Apache-Coyote/1.1[
][
]"
 DEBUG httpclient.wire.header - << "[
][
]"
 DEBUG httpclient.wire.content - << "{"response":{"code":"200002","message":"[0xe7][0xb3][0xbb][0xe7][0xbb][0x9f][0xe5][0x93][0x8d][0xe5][0xba][0x94][0xe5][0xbc][0x82][0xe5][0xb8][0xb8]"},"sign":"fZnWq08G5YRM/SMRLEhrey0EhZzdqdHoInVYI2c5O0wXoDRwWkmFSD1yl6bmsoqh/4fw+uXX06LxI0fNjd9sEaAny5lE7xwCGXu07GpdWTsM7OSRmWfpg5/PlPJAh5uoHpdh0G91qxfVcx/t/XMQ06jmraZUWWJz1NFh/scKvL8+qJ8RcaDleI9znDheES6XOwTimAtx/XR3ou1ozqgQC9wqOt9fCk91+Nc48eFbOSDii1NtXIOSwmCqMUAvMXSf7LMVnGlvLW5xGGc2eZ91CawQox7MI/nJD9zYj5Na/wtDwrxmgyK6Xt3GkK8tEhlcbnee1G9Ul2lsw8vMYVOkLw=="}"
 DEBUG org.apache.commons.httpclient.HttpMethodBase - Resorting to protocol version default close connection policy
 DEBUG org.apache.commons.httpclient.HttpMethodBase - Should NOT close connection, using HTTP/1.1
 DEBUG org.apache.commons.httpclient.HttpConnection - Releasing connection back to connection manager.

工具类:

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.httpclient.params.HttpMethodParams;

import lombok.CustomLog;


/**
 * @author zxg
 *
 * 依赖:<br>
 * commons-httpclient:commons-httpclient:3.1.0.redhat-7
 */
@CustomLog
public class HttpUtils {

    private static final String DEFAULT_CHARSET = "UTF-8";
    private static final boolean RETRY_ENABLED = false;
    private static final int RETRY_COUNT = 3;
    private static final String APPLICATION_JSON = "application/json";
    private static final String TEXT_PLAIN = "text/plain";
    private static final String CONTENT_LENGTH = "content-length";
    
    private static final String RN = System.getProperty("line.separator");

    private HttpUtils() {
        throw new AssertionError();
    }
    
    void xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0(){}
    
    /**
     * 获取文件
     * @param uri
     * @param filePath
     */
    public static void getF(String uri, String filePath) {
        getF(uri, filePath, null);
    }
    
    /**
     * 获取文件
     * @param uri
     * @param filePath
     * @param bar 下载进度句柄
     */
    public static void getF(String uri, String filePath, ProgressBar bar) {
        FileOutputStream fos = null;
        InputStream is = null;
        File file = new File(filePath);
        HttpClient client = new HttpClient();
        GetMethod method = null;
        try {
            method = new GetMethod(uri);

            method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
                    new DefaultHttpMethodRetryHandler(RETRY_COUNT, RETRY_ENABLED));

            int statusCode = client.executeMethod(method);

            if (statusCode != HttpStatus.SC_OK) {
                log.debug("Method failed: " + method.getStatusLine());
            }

            fos = new FileOutputStream(file);
            if(bar != null) {
                org.apache.commons.httpclient.Header responseHeader = method.getResponseHeader(CONTENT_LENGTH);
                long byteMax = -1;
                if (responseHeader != null) {
                    byteMax = Long.valueOf(responseHeader.getValue());
                }
                bar.init(byteMax);
            }
            is = method.getResponseBodyAsStream();
            byte[] b = new byte[1024];
            int l;
            while ((l = is.read(b)) != -1) {
                if(bar != null) {
                    bar.setStepSize(l);
                }
                fos.write(b, 0, l);
            }

        } catch (HttpException e) {
            log.debug("Fatal protocol violation: [" + uri + "]", e);
        } catch (IOException e) {
            log.debug("Fatal transport error: [" + uri + "]", e);
        } catch (IllegalArgumentException e) {
            log.debug("Illegal argument error: [" + uri + "]", e);
        } catch (IllegalStateException e) {
            log.debug("Illegal state error: [" + uri + "]", e);
        } finally {
            if (method != null) {
                method.releaseConnection();
            }
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException ignore) {
                }
            }
            if (is != null) {
                try {
                    is.close();
                } catch (IOException ignore) {
                }
            }
        }
    }

    void xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx1(){}
    
    /**
     * 获取文本数据 (default charset of response body is UTF-8)
     * 
     * @param uri
     * @return
     */
    public static String getD(String uri) {
        return HttpUtils.getD(uri, null, null);
    }

    /**
     * 获取文本数据(指定响应编码)
     * 
     * @param uri
     * @param responseCharset
     * @Param bar 下载进度句柄 
     * @return
     */
    public static String getD(String uri, String responseCharset, ProgressBar bar) {
        String result = null;
        BufferedReader br = null;
        HttpClient client = new HttpClient();
        GetMethod method = null;
        try {
            method = new GetMethod(uri);

            method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
                    new DefaultHttpMethodRetryHandler(RETRY_COUNT, RETRY_ENABLED));

            int statusCode = client.executeMethod(method);

            if (statusCode != HttpStatus.SC_OK) {
                log.debug("Method failed: " + method.getStatusLine());
            }
            if(bar != null) {
                org.apache.commons.httpclient.Header responseHeader = method.getResponseHeader(CONTENT_LENGTH);
                long byteMax = -1;
                if (responseHeader != null) {
                    byteMax = Long.valueOf(responseHeader.getValue());
                }
                bar.init(byteMax);
            }
            InputStream is = method.getResponseBodyAsStream();
            if (responseCharset == null) {
                responseCharset = DEFAULT_CHARSET;
            }
            InputStreamReader isr = new InputStreamReader(is, responseCharset);
            br = new BufferedReader(isr);
            StringBuffer sb = new StringBuffer();
            String l;
            while ((l = br.readLine()) != null) {
                if(bar != null) {
                    bar.setStepSize(l.getBytes(responseCharset).length);
                }
                sb.append(l);
                sb.append(RN);
            }
            result = sb.toString();
        } catch (HttpException e) {
            log.debug("Fatal protocol violation: [" + uri + "]", e);
        } catch (IOException e) {
            log.debug("Fatal transport error: [" + uri + "]", e);
        } catch (IllegalArgumentException e) {
            log.debug("Illegal argument error: [" + uri + "]", e);
        } catch (IllegalStateException e) {
            log.debug("Illegal state error: [" + uri + "]", e);
        } finally {
            if (method != null) {
                method.releaseConnection();
            }
            if (br != null) {
                try {
                    br.close();
                } catch (IOException ignore) {
                }
            }
        }
        return result;
    }
    
    void xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx2(){}

    /**
     * 提交表单(default charset of response body is UTF-8)
     * 
     * @param uri
     * @param params
     * @return
     */
    public static String postF(String uri, List<Parameter> params) {
        return HttpUtils.postF(uri, params, null);
    }
    
    /**
     * 提交表单,指定请求头(default charset of response body is UTF-8)
     * 
     * @param uri
     * @param params
     * @param headers
     * @return
     */
    public static String postF(String uri, List<Parameter> params, List<Header> headers) {
        return HttpUtils.postF(uri, params, headers, null, null);
    }

    /**
     * 提交表单,指定请求头,指定响应编码
     * 
     * @param uri
     * @param params
     * @param headers
     * @param responseCharset
     * @return
     */
    public static String postF(String uri, List<Parameter> params, List<Header> headers, String responseCharset, ProgressBar bar) {
        String result = null;
        BufferedReader br = null;
        HttpClient client = new HttpClient();
        PostMethod method = null;

        try {
            method = new PostMethod(uri);

            method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
                    new DefaultHttpMethodRetryHandler(RETRY_COUNT, RETRY_ENABLED));
            method.getParams().setContentCharset(DEFAULT_CHARSET);
            if (params != null) {
                for (Parameter param : params) {
                    method.addParameter(param.getKey(), param.getValue());
                }
            }
            int statusCode = client.executeMethod(method);

            if (statusCode != HttpStatus.SC_OK) {
                log.debug("Method failed: " + method.getStatusLine());
            }
            if(bar != null) {
                org.apache.commons.httpclient.Header responseHeader = method.getResponseHeader(CONTENT_LENGTH);
                long byteMax = -1;
                if (responseHeader != null) {
                    byteMax = Long.valueOf(responseHeader.getValue());
                }
                bar.init(byteMax);
            }
            InputStream is = method.getResponseBodyAsStream();
            if (responseCharset == null) {
                responseCharset = DEFAULT_CHARSET;
            }
            InputStreamReader isr = new InputStreamReader(is, responseCharset);
            br = new BufferedReader(isr);
            StringBuffer sb = new StringBuffer();
            String l;
            while ((l = br.readLine()) != null) {
                if(bar != null) {
                    bar.setStepSize(l.getBytes(responseCharset).length);
                }
                sb.append(l);
                sb.append(RN);
            }
            result = sb.toString();

        } catch (HttpException e) {
            log.debug("Fatal protocol violation: [" + uri + "]", e);
        } catch (IOException e) {
            log.debug("Fatal transport error: [" + uri + "]", e);
        } catch (IllegalArgumentException e) {
            log.debug("Illegal argument error: [" + uri + "]", e);
        } catch (IllegalStateException e) {
            log.debug("Illegal state error: [" + uri + "]", e);
        } finally {
            if (method != null) {
                method.releaseConnection();
            }
            if (br != null) {
                try {
                    br.close();
                } catch (IOException ignore) {
                }
            }
        }
        return result;
    }

    
    void xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx3(){}
    
    /**
     * 提交数据(default charset of response body is UTF-8)
     * 
     * @param uri
     * @param content
     * @return
     */
    public static String postD(String uri, Content content) {
        return HttpUtils.postD(uri, content, null);
    }
    
    /**
     * 提交数据,指定请求头(default charset of response body is UTF-8)
     * 
     * @param uri
     * @param content
     * @param headers
     * @return
     */
    public static String postD(String uri, Content content, List<Header> headers) {
        return HttpUtils.postD(uri, content, headers, null, null);
    }

    /**
     * 提交数据,指定请求头,指定响应编码
     * 
     * @param uri
     * @param content
     * @param headers
     * @param responseCharset
     * @return
     */
    public static String postD(String uri, Content content, List<Header> headers, String responseCharset, ProgressBar bar) {
        String result = null;
        BufferedReader br = null;
        HttpClient client = new HttpClient();
        PostMethod method = null;

        try {
            method = new PostMethod(uri);
            if (headers != null) {
                for (Header header : headers) {
                    method.addRequestHeader(header.getKey(), header.getValue());
                }
            }
            method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
                    new DefaultHttpMethodRetryHandler(RETRY_COUNT, RETRY_ENABLED));
            StringRequestEntity sre = new StringRequestEntity(content.getContent(), content.getContentType(),
                    content.getContentCharset());
            method.setRequestEntity(sre);

            int statusCode = client.executeMethod(method);

            if (statusCode != HttpStatus.SC_OK) {
                log.debug("Method failed: " + method.getStatusLine());
            }

            if (responseCharset == null) {
                responseCharset = DEFAULT_CHARSET;
            }
            if(bar != null) {
                org.apache.commons.httpclient.Header responseHeader = method.getResponseHeader(CONTENT_LENGTH);
                long byteMax = -1;
                if (responseHeader != null) {
                    byteMax = Long.valueOf(responseHeader.getValue());
                }
                bar.init(byteMax);
            }
            InputStream is = method.getResponseBodyAsStream();
            InputStreamReader isr = new InputStreamReader(is, responseCharset);
            br = new BufferedReader(isr);
            StringBuffer sb = new StringBuffer();
            String l;
            while ((l = br.readLine()) != null) {
                if(bar != null) {
                    bar.setStepSize(l.getBytes(responseCharset).length);
                }
                sb.append(l);
                sb.append(RN);
            }
            result = sb.toString();

        } catch (HttpException e) {
            log.debug("Fatal protocol violation: [" + uri + "]", e);
        } catch (IOException e) {
            log.debug("Fatal transport error: [" + uri + "]", e);
        } catch (IllegalArgumentException e) {
            log.debug("Illegal argument error: [" + uri + "]", e);
        } catch (IllegalStateException e) {
            log.debug("Illegal state error: [" + uri + "]", e);
        } finally {
            if (method != null) {
                method.releaseConnection();
            }
            if (br != null) {
                try {
                    br.close();
                } catch (IOException ignore) {
                }
            }
        }
        return result;
    }
    
    void xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx4(){}
    
    /**
     * 上传时,保存到服务器用
     * 
     * @param fileToServer
     * @param fileFromClient
     */
    public static void saveF(File fileToServer, File fileFromClient) {
        saveF(fileToServer, fileFromClient, null);
    }
    
    /**
     * 上传时,保存到服务器用 
     * 
     * @param fileToServer
     * @param fileFromClient
     * @param bar 进度条句柄 
     * @see org.springframework.web.multipart.MultipartFile.transferTo(File dest)
     */
    public static void saveF(File fileToServer, File fileFromClient, ProgressBar bar) {
        InputStream in = null;
        OutputStream out = null;
        try {
            if(bar != null) {
                bar.init(fileFromClient.length());
            }
            byte[] buffer = new byte[4098];
            in = new BufferedInputStream(new FileInputStream(fileFromClient));
            out = new BufferedOutputStream(new FileOutputStream(fileToServer));
            int buffered;
            while ((buffered = in.read(buffer)) != -1) {
                if(bar != null) {
                    bar.setStepSize(buffered);
                }
                out.write(buffer, 0, buffered);
            }
            out.flush();
        } catch (Exception e) {
            throw new RuntimeException("上传文件错误", e);
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
            }
        }
    }
    
    void xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx5(){}
    
    /**
     * @author zxg
     *
     */
    public static class Content {

        private String content, contentType, contentCharset;

        public Content(String content, String contentType, String contentCharset) {
            this.content = content;
            this.contentType = contentType;
            this.contentCharset = contentCharset;
        }

        public String getContent() {
            return content;
        }

        public String getContentType() {
            return contentType;
        }

        public String getContentCharset() {
            return contentCharset;
        }

        /**
         * 获取json类型 Content
         * 
         * @param jsontext
         * @return
         */
        public static Content json(String jsontext) {
            return new Content(jsontext, APPLICATION_JSON, DEFAULT_CHARSET);
        }

        /**
         * 获取text类型 Content
         * 
         * @param plaintext
         * @return
         */
        public static Content text(String plaintext) {
            return new Content(plaintext, TEXT_PLAIN, DEFAULT_CHARSET);
        }
    }
    
    /**
     * @author zxg
     *
     */
    public static class Parameter {
        private String key, value;

        public Parameter(String key, String value) {
            this.key = key;
            this.value = value;
        }

        public String getKey() {
            return key;
        }

        public String getValue() {
            return value;
        }

        /**
         * 将 get 形式的参数进行转换<br>
         * k1=v1&k2=v2&k3=&k4=v4
         * 
         * @param getStr
         * @return
         */
        public static List<Parameter> fromGet(String getStr) {
            List<Parameter> list = new ArrayList<Parameter>();
            if (getStr == null) {
                return list;
            }
            try {
                String[] params = URLDecoder.decode(getStr, "utf-8").split("&");
                for (String param : params) {
                    String[] split = param.split("=");
                    if (split.length == 1) {
                        list.add(new Parameter(split[0], ""));
                    } else if (split.length == 2) {
                        list.add(new Parameter(split[0], split[1]));
                    }
                }
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException("不支持的编码");
            }
            return list;
        }
    }

    /**
     * @author zxg
     *
     */
    public static class Header {
        private String key, value;

        public Header(String key, String value) {
            this.key = key;
            this.value = value;
        }

        public String getKey() {
            return key;
        }

        public String getValue() {
            return value;
        }
    }
    
    /**
     * 进度条,上传和下载
     * 
     * @author zxg
     *
     */
    public static class ProgressBar {

        private boolean download;

        private volatile boolean started = false;
        private volatile boolean ended = false;

        private volatile long start;
        private volatile long end;

        private volatile long byteBuffered;
        
        private boolean byteMaxUnknown = false;
        
        private long byteMax;
        private long byteSnapshot;
        private long bps;

        private final Timer timer = new Timer();
        private final TimerTask timerTask = new TimerTask() {

            @Override
            public void run() {
                if (ended) {
                    timer.cancel();
                    return;
                }
                if (byteBuffered > byteSnapshot) {
                    bps = byteBuffered - byteSnapshot;
                } else {
                    bps = 0;
                }
                byteSnapshot = byteBuffered;
            }

        };

        /**
         * @param byteMax 总字节数 
         * @param download true 下载 , false 上传
         */
        public ProgressBar(boolean download) {
            this.download = download;
        }

        /**
         * 初始化最大字节数 
         * @param byteMax
         */
        public void init(long byteMax) {
            if(byteMax < 0) {
                byteMaxUnknown = true;
            }
            this.byteMax = byteMax;
            timer.schedule(timerTask, 0, 1000);
        }
        
        /**
         * 
         * @param stepSize
         */
        public void setStepSize(long stepSize) {
            if (ended) {
                return;
            }
            if (!started) {
                started = true;
                start = System.currentTimeMillis();
            }
            if (byteMaxUnknown || byteBuffered + stepSize < byteMax) {
                byteBuffered += stepSize;
            } else {
                byteBuffered = byteMax;
                ended = true;
                end = System.currentTimeMillis();
            }
        }

        /**
         * 获取及时速度 <br>
         * 例如 99.10 KB/s
         * @return
         */
        public String getSpeed() {

            if (ended) {
                return "0B";
            }
            return formatSpeed(bps);
        }

        /**
         * 获取平均速度<br> 
         * 例如 100.00 KB/s
         * @return
         */
        public String getAverageSpeed() {
            long elapse;
            if (ended) {
                elapse = end - start;
            } else {
                elapse = System.currentTimeMillis() - start;
            }
            long speed = byteBuffered / (elapse / 1000);
            return formatSpeed(speed);
        }

        /**
         * 获取百分比进度<br>
         * 例如 10%
         * @return
         */
        public String getRatio() {
            if(byteMaxUnknown) {
                return "未知";
            } else if(ended) {
                return "100%";
            } else if(byteMax <= 0) {
                return "0%";
            } else {
                return String.format("%.1f%%", (byteBuffered * 100) / (byteMax * 1.0));
            }
        }

        /**
         * 获取预计剩余时间单位<br>
         * 例如 20s
         * @return
         */
        public String getRemainTime() {
            if(byteMaxUnknown) {
                return "未知";
            } else if (ended) {
                return "0s";
            } else if (bps > 0) {
                return (byteMax - byteBuffered) / bps + "s";
            } else {
                return "未知";
            }
        }

        /**
         * 获取已消耗时间秒<br>
         * 例如 10s
         * @return
         */
        public String getElapsedTime() {
            if (ended) {
                return (end - start) / 1000 + "s";
            } else if (started) {
                return (System.currentTimeMillis() - start) / 1000 + "s";
            } else {
                return "0s";
            }
        }

        /**
         * 获取剩余字节数<br>
         * 例如 22222B
         * @return
         */
        public String getRemainByte() {
            if(byteMaxUnknown) {
                return "未知";
            } else if (ended) {
                return "0B";
            } else {
                return (byteMax - byteBuffered) + "B";
            }
        }

        /**
         * 概要信息
         * @return
         */
        public String getInfo() {
            String title = download ? "下载" : "上传";
            String speed = getSpeed();
            String ratio = getRatio();
            String remainTime = getRemainTime();
            String elapsedTime = getElapsedTime();
            return title + "速度:" + speed + ", 进度:" + ratio + ", 剩余时间:" + remainTime + ", 已耗时:" + elapsedTime;
        }
        
        /**
         * 显示 Mb/S (保留两位) ,否则显示 KB/S(保留两位) ,否则显示 B/S
         * 
         * @param bps
         * @return
         */
        private String formatSpeed(long bps) {
            String result;
            long mb = 1 << 20;
            long kb = 1 << 10;
            if (bps >= mb) {
                result = String.format("%.2f MB/s", bps / (mb * 1.0));
            } else if (bps >= kb) {
                result = String.format("%.2f KB/s", bps / (kb * 1.0));
            } else {
                result = String.format("%.0f B/s", bps / 1.0);
            }
            return result;
        }
    }
}
原文地址:https://www.cnblogs.com/zno2/p/5718500.html