1. 程式人生 > >java web應用上傳圖片詳解

java web應用上傳圖片詳解

本文涉及如下技術:

  • 前端:extJS
  • 後端:struts2, tomcat等

前端實現

前端用的是ExtJS框架,實現了一個簡單的圖片上傳功能。由於我本身對前端技術也不是很熟悉,這部分只是班門弄斧隨便講下。

這裡寫圖片描述

基本思路是這樣的:

點選 “上傳” 按鈕時,呼叫一個js的函式,這個函式通過呼叫後端action來完成檔案上傳的操作。

js函式實現如下:

function uploadImg(){

    var filePath=uploadVar.getValue();
    if(filePath==''){
        Ext.MessageBox.alert("提示"
,"請選擇圖片!"); return; } imageForm.getForm().getEl().dom.enctype="multipart/form-data"; imageForm.getForm().submit({ waitMsg : "圖片上傳中...", waitTitle: '提示', method: 'POST', url:'uploadImage.action?flag=aa&id='+curSelNode.id, success : function
(form, action){
var image = Ext.get('picpath').dom; var fileUrl=action.result.fileUrl; if(fileUrl==null || fileUrl==''){ image.src = Ext.NOPIC_IMAGE_URL; }else{ image.src=fileUrl; } var
form = addOrUpdateAdvertPanelForm.getForm(); form.findField('advertisement.picpath').setValue(fileUrl); Ext.MessageBox.alert("提示","上傳成功!"); }, failure : function(){ Ext.MessageBox.alert("提示","上傳失敗!"); } }); }

url欄位指向了請求的action地址(uploadImage.action)。下面就是伺服器端的事了。

伺服器端實現

我首先在struts.xml裡配置action,

    <!-- 上傳圖片Action配置 -->
    <action name="uploadImage" class="imageUploadAction" method="uploadImageExt">
          <result >pages/uploadSuccess.jsp</result>
    </action>

這裡告訴伺服器actio對應的類和方法,接下來是具體實現:

@Controller("imageUploadAction")
public class ImageUploadAction {
    private static final long serialVersionUID = -7914395488136167452L;

    private File file; 
    private File imgFile; //確保和前端控制元件名一致
    private String flag; 
    private String fileUrl;
    private boolean success = false; // 成功標識



    /**
     * 上傳圖片-EXT
     */
    public String uploadImageExt() {


        try {
            if (null == this.flag || "".equals(this.flag)) {
                this.success = false;
                return SUCCESS;
            }

            String path = null; // 圖片物理根路徑
            String outPath = null; // 圖片伺服器URL


            //從配置檔案讀取物理路徑和訪問路徑
            String path = Config.getProperty("UPLOAD_PATH");
            String outPath = Config.getProperty("UPLOAD_URL");

            // 上傳檔案方法
            this.fileUrl = this.uploadCommon(path, outPath, this.imgFile,
                    this.imgFile.getAbsolutePath(), this.getCurrentUser()
                            .getUserid().toString());


            this.success = true;
        } catch (Exception e) {
            this.success = false;
        } finally {
            return SUCCESS;
        }
    }


    public String uploadCommon(String path, String outPath, File file,
            String fileName, String userid) {


        String r = "";
        try {
            // 獲取副檔名
            String extName = "";
            if (fileName.lastIndexOf(".") >= 0) {
                extName = fileName.substring(fileName.lastIndexOf("."));
            }
            if (".tmp".equals(extName)) {
                extName = ".jpg";
            }

            // 生成資料夾:編號+時間(相對路徑)
            String midPath = (null != id && !"".equals(id)
                    && !"null".equals(id) ? id + "/" : "")
                    + DateUtil.date2String(new Date(), "yyyyMMdd") + "/";

            // 生成檔名稱,具體的秒的時間
            String imgName = new SimpleDateFormat("yyyyMMdd_HHmmss")
                    .format(new Date()) + new Random().nextInt(100) + extName;


            // 圖片物理路徑=WEB物理路徑+相對路徑+檔名
            String filePath = path + midPath + imgName;

            // 完整的圖片訪問URL
            String imgUrl = outPath + midPath + imgName;

            // 取HTTP請求流,將其寫成圖片檔案
            FileInputStream inFile = new FileInputStream(file);
            double fileSize = inFile.available() / 1024; // 單位KB
            File f_img = new File(path + midPath);
            if (!f_img.exists()) {
                f_img.mkdirs();
            }
            FileOutputStream outFile = new FileOutputStream(filePath);
            byte[] buffer = new byte[1024];
            int i = 0;
            while ((i = inFile.read(buffer)) != -1) {
                outFile.write(buffer, 0, i);
            }
            outFile.flush();
            outFile.close();
            inFile.close();

            r = imgUrl;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return r;
    }

這樣我就把圖片儲存到了本地電腦的一個物理路徑,比如說這個路徑是類似這樣:

C:\img\upload\aa\1\20170629\20170629_09221534.jpg

訪問路徑我在配置檔案裡是這樣寫的:

http://localhost:8080/upload/img/aa/

配置虛擬路徑

圖片上傳成功後,我們還需要通過http訪問這個圖片。但是前面上傳的圖片並不在tomcat目錄下,該如何訪問呢?

有人可能要說,那你在配置檔案裡把物理路徑寫成tomcat專案下的不就可以了嗎?

確實是可以,但是為了以後軟體升級的方便,我會選擇某些上傳的靜態資源,如圖片、視訊等放置在伺服器tomcat目錄外,網站下次升級,只更新網站的war包,原靜態資源可以不用動。

這就需要配置下tomcat,告訴它我們的靜態資源在外部的一個地址。

拿我上面配置的地址為例,編輯Tomcat下的server.xml檔案,在host節點中增加如下的配置:

<Context path="/upload/img/aa/" docBase="C:\img\upload\aa\" reloadable="false" ></Context>