java上传文件限速_java HttpClient 上传限速(避免宽带占用过高)

需求: 因为工作站网络上行带宽过高会影响其他服务的正常使用,所以要限速

HttpClient.java

package com.wuchen.utils;

import com.alibaba.fastjson.JSON;

import com.alibaba.fastjson.JSONObject;

import com.wuchen.constant.Constant;

import com.wuchen.servlet.LimitRateFileBody;

import org.apache.http.HttpEntity;

import org.apache.http.HttpResponse;

import org.apache.http.client.config.RequestConfig;

import org.apache.http.client.methods.HttpGet;

import org.apache.http.client.methods.HttpPost;

import org.apache.http.entity.ContentType;

import org.apache.http.entity.StringEntity;

import org.apache.http.entity.mime.MultipartEntityBuilder;

import org.apache.http.entity.mime.content.FileBody;

import org.apache.http.entity.mime.content.StringBody;

import org.apache.http.impl.client.HttpClientBuilder;

import org.apache.http.util.EntityUtils;

import org.apache.log4j.Logger;

import java.io.File;

import java.net.URI;

import java.nio.charset.Charset;

import java.util.ArrayList;

import java.util.List;

import java.util.Properties;

import java.util.Set;

public class HttpClient {

private static Integer socketTime = null;

private static Integer connectTime = null;

private static Integer connectionRequestTime = null;

private static Logger logger = Logger.getLogger(HttpClient.class);

private static String token = null;

public static JSONObject doPost(JSONObject params, String url) {

if (socketTime == null) {

Properties properties = new PropertiesUtil().readPropertiesFile("application.properties");

socketTime = Integer.valueOf(properties.getProperty("socketTime"));

connectTime = Integer.valueOf(properties.getProperty("connectTime"));

connectionRequestTime = Integer.valueOf(properties.getProperty("connectionRequestTime"));

}

org.apache.http.client.HttpClient httpClient = HttpClientBuilder.create().build();

HttpPost httpPost = new HttpPost(url);

try {

httpPost.setHeader("Content-type", "application/json; charset=utf-8");

httpPost.setHeader("Connection", "Close");

StringEntity entity = new StringEntity(params.toString(), Charset.forName("UTF-8"));

entity.setContentEncoding("UTF-8");

entity.setContentType("application/json");

httpPost.setEntity(entity);

HttpResponse response = httpClient.execute(httpPost);

String resultString = EntityUtils.toString(response.getEntity());

JSONObject rempResult = JSON.parseObject(resultString);

return rempResult;

} catch (Exception e) {

logger.error("error", e);

return null;

}

}

public static JSONObject postFrom(JSONObject params, List paths, String url) {

org.apache.http.client.HttpClient httpClient = HttpClientBuilder.create().build();

try {

HttpPost httpPost = new HttpPost(url);

StringBody comment = new StringBody(params.toString(), ContentType.TEXT_PLAIN);

MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();

for (String filePath : paths) {

multipartEntityBuilder.addPart("file", new FileBody(new File(filePath)));

}

HttpEntity reqEntity = multipartEntityBuilder.addPart("desc", comment).build();

httpPost.setEntity(reqEntity);

HttpResponse response = httpClient.execute(httpPost);

String resultString = EntityUtils.toString(response.getEntity());

JSONObject result = JSON.parseObject(resultString);

return result;

} catch (Exception e) {

logger.error("error", e);

return null;

}

}

public static JSONObject postFromListRate(JSONObject params, List paths, String url) {

org.apache.http.client.HttpClient httpClient = HttpClientBuilder.create().build();

try {

HttpPost httpPost = new HttpPost(url);

StringBody comment = new StringBody(params.toString(), ContentType.TEXT_PLAIN);

MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();

for (String filePath : paths) {

multipartEntityBuilder.addPart("file", new LimitRateFileBody(new File(filePath), params.getInteger(Constant.MAX_RATE)));

}

HttpEntity reqEntity = multipartEntityBuilder.addPart("desc", comment).build();

httpPost.setEntity(reqEntity);

HttpResponse response = httpClient.execute(httpPost);

String resultString = EntityUtils.toString(response.getEntity());

JSONObject result = JSON.parseObject(resultString);

return result;

} catch (Exception e) {

logger.error("error", e);

return null;

}

}

}

004a5d76af9a2d58edb9e2b845dbb666.png

LimitRateBody.java

package com.wuchen.servlet;

import com.wuchen.utils.BandwidthLimiter;

import org.apache.http.entity.ContentType;

import org.apache.http.entity.mime.content.FileBody;

import org.apache.http.util.Args;

import java.io.File;

import java.io.FileInputStream;

import java.io.IOException;

import java.io.OutputStream;

/**

* @author: WangXiang

* @date: 2020/4/28 0028

**/

public class LimitRateFileBody extends FileBody {

private final File file;

private final String filename;

//限速的大小

private int maxRate = 1024;

public LimitRateFileBody(File file, int maxRate) {

this(file, ContentType.DEFAULT_BINARY, file != null ? file.getName() : null);

this.maxRate = maxRate;

}

public LimitRateFileBody(File file) {

this(file, ContentType.DEFAULT_BINARY, file != null ? file.getName() : null);

}

public LimitRateFileBody(File file, ContentType contentType, String filename) {

super(file, contentType, filename);

this.file = file;

this.filename = filename;

}

public LimitRateFileBody(File file, ContentType contentType) {

this(file, contentType, file != null ? file.getName() : null);

}

@Override

public void writeTo(OutputStream out) throws IOException {

Args.notNull(out, "Output stream");

FileInputStream in = new FileInputStream(this.file);

LimitInputStream ls = new LimitInputStream(in, new BandwidthLimiter(this.maxRate));

try {

byte[] tmp = new byte[4096];

int l;

while ((l = ls.read(tmp)) != -1) {

out.write(tmp, 0, l);

}

out.flush();

} finally {

in.close();

}

}

public void setMaxRate(int maxRate) {

this.maxRate = maxRate;

}

}

f1be1980bd23421ef924a3c7d767af19.png

LimitInputStream.java

package com.wuchen.servlet;

import com.wuchen.utils.BandwidthLimiter;

import java.io.FileInputStream;

import java.io.IOException;

import java.io.InputStream;

/**

* 限流文件读取

*

* @author: WangXiang

* @date: 2019/12/20 0020

**/

public class LimitInputStream extends InputStream {

private InputStream inputStream;

private BandwidthLimiter bandwidthLimiter;

public LimitInputStream(InputStream inputStream, BandwidthLimiter bandwidthLimiter) {

this.inputStream = inputStream;

this.bandwidthLimiter = bandwidthLimiter;

}

@Override

public int read(byte[] b, int off, int len) throws IOException {

if (bandwidthLimiter != null) {

bandwidthLimiter.limitNextBytes(len);

}

return inputStream.read(b, off, len);

}

@Override

public int read(byte[] b) throws IOException {

if (bandwidthLimiter != null && b.length > 0) {

bandwidthLimiter.limitNextBytes(b.length);

}

return inputStream.read(b);

}

@Override

public int read() throws IOException {

if (bandwidthLimiter != null) {

bandwidthLimiter.limitNextBytes();

}

return inputStream.read();

}

}

BandwidthLimiter.java

package com.wuchen.utils;

import com.wuchen.service.FileUploadService;

import org.apache.log4j.Logger;

/**

* @author: WangXiang

* @date: 2019/12/20 0020

**/

public class BandwidthLimiter {

private static Logger logger = Logger.getLogger(BandwidthLimiter.class);

//KB代表的字节数

private static final Long KB = 1024L;

//一个chunk的大小,单位byte。设置一个块的大小为1M

private static final Long CHUNK_LENGTH = 1024 * 1024L;

//已经发送/读取的字节数

private int bytesWillBeSentOrReceive = 0;

//上一次接收到字节流的时间戳——单位纳秒

private long lastPieceSentOrReceiveTick = System.nanoTime();

//允许的最大速率,默认为 1024KB/s

private int maxRate = 1024;

//在maxRate的速率下,通过chunk大小的字节流要多少时间(纳秒)

private long timeCostPerChunk = (1000000000L * CHUNK_LENGTH) / (this.maxRate * KB);

public BandwidthLimiter(int maxRate) {

this.setMaxRate(maxRate);

}

//动态调整最大速率

public void setMaxRate(int maxRate) {

if (maxRate < 0) {

throw new IllegalArgumentException("maxRate can not less than 0");

}

this.maxRate = maxRate;

if (maxRate == 0) {

this.timeCostPerChunk = 0;

} else {

this.timeCostPerChunk = (1000000000L * CHUNK_LENGTH) / (this.maxRate * KB);

}

}

public synchronized void limitNextBytes() {

this.limitNextBytes(1);

}

public synchronized void limitNextBytes(int len) {

this.bytesWillBeSentOrReceive += len;

while (this.bytesWillBeSentOrReceive > CHUNK_LENGTH) {

long nowTick = System.nanoTime();

long passTime = nowTick - this.lastPieceSentOrReceiveTick;

long missedTime = this.timeCostPerChunk - passTime;

if (missedTime > 0) {

try {

Thread.sleep(missedTime / 1000000, (int) (missedTime % 1000000));

} catch (InterruptedException e) {

logger.error(e.getMessage(), e);

}

}

this.bytesWillBeSentOrReceive -= CHUNK_LENGTH;

this.lastPieceSentOrReceiveTick = nowTick + (missedTime > 0 ? missedTime : 0);

}

}

}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java后端使用HttpClient库可以发送POST请求,并提交文件流。以下是示例代码: ```java import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.InputStreamEntity; import org.apache.http.impl.client.HttpClients; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; public class HttpClientExample { public static void main(String[] args) throws IOException { HttpClient httpClient = HttpClients.createDefault(); // 创建POST请求 HttpPost httpPost = new HttpPost("http://example.com/upload"); // 读取文件流 File file = new File("path/to/file"); InputStream inputStream = new FileInputStream(file); // 设置请求体为文件流 InputStreamEntity entity = new InputStreamEntity(inputStream); httpPost.setEntity(entity); // 发送请求并获取响应 HttpResponse response = httpClient.execute(httpPost); // 处理响应 HttpEntity responseEntity = response.getEntity(); if (responseEntity != null) { // 处理响应内容 InputStream responseStream = responseEntity.getContent(); // ... } } } ``` 以上代码使用Apache HttpClient库发送POST请求,并将文件流作为请求体。在示例中,我们将文件路径设置为`path/to/file`,你需要将其替换为实际文件的路径。然后,我们可以通过`httpClient.execute(httpPost)`发送请求并获取响应。最后,我们可以从响应中获取响应内容进行处理。 请注意,这只是一个基本示例,你可能需要根据你的实际需求进行适当的修改。另外,你需要在项目中添加Apache HttpClient的依赖。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值