前言:
最近在寫自己的博客網站,算是強化一下自己對s2sh框架的理解。期間遇到了很多問題,這些問題在寫之前都考慮過,感覺也就是那樣吧。但正真遇到了,也挺讓人難受的。就利用zyUpload這個js插件實現文件的上傳, 我來談一談。
zyUpload下載:
https://github.com/hjzgg/zyUpload?,或者可以在網上,隨便就可以下載到,只不過提供的網址中的zyUpload是我改過的。
zyUpload界面效果:
zyUpload使用需要注意的幾個地方:
說明:zyUpload 配合Strus2實現圖片或文件的上傳
(1)zyFile.js,lanrenzhijia.js,zyUpload.js設置 url : "fileUploadAction!execute", // 上傳文件的路徑
(2)文件的上傳通過 zyFile.js中的funUploadFile函數,修改formdata.append("upload", file) file對應的name屬性值,這里是"upload",保證和后臺的name屬性值一樣!上傳的代碼如下:
// 上傳多個文件funUploadFiles : function(){var self = this; // 在each中this指向沒個v 所以先將this保留// 遍歷所有文件 ,在調用單個文件上傳的方法$.each(this.uploadFile, function(k, v){self.funUploadFile(v);});},// 上傳單個個文件funUploadFile : function(file){var self = this; // 在each中this指向沒個v 所以先將this保留var formdata = new FormData();formdata.append("upload", file); var xhr = new XMLHttpRequest();// 綁定上傳事件// 進度xhr.upload.addEventListener("progress", function(e){// 回調到外部 self.onProgress(file, e.loaded, e.total);}, false); // 完成xhr.addEventListener("load", function(e){// 從文件中刪除上傳成功的文件 false是不執行onDelete回調方法self.funDeleteFile(file.index, false);// 回調到外部 self.onSuccess(file, xhr.responseText);if(self.uploadFile.length==0){// 回調全部完成方法self.onComplete("全部完成");}}, false); // 錯誤xhr.addEventListener("error", function(e){// 回調到外部 self.onFailure(file, xhr.responseText);}, false); xhr.open("POST", self.url, true);xhr.send(formdata);},
(3)缺陷就是只能單個文件上傳!用的是FormData對象,利用ajax技術,每次上傳都要請求后臺。
(4)zyFile.js中的一些接口都是在zyUpload.js中實現!
下面是zyFile.js中的一些接口
filterFile : function(files){ // 提供給外部的過濾文件格式等的接口,外部需要把過濾后的文件返回 },onSelect : function(selectFile, files){ // 提供給外部獲取選中的文件,供外部實現預覽等功能 selectFile:當前選中的文件 allFiles:還沒上傳的全部文件 },onDelete : function(file, files){ // 提供給外部獲取刪除的單個文件,供外部實現刪除效果 file:當前刪除的文件 files:刪除之后的文件 },onProgress : function(file, loaded, total){ // 提供給外部獲取單個文件的上傳進度,供外部實現上傳進度效果 },onSuccess : function(file, responseInfo){ // 提供給外部獲取單個文件上傳成功,供外部實現成功效果 },onFailure : function(file, responseInfo){ // 提供給外部獲取單個文件上傳失敗,供外部實現失敗效果 },onComplete : function(responseInfo){ // 提供給外部獲取全部文件上傳完成,供外部實現完成效果 },
zyFile.js中filterFile給外部提供的函數接口在 zyUpload.js可以找到,用來進行文件的過濾!對于filterFile這個借口,實現如下(當然,你可以根據自己的需求自己來實現,我這里只是想上傳圖片文件而已):
this.funFilterEligibleFile = function(files){var arrFiles = []; // 替換的文件數組for (var i = 0, file; file = files[i]; i++) {if (file.size >= 51200000) {alert('您這個"'+ file.name +'"文件大小過大'); } else {// 在這里需要判斷當前所有文件中var fileExt = file.name.substr(file.name.lastIndexOf(".")).toLowerCase();//獲得文件后綴名if(fileExt==".png" || fileExt==".gif" || fileExt==".jpg" || fileExt==".jpeg")arrFiles.push(file);//如果文件是圖片格式,那么就放入文件的數組 else {alert("文件僅限于 png, gif, jpeg, jpg格式 !");}}}return arrFiles;};
filterFile: function(files) {// 過濾合格的文件return self.funFilterEligibleFile(files);},
struct2后臺處理:
1.structs.xml中配置文件上傳解析器
<!-- struct2默認使用jakarta的Common-FileUpload的文件上傳解析器 --> <constant name="struts.multipart.parser" value="jakarta"/>
2.structs.xml中action的配置
<action name="fileUploadAction" class="fileUploadAction" method="struts-default"><param name="savePath">/fileUpload</param><result name="errors" type="redirect">/errorsMessage/fileErrorsTip.jsp</result><result name="operations" type="redirect">/operationsMessage/fileOperationsTip.jsp</result></action>
3.dao層
public class PictureDao implements Serializable{private SessionFactory sessionFactory;public SessionFactory getSessionFactory() {return sessionFactory;}public void setSessionFactory(SessionFactory sessionFactory) {this.sessionFactory = sessionFactory;}private Session getSession(){return sessionFactory.getCurrentSession();}public PictureGroup pictureJspGetOneGroup(int groupId){//得到相冊的分組PictureGroup pictureGroup = null;Session session = null;Transaction tran = null;try{session = this.getSession();tran = session.beginTransaction();pictureGroup = (PictureGroup)session.createQuery("from PictureGroup where groupId="+groupId).list().get(0);tran.commit();} catch(Exception e) {System.out.println(e.toString());tran.rollback();return null;}return pictureGroup;}public String newMyPicture(MyPicture myPicture){//持久化圖片信息Session session = null;Transaction tran = null;try{session = this.getSession();tran = session.beginTransaction();session.persist(myPicture);tran.commit();} catch(Exception e){System.out.println(e.toString());tran.rollback();return e.toString();}return null;}}
4.action部分
public class FileUploadAction extends ActionSupport{private PictureDao pictureDao;public PictureDao getPictureDao() {return pictureDao;}public void setPictureDao(PictureDao pictureDao) {this.pictureDao = pictureDao;}private List<File> upload; // 上傳的文件private List<String> uploadFileName; // 文件名稱private List<String> uploadContentType; // 文件類型private String savePath;public List<File> getUpload() {return upload;}public void setUpload(List<File> upload) {this.upload = upload;}public List<String> getUploadFileName() {return uploadFileName;}public void setUploadFileName(List<String> uploadFileName) {this.uploadFileName = uploadFileName;}public List<String> getUploadContentType() {return uploadContentType;}public void setUploadContentType(List<String> uploadContentType) {this.uploadContentType = uploadContentType;}public String getSavePath() {return savePath;}public void setSavePath(String savePath) {this.savePath = savePath;}private String pictureName = null;private String picturePath = null;private String pictureGroupId = null;public String fileUploadSuccess(){//添加一張圖片try{MyPicture myPicture = new MyPicture();myPicture.setPictureName(pictureName);myPicture.setPicturePath(picturePath);myPicture.setPictureBuildTime(new Timestamp(System.currentTimeMillis()));PictureGroup pictureGroup = pictureDao.pictureJspGetOneGroup(Integer.parseInt(pictureGroupId));//為了得到持久化的相冊分組對象if(pictureGroup == null) throw new NullPointerException("分組為空!");myPicture.setGroup(pictureGroup);String msg = pictureDao.newMyPicture(myPicture);ActionContext.getContext().getSession().put("operations", "圖片" + pictureName + (msg==null ? "上傳成功!" : "上傳失敗:"+msg));} catch (Exception e){System.out.println(e.toString());ActionContext.getContext().getSession().put("errors", "圖片" + pictureName + "添加失敗: " + e.toString() + " 異常位置: FileUploadAction!fileUploadSuccess。");return "errors";}return "operations";}@Overridepublic String execute() throws Exception {try{// 取得需要上傳的文件數組List<File> files = getUpload();HttpServletRequest request = ServletActionContext.getRequest();//得到 到 項目根目錄的URLString url = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath();if (files != null && files.size() > 0) {String realPath = ServletActionContext.getServletContext().getRealPath(savePath);//多個文件的上傳 // for (int i = 0; i < files.size(); i++) { // String fileName = System.currentTimeMillis()+getUploadContentType().get(i).replace("/", "."); // picturesPath.add(url+savePath+"/"+fileName); // FileOutputStream fos = new FileOutputStream(realPath + "\\" + fileName); // FileInputStream fis = new FileInputStream(files.get(i)); // byte[] buffer = new byte[1024]; // int len = 0; // while ((len = fis.read(buffer)) > 0) { // fos.write(buffer, 0, len); // } // fis.close(); // fos.close(); // }if((pictureGroupId=(String)ActionContext.getContext().getSession().get("pictureGroupId")) == null){//未選擇分組ActionContext.getContext().getSession().put("operations", "圖片"+uploadFileName+"上傳失敗,分組未選擇! <a target='_parent' href='../pictureAction!pictureGroupJspGetAllGroups'>選擇分組</a>");return "operations";}//處理單個文件的上傳String fileName = System.currentTimeMillis()+getUploadFileName().get(0)+getUploadContentType().get(0).replace("/", ".");FileOutputStream fos = new FileOutputStream(realPath + "\\" + fileName);FileInputStream fis = new FileInputStream(files.get(0));byte[] buffer = new byte[1024];int len = 0;while ((len = fis.read(buffer)) > 0) {fos.write(buffer, 0, len);}fis.close();fos.close();picturePath = url+savePath+"/"+fileName;pictureName = getUploadFileName().get(0);return fileUploadSuccess();} else {ActionContext.getContext().getSession().put("errors", "得到文件數目為0! 異常位置:FileUploadAction!execute。");}} catch (Exception e){System.out.println(e.toString());ActionContext.getContext().getSession().put("errors", "圖片" + getUploadFileName().get(0) + "上傳失敗: " + e.toString()+"異常位置:FileUploadAction!execute。");return "errors";}return "errors";} }
5.說一下Action中的一些信息:
String url = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath(); 得到請求項目的地址,如http://localhost:8080/myBlog;
String fileName =?System.currentTimeMillis()+getUploadFileName().get(0)+
? ? ?getUploadContentType().get(0).replace("/", "."); 生成唯一文件名稱。
String realPath = ServletActionContext.getServletContext().getRealPath(savePath);得到圖片的存儲地址
picturePath = url+savePath+"/"+fileName;得到圖片的src地址
最終效果:
1.上傳后,無論是失敗還是成功,都可以通過ajax從后臺得到!
2.最后從后臺得到數據并展示