1. 程式人生 > >SpringMvc非同步圖片上傳回顯(使用jersey上傳到另一臺伺服器)

SpringMvc非同步圖片上傳回顯(使用jersey上傳到另一臺伺服器)

在之前的文章中已經介紹過springMvc的檔案上傳,springMvc檔案上傳

場景介紹

在本篇部落格中主要介紹使用springMvc進行圖片的上傳
功能需求:在很多網站中都有上傳使用者頭像的功能,上傳之後就會立刻在頁面上顯示出來,這邊就是採用的非同步的方式,並且在實際應用中最好有一個單獨的伺服器作為圖片伺服器,因為載入圖片的時候通常會佔據較大的頻寬,與應用程式伺服器放在一塊的話,影響應用程式伺服器的效能,在這裡由於沒有兩臺伺服器,所以會在一臺電腦上部署兩個tomcat,這樣當圖片上傳後,會先將圖片通過jersey上傳到另一臺伺服器下,然後將路徑儲存到資料庫中

準備

在同一臺電腦上部署兩臺tomcat

第一步 準備好tomcat壓縮包,解壓後,修改server.xml中的三個埠(不要與其他應用程式的埠號衝突,例如SVN的8443),這三個埠號預設是8005,8009,8080,將他們修改為別的
第二步 因為jersey是需要將圖片寫入到伺服器中的,所以需要配置圖片上傳的tomcat允許使用者用過post或者put向伺服器寫資料(預設是不允許的),配置方式如下

    <!--tomcat中的web.xml,主要設定readOnly為false-->
    <servlet>
        <servlet-name>default</servlet-name
>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class> <init-param> <param-name>debug</param-name> <param-value>0</param-value> </init-param> <init-param> <param-name
>
readonly</param-name> <param-value>false</param-value> </init-param> <init-param> <param-name>listings</param-name> <param-value>false</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>

準備好jersey的jar包

使用springMvc上傳圖片

檔案上傳解析器的配置

與上傳檔案一樣,需要配置一個檔案上傳的解析器,注意在配置的時候,圖片解析器的id必須為multipartResolver

<!-- 配置圖片上傳的解析器 -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!-- 單位是位元組,這裡設定成10MB,即1024*1024 -->
        <property name="maxUploadSize" value="10485760"></property>
        <property name="uploadTempDir" value="/WEB-INF/temp"></property>
    </bean>

前端程式碼的編寫

因為是圖片上傳,所以我們可以將input標籤包裹在form表單裡,然後使用ajax直接提交表單到後臺,至於提交的其它的欄位,我們可以在控制器裡不管它們
注意
非同步上傳圖片的時候,需要在使用者點選選擇—>開啟檔案後,就通過ajax將圖片上傳到伺服器,所以需要監聽input type=‘file’的一個事件,這個事件就是onchange

<form id="jvForm" action="/back/brand/add.do" method="post" enctype="multipart/form-data">
    ...
        <tr>
            <td width="20%" class="pn-flabel pn-flabel-h"></td>
                <td width="80%" class="pn-fcontent">
                <img width="100" height="100" id="allImgUrl"/>
                <input type="hidden" name="imgUrl" id="imgUrl"/>
                <input type="file" onchange="uploadPic()" name="pic"/>
            </td>
        </tr>
    ...
</form>

在上傳檔案後,我們將圖片回顯到頁面上的img標籤上,並且將返回過來的imgUrl設定到隱藏域中,因為當用戶真正提交表單的時候,需要將圖片的路徑儲存到資料庫中,而當觸發的onchange事件時,只會將圖片上傳到伺服器,並將圖片的路徑返回過來,並不會儲存到資料庫,這就要求我們在提交的時候將imgUrl儲存

<script type="text/javascript">
    function uploadPic(){
        $("#jvForm").ajaxSubmit({
            url:"/back/uploadPic.do",
            dataType:"json",
            type:"post",
            success:function(data){
                $("#allImgUrl").attr("src",data.url);
                $("#imgUrl").val(data.path);
            }
        });
    }
</script>

控制器的編寫

    import org.apache.commons.io.FilenameUtils;
    import com.sun.jersey.api.client.WebResource;
    import com.sun.jersey.api.client.Client;

    @RequestMapping("/uploadPic.do")
    public void uploadPic(MultipartFile pic, HttpServletResponse response) {

        // 獲取檔案的相關資訊
        // 檔案的名稱,使用uuid
        String fileName = UUID.randomUUID().toString().replace("-", "");
        // 獲取檔案的副檔名
        String ext = FilenameUtils.getExtension(pic.getOriginalFilename());

        // 要上傳的檔案的url,將其回顯到前臺進行展示
        // 將其回顯到前端,在brand新增表單提交的時候,插入到資料庫中
        String path = "babasport_images/" + fileName + "." + ext;
        //Constants.IMAGE_SERVER     http://localhost:8088/
        String url = Constants.IMAGE_SERVER + path;

        Client client = new Client();
        WebResource resource = client.resource(url);
        try {
            resource.put(pic.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }

        JSONObject jo = new JSONObject();
        jo.put("url", url);
        jo.put("path", path);

        response.setContentType("application/json;charset=UTF-8");
        try {
            response.getWriter().write(jo.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

注意事項
1. 返回的時候,是返回的json,所以一定要設定contentType
2. 圖片上傳的前端必須要設定enctype=”multipart/form-data”,以及用post

一個常見異常的解決

Failed to parse multipart request
org.apache.commons.fileupload.FileUploadException: Processing of multipart/form-data request failed. 、\localhost \_ \upload__3d7cf8b_11936276cf8__7ffd_00000011.tmp

需要重新設定一下檔案上傳時,commons.fileupload將上傳的檔案以流的形式將檔案寫到一個臨時資料夾中,現在這個檔案找不到了
解決方法:自己設定臨時資料夾,不用commons.fileupload預設的,在注入的時候注入uploadTempDir