将图片地址转为二进制(博客自定义随机背景图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,但是大家都说原生的不好,就坚持下来了。

写这篇文章参考了很多,比如参考1参考2

posted @   丁少华  阅读(784)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示