java后端調(diào)用第三方接口返回圖片流給前端的具體代碼實(shí)現(xiàn)
一、背景
有個(gè)需求是這樣的,客戶(hù)端直接通過(guò)外網(wǎng)訪(fǎng)問(wèn)oss獲取圖片需要額外付費(fèi),考慮到成本問(wèn)題,修改技術(shù)方案為:客戶(hù)端將請(qǐng)求鏈接發(fā)給后端,后端根據(jù)請(qǐng)求做一定的截取或拼接,通過(guò)內(nèi)網(wǎng)調(diào)用oss,再將下載下來(lái)的圖片流返回給前端。
圖片流,展現(xiàn)在頁(yè)面上就是直接返回一張圖片在瀏覽器上。
二、具體代碼展示
前端期望,如果異常,直接把http status返回非200
@Slf4j @RestController public class PictureController { @Autowired private PictureService pictureService; @RequestMapping(value = "getPicture") public void getPicture(String path, HttpServletResponse resp) { boolean picSuccess; // 注意:一定要有這步,否則圖片顯示不出來(lái) 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調(diào)用返回異常: 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; } /** * 將輸入流輸出到頁(yè)面 * * @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(); } } } }
三、總結(jié)
上面就是返回圖片流的方式;
補(bǔ)充:Java后端實(shí)現(xiàn)圖片上傳并返回文件流
/** * @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);//瀏覽器上提示下載時(shí)默認(rèn)的文件名 ServletOutputStream out = response.getOutputStream(); InputStream stream = file.getInputStream(); try {//讀取服務(wù)器上的文件 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(); } } }
到此這篇關(guān)于java后端調(diào)用第三方接口返回圖片流給前端的具體代碼實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)java后端返回圖片流給前端內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java使用OpenFeign管理多個(gè)第三方服務(wù)調(diào)用
最近開(kāi)發(fā)了一個(gè)統(tǒng)一調(diào)度類(lèi)的項(xiàng)目,需要依賴(lài)多個(gè)第三方服務(wù),這些服務(wù)都提供了HTTP接口供我調(diào)用。感興趣的可以了解一下2021-06-06Spring核心容器之ApplicationContext上下文啟動(dòng)準(zhǔn)備詳解
這篇文章主要介紹了Spring核心容器之ApplicationContext上下文啟動(dòng)準(zhǔn)備詳解,ApplicationContext 繼承自 BeanFactory ,其不僅包含 BeanFactory 所有功能,還擴(kuò)展了容器功能,需要的朋友可以參考下2023-11-11Java與Spring?boot后端項(xiàng)目Bug超全總結(jié)
Spring Boot是一個(gè)開(kāi)源的 Java 開(kāi)發(fā)框架,它的目的是簡(jiǎn)化Spring應(yīng)用程序的開(kāi)發(fā)和部署,下面這篇文章主要給大家介紹了關(guān)于Java與Spring?boot后端項(xiàng)目Bug的相關(guān)資料,文中通過(guò)圖文以及實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-06-06如何將java或javaweb項(xiàng)目打包為jar包或war包
本文主要介紹了如何將java或javaweb項(xiàng)目打包為jar包或war包,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07MapReduce實(shí)現(xiàn)TopN效果示例解析
這篇文章主要為大家介紹了MapReduce實(shí)現(xiàn)TopN效果示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07SpringSecurity+Redis+Jwt實(shí)現(xiàn)用戶(hù)認(rèn)證授權(quán)
SpringSecurity是一個(gè)強(qiáng)大且靈活的身份驗(yàn)證和訪(fǎng)問(wèn)控制框架,本文主要介紹了SpringSecurity+Redis+Jwt實(shí)現(xiàn)用戶(hù)認(rèn)證授權(quán),具有一定的參考價(jià)值,感興趣的可以了解一下2024-07-07