功能
提供异步图片的下载功能,实时返回替换的链接。
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;
import org.jsoup.Connection.Response;
import org.jsoup.Jsoup;
import org.mall.spider.cont.SpiderConstant;
import org.mall.utils.DateUtil;
import org.mall.utils.gson.GsonHelper;
/**
* @description Http协议下载工具(不支持断点续传),每个图片会重试10次
* @author <a href="mailto:fengwuze@kk.com">fengwuze</a>
* @since 2016年9月19日
* @version 1.0.0
*/
public final class HttpDownloadUtils {
private static final Logger logger = Logger.getLogger(HttpDownloadUtils.class);
/**
* 图片命名计数器(保证不重复)
*/
private static AtomicLong imgNameCounter = new AtomicLong(Long.valueOf(DateUtil.format(new Date(), "yyyyMMddHHmmss")));
/**
* 线程池
*/
private static ExecutorService exec = new ThreadPoolExecutor(10, 100, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(),
Executors.defaultThreadFactory());
/**
* 提交下载任务
*
* @param targetUrl
* @param saveDir
* @return String
*/
public static String submitTask(final String targetUrl, final String saveDir, final String subSaveDir) {
final HttpTask task = new HttpTask(targetUrl, saveDir, subSaveDir);
exec.submit(new HttpDownTask(task));
return task.getSubSaveDir();
}
static class HttpDownTask implements Runnable {
private HttpTask task;
public HttpDownTask(HttpTask task) {
this.task = task;
}
@Override
public void run() {
FileOutputStream out = null;
try {
Response rsp = Jsoup.connect(task.getTargetUrl()).timeout(10 * 1000).header("User-Agent", SpiderConstant.UA)
.ignoreContentType(true).execute();
out = new FileOutputStream(task.getSavePath());
IOUtils.write(rsp.bodyAsBytes(), out);
out.flush();
logger.info("down succ, task: " + GsonHelper.toJson(task));
} catch (Exception e) {
if (task.getRetry() <= 10) {
task.setRetry(task.getRetry() + 1);
exec.submit(new HttpDownTask(task));
} else {
logger.error("down fail, task: " + GsonHelper.toJson(task), e);
}
} finally {
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
static class HttpTask {
private String targetUrl;
private String saveDir;
private String subSaveDir;
private String savePath;
private Integer retry = 0;
public HttpTask(String targetUrl, String saveDir, String subSaveDir) {
this.targetUrl = targetUrl;
this.saveDir = saveDir;
this.subSaveDir = subSaveDir;
String suffix = targetUrl.substring(targetUrl.lastIndexOf("."), targetUrl.length());
this.subSaveDir = this.subSaveDir + "/" + imgNameCounter.addAndGet(1) + suffix;
this.savePath = saveDir + this.subSaveDir;
}
public String getSavePath() {
return savePath;
}
public String getTargetUrl() {
return targetUrl;
}
public String getSaveDir() {
return saveDir;
}
public Integer getRetry() {
return retry;
}
public void setRetry(Integer retry) {
this.retry = retry;
}
public String getSubSaveDir() {
return subSaveDir;
}
public void setSubSaveDir(String subSaveDir) {
this.subSaveDir = subSaveDir;
}
}
public static void main(String[] args) {
String subDir = HttpDownloadUtils.submitTask("http://img.zcool.cn/community/03377fb554c721200000158fc8ac222.jpg", "D:\\", "/imgs");
System.out.println(subDir);
}
}