java后端調(diào)用第三方接口返回圖片流給前端的具體代碼實(shí)現(xiàn)
一、背景
有個(gè)需求是這樣的,客戶端直接通過外網(wǎng)訪問oss獲取圖片需要額外付費(fèi),考慮到成本問題,修改技術(shù)方案為:客戶端將請(qǐng)求鏈接發(fā)給后端,后端根據(jù)請(qǐng)求做一定的截取或拼接,通過內(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)用
最近開發(fā)了一個(gè)統(tǒng)一調(diào)度類的項(xiàng)目,需要依賴多個(gè)第三方服務(wù),這些服務(wù)都提供了HTTP接口供我調(diào)用。感興趣的可以了解一下2021-06-06
Spring核心容器之ApplicationContext上下文啟動(dòng)準(zhǔn)備詳解
這篇文章主要介紹了Spring核心容器之ApplicationContext上下文啟動(dòng)準(zhǔn)備詳解,ApplicationContext 繼承自 BeanFactory ,其不僅包含 BeanFactory 所有功能,還擴(kuò)展了容器功能,需要的朋友可以參考下2023-11-11
Java與Spring?boot后端項(xiàng)目Bug超全總結(jié)
Spring Boot是一個(gè)開源的 Java 開發(fā)框架,它的目的是簡(jiǎn)化Spring應(yīng)用程序的開發(fā)和部署,下面這篇文章主要給大家介紹了關(guān)于Java與Spring?boot后端項(xiàng)目Bug的相關(guān)資料,文中通過圖文以及實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-06-06
如何將java或javaweb項(xiàng)目打包為jar包或war包
本文主要介紹了如何將java或javaweb項(xiàng)目打包為jar包或war包,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07
MapReduce實(shí)現(xiàn)TopN效果示例解析
這篇文章主要為大家介紹了MapReduce實(shí)現(xiàn)TopN效果示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07
SpringSecurity+Redis+Jwt實(shí)現(xiàn)用戶認(rèn)證授權(quán)
SpringSecurity是一個(gè)強(qiáng)大且靈活的身份驗(yàn)證和訪問控制框架,本文主要介紹了SpringSecurity+Redis+Jwt實(shí)現(xiàn)用戶認(rèn)證授權(quán),具有一定的參考價(jià)值,感興趣的可以了解一下2024-07-07

