java后端調(diào)用第三方接口返回圖片流給前端的具體代碼實現(xiàn)
一、背景
有個需求是這樣的,客戶端直接通過外網(wǎng)訪問oss獲取圖片需要額外付費,考慮到成本問題,修改技術方案為:客戶端將請求鏈接發(fā)給后端,后端根據(jù)請求做一定的截取或拼接,通過內(nèi)網(wǎng)調(diào)用oss,再將下載下來的圖片流返回給前端。
圖片流,展現(xiàn)在頁面上就是直接返回一張圖片在瀏覽器上。
二、具體代碼展示
前端期望,如果異常,直接把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調(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;
}
/**
* 將輸入流輸出到頁面
*
* @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后端實現(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);//瀏覽器上提示下載時默認的文件名
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后端調(diào)用第三方接口返回圖片流給前端的具體代碼實現(xiàn)的文章就介紹到這了,更多相關java后端返回圖片流給前端內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Java使用OpenFeign管理多個第三方服務調(diào)用
最近開發(fā)了一個統(tǒng)一調(diào)度類的項目,需要依賴多個第三方服務,這些服務都提供了HTTP接口供我調(diào)用。感興趣的可以了解一下2021-06-06
Spring核心容器之ApplicationContext上下文啟動準備詳解
這篇文章主要介紹了Spring核心容器之ApplicationContext上下文啟動準備詳解,ApplicationContext 繼承自 BeanFactory ,其不僅包含 BeanFactory 所有功能,還擴展了容器功能,需要的朋友可以參考下2023-11-11
SpringSecurity+Redis+Jwt實現(xiàn)用戶認證授權
SpringSecurity是一個強大且靈活的身份驗證和訪問控制框架,本文主要介紹了SpringSecurity+Redis+Jwt實現(xiàn)用戶認證授權,具有一定的參考價值,感興趣的可以了解一下2024-07-07

