extJs顯示圖片問題
困擾幾天的圖片顯示問題今天解決了,中間走過了許多坑,下面一點點說:
需求:一個簡單的意見反饋功能,要求有圖片展示,一條記錄可最多上傳5張圖片,前端用的是安卓,後端提供service,並展示在頁面。
分析:
1、與安卓前端互動的是一個service的war包,請求通過封裝,只能使用json格式傳資料;
2、頁面展示的是在另外一個web的war包上,有一點好處是兩個war包會部署在同一個伺服器上;
3、本地開發使用windows+tomcat,伺服器使用jboss部署在linux環境下;
4、因為考慮到圖片未來的增長量,不能直接存入資料庫(每張圖片壓縮過後200k,對資料庫的壓力蠻大);
5、伺服器上因為許可權問題,存入的檔案通過web直接訪問路徑是無法載入的;
6、前端使用extJS,對extjs載入圖片的使用不熟悉;
解決方案:
1、使用解析json格式包文,使用 List<byte[]>
2、考慮到伺服器和war包的因素,在伺服器上war包部署的根目錄建立資料夾,並對訪問war包的使用者賦予讀寫許可權;建立的資料夾在程式碼裡使用絕對路徑訪問 (/opt/attach/dlv/images )
3、解析的byte陣列直接儲存在第二步建立的資料夾中,重新生成檔名,資料庫保留檔名記錄;
4、頁面訪問圖片時,直接以流的形式載入上一步儲存的圖片,然後使用輸出流的方式顯示在前端頁面;
5、訪問圖片的url需要加時間戳,來保證二次訪問可以正常開啟;
解析程式碼如下:
Object dataList = map.get ("fileList");
List< byte[]> byteList = JSONObject. parseArray(dataList +"", byte [].class);
頁面載入程式碼如下:
String filePath = "/opt/attach/dlv/images/" +yearMonth +"/" +imageName ;
File filePic = new File(filePath);
if(filePic.exists()){
FileInputStream is = new FileInputStream(filePic);
int i = is.available(); // 得到檔案大小
byte data[] = new byte[i];
is.read(data); // 讀資料
is.close();
response.setContentType( "image/*"); // 設定返回的檔案型別
OutputStream toClient;
toClient = response.getOutputStream();
toClient.write(data); // 輸出資料
toClient.close();
}
前端extJS載入圖片程式碼:
aa.onDblClick = function (fileName ) {
var win_Watch = Ext.create( 'Ext.Window', {
width: 640,
height: 800,
modal: true, //是否模態視窗,預設為false
maximizable: true,
layout: "fit", //窗口布局型別
resizable: false,
closeAction: 'hide',
plain: true,
draggable: true,
border: false,
items: [
Ext.create( 'Ext.Img', {
height: '100%',
width: '100%',
src: 'loadSuggestPic.action?imageName=' +fileName+ '&exptoken='+ encodetoke
})
]
});
win_Watch.show();
}
PS:
1、之前嘗試使用 ServletActionContext.getServletContext().getRealPath(“/images/”)的方式獲取路徑展示,但是在本地開發的時候可以使用,在伺服器上是不能使用的,因為打war包到伺服器上之後,上述程式碼獲取的路徑是一個臨時路徑,並不是你想要的路徑,大概是“webapps/tmp/vfs/temp/tempb6c09149eda39ca6/xxxxx.war-45be899d46ab6225/images” 這樣格式的,所以是不行的;
2、不要糾結action程式碼中異常以及流沒關的問題。。。。只是為了篇幅,把程式碼貼出來而已。。。。囧