一、依赖项

Maven

<dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>2.9.0</version>
</dependency>
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.22</version>
</dependency>
<dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.13</version>
</dependency>
<dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpmime</artifactId><version>4.5.13</version>
</dependency>
<dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-api</artifactId><version>2.17.2</version>
</dependency>
<dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.17.2</version>
</dependency>

第三方工具

【HttpUtil】基于HttpClient的Http工具类

二、源代码

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import lombok.Getter;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.content.ByteArrayBody;
import org.apache.http.entity.mime.content.ContentBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.util.EntityUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;/*** @author NXY666*/
public class ImgtuUtil {static final String IMGTU_USER_NAME = "**你的用户名**";static final String IMGTU_PASSWORD = "**你的密码**";static final Logger log = LogManager.getLogger(ImgtuUtil.class);static final private String IMGTU_INIT_URL = "https://imgtu.com/init";static final private String IMGTU_LOGIN_URL = "https://imgtu.com/login";static final private String IMGTU_OPERATE_URL = "https://imgtu.com/json";static final private Pattern SESSION_ID_PATTERN = Pattern.compile("PHPSESSID=([^;]*); path=/; HttpOnly");static final private Pattern AUTH_TOKEN_PATTERN = Pattern.compile("PF\\.obj\\.config\\.auth_token = \"([0-9a-f]{40})\";");static final private Pattern KEEP_LOGIN_PATTERN = Pattern.compile("KEEP_LOGIN=([^;]*);");static final private long INIT_VALID_DURATION = 15L * 60 * 1000;static final private long LOGIN_VALID_DURATION = 30L * 24 * 60 * 60 * 1000;@Getterstatic private String sessionId;@Getterstatic private String authToken;@Getterstatic private String keepLogin;@Getterstatic private long initTimestamp = 0;@Getterstatic private long loginTimestamp = 0;public static Boolean initSession() {return initSession(false);}public static Boolean initSession(boolean forceAction) {if (!forceAction && !isSessionIdExpired()) {log.info("【初始化】成功:会话有效期内,无需重新初始化。");return null;}synchronized (ImgtuUtil.class) {// 初始化sessionId = null;authToken = null;// 请求登录页String httpRawString;CloseableHttpResponse httpResponse;try {httpResponse = HttpUtil.get(IMGTU_INIT_URL, new HashMap<>(0), new HashMap<>(0));HttpEntity httpEntity = httpResponse.getEntity();httpRawString = EntityUtils.toString(httpEntity);} catch (IOException e) {log.error("【初始化】失败:请求页面失败。({})", e.getLocalizedMessage());e.printStackTrace();return false;}// 获取SessionIdHeader[] responseHeaders = httpResponse.getAllHeaders();for (Header header : responseHeaders) {if ("Set-Cookie".equalsIgnoreCase(header.getName())) {String cookies = header.getValue();Matcher matcher = SESSION_ID_PATTERN.matcher(cookies);if (matcher.find(0)) {sessionId = matcher.group(1);}}}if (sessionId == null) {log.error("【初始化】失败:获取SessionId失败。");return false;}// 获取AuthTokenMatcher matcher = AUTH_TOKEN_PATTERN.matcher(httpRawString);if (matcher.find(0)) {authToken = matcher.group(1);} else {log.error("【初始化】失败:获取AuthToken失败。");return false;}log.info("【初始化】√ SessionId:" + sessionId);log.info("【初始化】√ AuthToken:" + authToken);initTimestamp = System.currentTimeMillis();return true;}}public static Boolean login() throws IOException {return login(false);}public static Boolean login(boolean forceAction) throws IOException {if (!forceAction && !isLoginExpired()) {log.info("【登录】成功:登录状态有效期内,无需重新登录。");return null;}synchronized (ImgtuUtil.class) {// 初始化会话if (isSessionIdExpired()) {Boolean b = initSession();if (!(b == null || b)) {log.error("【登录】失败:初始化会话受阻。");}}// 设置请求头Map<String, String> headers = new HashMap<>(3);headers.put("cookie", "PHPSESSID=" + sessionId + ";");headers.put("content-type", "application/x-www-form-urlencoded");headers.put("connection", "keep-alive");CloseableHttpResponse httpResponse = HttpUtil.post(IMGTU_LOGIN_URL, new HashMap<>(0), headers, "login-subject=" + IMGTU_USER_NAME + "&password=" + IMGTU_PASSWORD + "&auth_token=" + authToken);Header[] responseHeaders = httpResponse.getAllHeaders();for (Header header : responseHeaders) {if ("Set-Cookie".equalsIgnoreCase(header.getName())) {String cookies = header.getValue();Matcher matcher = KEEP_LOGIN_PATTERN.matcher(cookies);if (matcher.find(0)) {keepLogin = matcher.group(1);}}}if (keepLogin != null) {loginTimestamp = System.currentTimeMillis();log.info("【登录】√ KeepLogin:" + keepLogin);return true;} else {log.error("【登录】× StatusCode:" + httpResponse.getStatusLine().getStatusCode());return false;}}}public static boolean ensureLogin() throws IOException {Boolean loginRes = login();if (loginRes == null) {Boolean initRes = initSession();return initRes == null || initRes;} else {return loginRes;}}public static JsonObject upload(byte[] bytes, String fileName, ContentType fileType) throws IOException {log.info("-------->>>> 图床·上传 <<<<--------");if (!ensureLogin()) {log.error("【上传】失败:服务不可用。");return null;}Map<String, String> headers = new HashMap<>(3);headers.put("Cookie", "PHPSESSID=" + sessionId + "; KEEP_LOGIN=" + keepLogin);headers.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.84 Safari/537.36");headers.put("Connection", "keep-alive");try {Map<String, ContentBody> params = new HashMap<>(6);params.put("source", new ByteArrayBody(bytes, fileType, fileName));params.put("type", new StringBody("file", ContentType.MULTIPART_FORM_DATA));params.put("action", new StringBody("upload", ContentType.MULTIPART_FORM_DATA));params.put("timestamp", new StringBody(Long.toString(System.currentTimeMillis()), ContentType.MULTIPART_FORM_DATA));params.put("auth_token", new StringBody(authToken, ContentType.MULTIPART_FORM_DATA));params.put("nsfw", new StringBody("0", ContentType.MULTIPART_FORM_DATA));CloseableHttpResponse httpResponse = HttpUtil.multipart(IMGTU_OPERATE_URL, new HashMap<>(0), headers, params);String httpRawString = EntityUtils.toString(httpResponse.getEntity());log.info("【上传】成功:上传成功!");return new Gson().fromJson(httpRawString, JsonObject.class);} catch (IOException e) {log.error("【上传】失败:{}", e.getLocalizedMessage());e.printStackTrace();return null;}}public static JsonObject delete(String deleteId) throws IOException {log.info("-------->>>> 图床·删除 <<<<--------");if (!ensureLogin()) {log.error("【删除】失败:服务不可用。");return null;}Map<String, String> headers = new HashMap<>(3);headers.put("Cookie", "PHPSESSID=" + sessionId + "; KEEP_LOGIN=" + keepLogin);headers.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.84 Safari/537.36");headers.put("Connection", "keep-alive");try {Map<String, ContentBody> params = new HashMap<>(5);params.put("auth_token", new StringBody(authToken, ContentType.MULTIPART_FORM_DATA));params.put("action", new StringBody("delete", ContentType.MULTIPART_FORM_DATA));params.put("single", new StringBody("true", ContentType.MULTIPART_FORM_DATA));params.put("delete", new StringBody("image", ContentType.MULTIPART_FORM_DATA));params.put("deleting[id]", new StringBody(deleteId, ContentType.MULTIPART_FORM_DATA));CloseableHttpResponse httpResponse = HttpUtil.multipart(IMGTU_OPERATE_URL, new HashMap<>(0), headers, params);String httpRawString = EntityUtils.toString(httpResponse.getEntity());log.info("【删除】成功:删除成功!");return new Gson().fromJson(httpRawString, JsonObject.class);} catch (IOException e) {log.error("【删除】失败:{}", e.getLocalizedMessage());e.printStackTrace();return null;}}static boolean isSessionIdExpired() {return initTimestamp + INIT_VALID_DURATION < System.currentTimeMillis();}static boolean isLoginExpired() {return loginTimestamp + LOGIN_VALID_DURATION < System.currentTimeMillis();}
}

三、使用方法

  • 使用前,请先注册一个图床帐号,然后将 用户名密码 分别填写在 IMGTU_USER_NAMEIMGTU_PASSWORD 两个变量的初始值上。
  • 使用时,可直接调用 uploaddelete 方法,会自动判断是否需要 初始化会话重新登录
  • 如果你需要保证更快的文件上传,可定期手动调用 initSession(true)
  • 默认 PHPSESSID 有效期为15分钟, KeepLogin 有效期为30天,若出现报错可以酌情减少间隔。
  • 因图床限制,若使用VPN代理可能会导致请求被拒绝。

四、基本流程

  1. 请求 https://imgtu.com/init ,从返回的 404页面 中获取 PHPSESSIDtoken
  2. 请求 https://imgtu.com/login ,完成 登录
  3. 使用 https://imgtu.com/json 进行 上传删除 操作。

【ImgtuUtil】路过图床基础 Java 工具类(支持登录、上传、删除图片等操作)相关推荐

  1. 阿里云视频点播服务Vod工具类——实现视频上传、删除、播放

    阿里云视频点播服务Vod工具类--实现视频上传.删除.播放 阿里云视频点播服务Vod工具类 maven依赖 工具类实现 工具类的测试 获取视频 1. 获取单个视频的播放地址和ID: 2. 获取所有视频 ...

  2. java 工具类实现Base64二维码图片识别

    工具类已经实现Base64二维码图片识别和路径图片识别 所需maven依赖 <!--二维码生成和解析相关的jar包[生成][解析]-->     <dependency>   ...

  3. tp6腾讯云、七牛云对象存储的工具类以及异步上传

    composer安装 composer require lorine/oss-utils 代码: use Lorine\OssUtils\OssService;$config = ['ak' => ...

  4. 抽了几天用Flex写了个上传小工具,支持批量上传,支持配置

    2019独角兽企业重金招聘Python工程师标准>>> 抽了几天用Flex写了个上传小插件,支持批量上传,想实现MD5校验的但没想到好的方法 欢迎大家提意见 源码地址 http:// ...

  5. java分布式实现图片上传到图片服务器

    java分布式实现图片上传到图片服务器 操作步骤 第一步 第二步 第三步 第四步 第五步 第六步 代码实现 第七步 JS代码 大功告成!! 操作步骤 第一步 在页面中的form表单里面增加一个inpu ...

  6. Java 线程 - 基础及工具类 (二)

    Java 并发系列文章 Java 线程 - 并发理论基础(一) Java 线程 - 基础及工具类 (二) Java 线程 - 并发设计模式 (三) Java 线程(二) 通用的线程生命周期 Java ...

  7. JavaSE基础:Arrays工具类

    Java工具类: Arrays Arrays类是数组的操作类,定义在java.util包中,主要功能是实现数组元素的查找/数组内容的充填/排序等功能 1.排序数组的sort方法 重点:对数组元素进行排 ...

  8. 干货:排名前 16 的 Java 工具类!

    2019独角兽企业重金招聘Python工程师标准>>> 干货:排名前 16 的 Java 工具类!   在Java中,工具类定义了一组公共方法,这篇文章将介绍Java中使用最频繁及最 ...

  9. 排名前 16 的 Java 工具类

    转载来自微信公众号:Java 技术栈.如有侵权,请联系作者删除!! 在 Java 中,工具类定义了一组公共方法,这篇文章将介绍 Java 中使用最频繁及最通用的 Java 工具类.以下工具类.方法按使 ...

  10. beanutils工具类_16 个超级实用的 Java 工具类!

    在Java中,工具类定义了一组公共方法,这篇文章将介绍Java中使用最频繁及最通用的Java工具类.以下工具类.方法按使用流行度排名,参考数据来源于Github上随机选取的5万个开源项目源码. 一. ...

最新文章

  1. 排序算法的时间复杂度_算法的时间复杂度
  2. 2021年高考英语卷三成绩查询,2021年全国3卷高考外语卷难不难,今年全国3卷高考外语卷难度系数点评...
  3. Android开发中目前流行控件和知识点总结
  4. mysql数据库的服务无法启动_mysql5数据库服务无法启动
  5. dubbo 自定义路由_爱奇艺在 Dubbo 生态下的微服务架构实践
  6. COJ 1079 树上的查询 (离线LCA)
  7. IntelliJ IDEA for CleanCode
  8. 一个VSCode插件实现软妹音程序员鼓励师24小时在线,还能吐槽PM
  9. 串口通信协议之SPI通信协议
  10. matlab模拟滤波器频率响应,怎样求FIR滤波器在任意频率上的频率响应?
  11. SFDC Developer
  12. CRC-16 CCITT
  13. 圆通快递查询电子面单接口对接快递鸟api指南
  14. HALCON数组的删除 三
  15. python迅雷sdk_Python批量创建迅雷任务及创建多个文件
  16. 抑郁症维持期治疗应维持多久?如何管理患者发生停药反应的风险?
  17. ibm的量子计算机技术,IBM实现又一台量子体积64的世界上最强量子计算机!
  18. 致敬博士-博士学位真的那么重要吗
  19. 美国的计算机科学本科哪个好,美国本科,专业排名和综合排名哪个更重要,比如说圣路易斯华盛顿大学、圣母大学的计算机科学专业和伊利诺伊大学、普渡大学的相比选择哪一个?谢谢!...
  20. OA预算报销流程设计

热门文章

  1. shuipFCMS收集2
  2. android自定义进度条图片,Android零基础入门|自定义酷炫进度条
  3. epsfallback_EPS网络CS Fallback技术研究
  4. 前5名:Raspberry Pi龙卷风警告系统,用于物联网开发的4个开放式开发板等
  5. 初学Web:计算机气质个人主页
  6. 教会如何使用WordPress提供在线讲道
  7. 静态工作点稳定方法——原理;分压偏置共射放大电路静态分析、动态分析
  8. idea查看代码行数Statistic
  9. 天眼查、企查查APP的Authorized值和sign值破解思路记载
  10. MySQL之——基本操作汇总