将图片地址转为二进制(博客自定义随机背景图API)
背景
最近写博客。
觉得自己的博客毫无生机,想加一些图片。
于是在找了一些三方的随机图片链接
,发现一些问题:
给的些链接不会直接返回图片,
要么是302重定向
要么是返回json
这导致,这个链接无法直接使用在css的background-image: url(xxx)
中。
解决思路
后端代理
1、拿到图片真实地址,
2、并将其转换为二进制返回给前端
HttpHelper.java
package com.dshvv.blogserver.utils;
import com.alibaba.fastjson.JSONObject;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.springframework.stereotype.Component;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
@Component
public class HttpHelper {
/*
* 根据url地址返回json
* */
public JSONObject sendGetReturnJson(String url) throws Exception {
CloseableHttpClient httpClient = HttpClients.createDefault();
// 执行请求
CloseableHttpResponse response = httpClient.execute(new HttpGet(url));
// 获取响应体
HttpEntity entity = response.getEntity();
// 获取响应内容
String contentStr = EntityUtils.toString(entity, "utf-8");
// 关闭连接,释放资源
response.close();
httpClient.close();
return JSONObject.parseObject(contentStr);
}
/*
* 根据url地址返回二进制
* */
public BufferedInputStream sendGetReturnStream(String url) throws Exception {
CloseableHttpClient httpClient = HttpClients.createDefault();
// 执行请求
CloseableHttpResponse response = httpClient.execute(new HttpGet(url));
// 获取响应体
HttpEntity entity = response.getEntity();
// 获取响应内容
byte[] contentByteArray = EntityUtils.toByteArray(entity);
ByteArrayInputStream byteInputStream = new ByteArrayInputStream(contentByteArray);
BufferedInputStream imgStream = new BufferedInputStream(byteInputStream);
// 关闭连接,释放资源
response.close();
httpClient.close();
return imgStream;
}
}
OtherController.js
package com.dshvv.blogserver.controller;
import com.dshvv.blogserver.utils.*;
import io.swagger.annotations.ApiOperation;
import org.junit.platform.commons.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
@RequestMapping
@RestController
public class OtherController {
@Autowired
private HttpHelper httpHelper;
// 随机获取一张二次元图片
@ApiOperation("随机获取一张二次元图片")
@GetMapping(value = {"/img", "/img/{type}"})
public void getImg(HttpServletResponse response, @PathVariable(value = "type", required = false) String type) throws Exception {
String imgApiUrl = "https://api.ixiaowai.cn/api/api.php?return=json";
if (!StringUtils.isBlank(type)) {
if (type.equals("fj")) {
imgApiUrl = "https://api.ixiaowai.cn/gqapi/gqapi.php?return=json";
}
}
// 拿到图片的url
String imgUrl = (String) httpHelper.sendGetReturnJson(imgApiUrl).get("imgurl");
System.out.println(imgUrl);
// 根据图片url拿到二进制流 并返回前端
BufferedInputStream imgStream = httpHelper.sendGetReturnStream(imgUrl);
OutputStream out = response.getOutputStream();
// 读取文件流
int len = 0;
byte[] buffer = new byte[1024 * 10];
while ((len = imgStream.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
out.flush();
out.close();
}
}
遇到的坑
在使用HttpClient时,封装了工具一度存在问题,最后网上排查发现EntityUtils只能使用一次,使用了EntityUtils.toByteArray()方法,上面就不能再使用EntityUtils.toString()。
期间一度准备放弃转听同事@朱杰
的使用原生的http请求工具HttpURLConnection
,但是大家都说原生的不好,就坚持下来了。