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[\r][\n]" 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[\r][\n]" DEBUG httpclient.wire.header - >> "Host: xlapi-es.test.etcsd.cn[\r][\n]" DEBUG httpclient.wire.header - >> "Content-Length: 596[\r][\n]" DEBUG httpclient.wire.header - >> "Content-Type: application/x-www-form-urlencoded[\r][\n]" DEBUG httpclient.wire.header - >> "[\r][\n]" 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[\r][\n]" DEBUG httpclient.wire.header - << "HTTP/1.1 200 OK[\r][\n]" DEBUG httpclient.wire.header - << "Content-Length: 415[\r][\n]" DEBUG httpclient.wire.header - << "Content-Type: application/json;charset=utf-8[\r][\n]" DEBUG httpclient.wire.header - << "Date: Thu, 12 Mar 2020 09:47:32 GMT[\r][\n]" DEBUG httpclient.wire.header - << "Server: Apache-Coyote/1.1[\r][\n]" DEBUG httpclient.wire.header - << "[\r][\n]" 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; } } }