記一次跨服務(wù)器的文件下載功能開發(fā)
1、背景:
有這樣一個(gè)需求,就是目前在OA系統(tǒng)的所有請(qǐng)求都會(huì)打到A服務(wù)器上,A服務(wù)器作為OA系統(tǒng)的門戶服務(wù),但是現(xiàn)在有個(gè)獨(dú)立的文件備份服務(wù),也想通過A服務(wù)器來讓OA系統(tǒng)調(diào)用,里邊包括了下載文件的功能,
此時(shí)比如把文件備份服務(wù)部署到B服務(wù)器上,需要下載的文件也在B服務(wù)器上,文件備份服務(wù)提供了個(gè)接口,用來下載文件,所以想要在OA系統(tǒng)上下載B服務(wù)器上的文件,整個(gè)鏈路就變成了如下:
瀏覽器發(fā)出下載請(qǐng)求 ---> A服務(wù)器接收到瀏覽器請(qǐng)求后,向B服務(wù)器發(fā)送請(qǐng)求 ----> B服務(wù)器接收到A服務(wù)器的請(qǐng)求后,進(jìn)行文件下載傳輸 ----> A服務(wù)器接收到返回的文件流,將該文件流傳輸?shù)綖g覽器的返回流上 ----> 瀏覽器接收到返回的流文件
當(dāng)然也可以有其他替代的方式,比如使用nginx來直接將請(qǐng)求轉(zhuǎn)到B服務(wù)器上,或者使用前端轉(zhuǎn)發(fā)的形式將請(qǐng)求轉(zhuǎn)發(fā)到B服務(wù)器上,但是這些轉(zhuǎn)發(fā)的方式有個(gè)問題,就是要么修改Nginx配置,要么要前端改,感覺比較麻煩,萬(wàn)一服務(wù)部署的時(shí)候忘記了就比較麻煩了。
2、實(shí)現(xiàn):
具體的實(shí)現(xiàn)原理其實(shí)就是把B服務(wù)器上返回的文件流直接寫入到瀏覽器請(qǐng)求的返回流上就行,代碼如下:
BufferedInputStream bufferedInputStream = null;
OutputStream os = null; try { URL url = new URL("http://B服務(wù)器:端口/文件下載接口"); URLConnection connection = url.openConnection(); InputStream inputStream = connection.getInputStream(); bufferedInputStream = new BufferedInputStream(inputStream); os = new BufferedOutputStream(response.getOutputStream()); String encoderName = URLEncoder.encode("文件名", CharsetUtil.UTF_8); response.reset();
response.setHeader("Access-Control-Allow-Origin", "*");
//下面這句很關(guān)鍵,如果沒有,下載下來的就不是文件了 response.setHeader("Content-Disposition", "attachment;filename=" + encoderName); byte[] buffer = new byte[1024]; int bytesRead; while ((bytesRead = bufferedInputStream.read(buffer)) != -1) { os.write(buffer, 0, bytesRead); } } catch (Exception e) { log.error("下載備份文件異常", e); } finally { try { if (os != null) { os.close(); } } catch (IOException e) { log.error("輸出流關(guān)閉失敗"); } try { if (os != null) { bufferedInputStream.close(); } } catch (IOException e) { log.error("輸入流關(guān)閉失敗"); } }

浙公網(wǎng)安備 33010602011771號(hào)