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后端返回图片流给前端内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
最新评论