java后端调用第三方接口返回图片流给前端的具体代码实现

 更新时间:2024年02月13日 10:17:35   作者:Monameng  
在前后端分离的开发中,经常会遇到需要从后端返回图片流给前端的情况,下面这篇文章主要给大家介绍了关于java后端调用第三方接口返回图片流给前端的具体代码实现,需要的朋友可以参考下

一、背景

有个需求是这样的,客户端直接通过外网访问oss获取图片需要额外付费,考虑到成本问题,修改技术方案为:客户端将请求链接发给后端,后端根据请求做一定的截取或拼接,通过内网调用oss,再将下载下来的图片流返回给前端。

图片流,展现在页面上就是直接返回一张图片在浏览器上。

二、具体代码展示 

前端期望,如果异常,直接把http status返回非200

@Slf4j
@RestController
public class PictureController {
    @Autowired
    private PictureService pictureService;

    @RequestMapping(value = "getPicture")
    public void getPicture(String path, HttpServletResponse resp) {
        boolean picSuccess;
        // 注意:一定要有这步,否则图片显示不出来
        resp.setContentType(MediaType.IMAGE_JPEG_VALUE);
        long start = System.currentTimeMillis();
        try {
            picSuccess = pictureService.getOssPicture(path, resp);
            if (!picSuccess) {
                resp.setStatus(HttpServletResponse.SC_FORBIDDEN);
            }
        } catch (Exception e) {
            resp.setStatus(HttpServletResponse.SC_FORBIDDEN);
            log.error("下载图片失败!!");
        }
        log.info("cmd=/getPicture,param={},cost:{}", path, System.currentTimeMillis() - start);
    }
}
public interface PictureService {
    boolean getOssPicture(String path, HttpServletResponse resp) throws IOException;
}
@Slf4j
@Service
public class PictureServiceImpl implements PictureService {
    
    @Value("${alioss.ak}")
    private String accessKeyId;

    // http://*********.aliyuncs.com
    @Value("${url.prefix}")
    private String urlPrefix;

    @Value("${oss.connect.time:3000}")
    private int ossConnectTime;

    @Override
    public boolean getOssPicture(String path, HttpServletResponse resp) throws IOException {
        String url = getOssUrl(path);
        long st = System.currentTimeMillis();
        Request requestDownload = new Request.Builder()
                .url(url)
                .build();
        OkHttpClient client = new OkHttpClient();
        client = client.newBuilder().connectTimeout(ossConnectTime, TimeUnit.MILLISECONDS).build();
        Response responseDownload = client.newCall(requestDownload).execute();
        if (responseDownload.isSuccessful() && responseDownload.body() != null && responseDownload.body().byteStream() != null) {
            InputStream is = responseDownload.body().byteStream();
            writeImageFile(resp, is);
        } else {
            log.error("PictureServiceImpl-oss调用返回异常: url={}, data={}", url, responseDownload);
            return false;
        }
        long responseTime = System.currentTimeMillis() - st;
        log.info("request-oss cost:{}", responseTime);
        return true;
    }

    // base64解码==这块是与前端约定好的,我这边要做的解码
    private String getOssUrl(String path) throws UnsupportedEncodingException {
        final Base64.Decoder decoder = Base64.getDecoder();
        String decodePath = new String(decoder.decode(path), "UTF-8");
        StringBuffer buffer = new StringBuffer();
        String[] split = decodePath.split("&");
        for (int i = 0; i < split.length; i++) {
            if (!split[i].startsWith("Version")) {
                buffer.append(split[i]).append("&");
            }
        }
        log.info("getOssUrl={}", urlPrefix + buffer);
        buffer.append("OSSAccessKeyId=").append(accessKeyId);
        return urlPrefix + buffer;
    }

    /**
     * 将输入流输出到页面
     *
     * @param resp
     * @param inputStream
     */
    public void writeImageFile(HttpServletResponse resp, InputStream inputStream) {
        OutputStream out = null;
        try {
            out = resp.getOutputStream();
            int len = 0;
            byte[] b = new byte[1024];
            while ((len = inputStream.read(b)) != -1) {
                out.write(b, 0, len);
            }
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

三、总结

上面就是返回图片流的方式;

补充:Java后端实现图片上传并返回文件流

/**
 * @ClassName:
 * @User: ljh
 * @Date: 2022/12/19 15:01
 */
@RestController
public class IoController {

    @GetMapping("/download")
    public void download(@RequestParam("file") MultipartFile file,
                         HttpServletResponse response) throws Exception {
        String path = "E://";
        String filename = URLEncoder.encode("test.png", "UTF-8");
        response.setContentType("application/x-download");
        response.setHeader("Content-Disposition", "attachment;filename=" + filename);//浏览器上提示下载时默认的文件名
        ServletOutputStream out = response.getOutputStream();
        InputStream stream = file.getInputStream();

        try {//读取服务器上的文件
            byte buff[] = new byte[file.getBytes().length];
            int length = 0;
            while ((length = stream.read(buff)) > 0) {
                out.write(buff, 0, length);
            }

            File newFile =new File(path + filename);
            file.transferTo(newFile);

            stream.close();
            out.flush();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

到此这篇关于java后端调用第三方接口返回图片流给前端的具体代码实现的文章就介绍到这了,更多相关java后端返回图片流给前端内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java实现两人五子棋游戏(二) 画出棋盘

    Java实现两人五子棋游戏(二) 画出棋盘

    这篇文章主要为大家详细介绍了Java实现两人五子棋游戏,画出五子棋的棋盘,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-03-03
  • java中原码、反码与补码的问题分析

    java中原码、反码与补码的问题分析

    本篇文章介绍了,在java中原码、反码与补码的问题分析。需要的朋友参考下
    2013-04-04
  • 如何基于JavaFX开发桌面程序

    如何基于JavaFX开发桌面程序

    这篇文章主要介绍了如何基于JavaFX开发桌面程序,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • Java并发编程信号量Semapher

    Java并发编程信号量Semapher

    这篇文章主要介绍了Java并发编程信号量Semapher,Semapher信号量也是Java中的一个同步器,下文关于信号量Semapher的更多内容介绍,需要的小伙伴可以参考下面文章
    2022-04-04
  • SpringBoot中自定义注解实现控制器访问次数限制实例

    SpringBoot中自定义注解实现控制器访问次数限制实例

    本篇文章主要介绍了SpringBoot中自定义注解实现控制器访问次数限制实例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
    2017-04-04
  • IDEA中maven无法下载源码的解决方法

    IDEA中maven无法下载源码的解决方法

    这篇文章主要为大家详细介绍了当IDEA中maven无法下载源码时改如何解决,文中通过图文为大家进行了详细讲解,需要的小伙伴可以参考一下
    2023-08-08
  • java写入文件的几种方法分享

    java写入文件的几种方法分享

    这篇文章主要介绍了java写入文件的几种方法,需要的朋友可以参考下
    2014-02-02
  • Java Lambda表达式详解

    Java Lambda表达式详解

    这篇文章主要介绍了Java Lambda表达式详解,包括了Java Lambda表达式创建线程,Java Lambda表达式的语法,Java lambda遍历List集合,Java lambda过滤String需要的朋友可以参考下
    2023-02-02
  • ThreadLocal原理介绍及应用场景

    ThreadLocal原理介绍及应用场景

    本文详细讲解了ThreadLocal原理介绍及应用场景,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-12-12
  • spring IOC容器的Bean管理XML自动装配过程

    spring IOC容器的Bean管理XML自动装配过程

    这篇文章主要为大家介绍了spring IOC容器Bean管理基于XML的自动装配过程,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-05-05

最新评论