AjaxSubmit+Servlet表單文件上傳和下載


一、背景

前段時間公司要求我做一個上傳和下載固件的頁面,以備硬件產品在線升級,現在我把這部分功能抽取出來作為一個Demo Project給大家分享。

話不多說,先看項目演示 --> 演示  源碼

二、源碼

前端

js庫:jquery-3.2.1.min.js,jquery.form.js(異步表單提交),jsviews.min.js(模板渲染)

jsviews科普:jsviews是實現MVVM的js庫,分為JsRender(渲染),JsViews(數據視圖雙向綁定),JsObservable (數據監聽),有興趣的同學可以去官網了解,這里只用到了渲染的功能。

1、下載頁面 index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>ajaxSubmit上傳</title>
    <link rel="shortcut icon" href="images/favicon.ico">
    <link rel="Bookmark" href="images/favicon.ico">
    <link rel="stylesheet" href="css/index.css" />
    <script type="text/javascript" src="js/jquery-3.2.1.min.js"></script>
    <script type="text/javascript" src="js/jquery.form.js"></script>
    <script type="text/javascript" src="js/jsviews.min.js"></script>
    <script type="text/javascript" src="js/common.js"></script>
    
</head>
<body>
<h1>上傳下載Demo</h1>
<h2>1、上傳文件</h2>
<form id="addForm">
    <div>
        <span>選擇類型:</span>
        <select name="code" id="code">
            <option value="0">普通開關</option>
            <option value="1">插座</option>
        </select>
    </div>
    <div>
        <span>選擇文件(小於5k):</span>
        <input type="file" id="file" name="file">
    </div>
    <div>
        <button type="button" id="addConfirm" name="addConfirm">確定</button>
    </div>
</form>
<h2>2、測試上傳結果</h2>
<table id="tbBody">
<thead>
<tr><td>類型</td><td>文件名</td><td>通過Servlet下載</td></tr>
</thead>
</table>
</body>
<script type="text/javascript" src="js/index.js"></script>
<!--  jsviews模板 -->
<script id="listTmpl" type="text/x-jsrender">
           <tr>
            <td>
            {^{if code=='0'}}普通開關
            {{else code=='1'}}插座
            {{else}}數據錯誤{{/if}}
            </td>
            <td>{{:fileName}}</td>
            <td><a href="fileDownload?fileName={{:fileName}}">urlServlet</a></td>
          </tr>
</script>
</html>

2、公共js js/common.js

//獲取鏈接參數
function getQueryString(name)
{
     var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)");
     var r = window.location.search.substr(1).match(reg);
     if(r!=null)return  unescape(r[2]); return null;
}

 3、 js/index.js

//提交表單
function addSubmit(){
    var options={
         url: "fileUpload",
          type:'post',            
          datatype:'json',
          success: function (data) {
            var result = JSON.parse(data);
            if(result.code == "0000"){
                var pageBarTmpl = $.templates("#listTmpl");
                var html = pageBarTmpl.render(result.content);
                $("#tbBody").append(html);
            }else{
                alert(result.desc);
            }    
      }
    }
    $("#addForm").ajaxSubmit(options); 
}
//提交前檢查
function submitCheck(){
    var code = $("#code").val();
    if (!code) {
        alert("請選擇類型");
        return false;
    }
    var file = $("#file").val();
    if (!file) {
        alert("請選擇需要上傳的固件");
        return false;
    }
    return true;
    
}
//按鈕觸發
$("#addConfirm").click(function(){
    if(submitCheck())
        addSubmit();
});

4、css/index.css

table th,table td{ 
    border:1px solid black;
} 
form div{
    margin:5px;
}

 后端

使用到了commons-fileupload-1.3.1.jar,commons-io-2.4.jar以及gson-2.6.2.jar

1、返回結果類  RspResult.java

/**
 * 返回結果類
 * @author zhang
 *
 */
public class RspResult{
    
    private String code; //返回碼
    private String desc; //返回描述
    private Map<String,Object> content;  //返回內容
    public String getCode() {
        return code;
    }
    public void setCode(String code) {
        this.code = code;
    }
    public String getDesc() {
        return desc;
    }
    public void setDesc(String desc) {
        this.desc = desc;
    }
    public Map<String, Object> getContent() {
        return content;
    }
    public void setContent(Map<String, Object> content) {
        this.content = content;
    }
    
}

2、自定義異常類  MyException.java

/**
 * 自定義異常
 * @author zhang
 *
 */
public class MyException extends Exception{
    
    private static final long serialVersionUID = 3075956744530570774L;
    private String code;  //錯誤碼
    private String desc;  //描述
    public MyException(String code, String desc) {
        super();
        this.code = code;
        this.desc = desc;
    }
    public String getCode() {
        return code;
    }
    public void setCode(String code) {
        this.code = code;
    }
    public String getDesc() {
        return desc;
    }
    public void setDesc(String desc) {
        this.desc = desc;
    } 
}

3、文件上傳Servlet  FileUpload.java

/**
 * 文件上傳類
 * 使用commons-fileupload工具包解析表單內容,捕獲自定義異常
 * @author zhang
 *
 */
public class FileUpload extends HttpServlet{
    
    private static final long serialVersionUID = -4700695646596658600L;
    private static final String SAVE_LOCATION = "/home/www/download/blog/ajaxUpload/"; //保存地址

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException {
        resp.setCharacterEncoding("UTF-8");
        RspResult result = new RspResult();
        result.setCode("0000");
        result.setDesc("success");
        try {

            DiskFileItemFactory factory = new DiskFileItemFactory();
            ServletFileUpload upload = new ServletFileUpload(factory);
            upload.setFileSizeMax( 5*1024 ); //單個文件最大上傳大小為5k
            upload.setSizeMax( 5*1024 );     //設置全部文件最大上傳總大小為5k
            upload.setHeaderEncoding("utf-8");  //設置編碼
            
            List<FileItem> fileItems = upload.parseRequest(req);
            Iterator<FileItem> iterator = fileItems.iterator();
            Map<String, Object> rspConent = new HashMap<>();
            DiskFileItem fileItem = null;
            //循環讀取表單數據
            while (iterator.hasNext()) {
                FileItem item = iterator.next();
                if (!item.isFormField()) { //是否為文件類型,因為只有一個文件,所以單個引用就行
                    fileItem = (DiskFileItem) item;
                }else {
                    rspConent.put(item.getFieldName(), item.getString());
                }
            }
            if(fileItem == null)
                throw new MyException("0001","無選擇文件");
            String fileName = fileItem.getName();
            fileItem.write(new File(SAVE_LOCATION + fileName));
            rspConent.put("fileName", fileName);
            result.setContent(rspConent);
            
        } catch (FileUploadException e ) {
            result.setCode("0001");
            result.setDesc("文件上傳大小為5k");
            e.printStackTrace();
        } catch (MyException e ) {  //取得自定義異常結果
            result.setCode(e.getCode());
            result.setDesc(e.getDesc());
        } catch (Exception e) {
            result.setCode("0001");
            result.setDesc("未知錯誤");
            e.printStackTrace();
        }finally {
            PrintWriter out = null;
            try {
                out = resp.getWriter();
            } catch (IOException e) {
                e.printStackTrace();
            }
            out.write(new Gson().toJson(result));
        }
    }
}

4、文件下載Servlet  FileDownload.java

/**
 * 文件下載類,讀取文件,以字節流形式寫到response
 * @author admin
 *
 */
public class FileDownload extends HttpServlet
{    
    private static final long serialVersionUID = -9135576688701595777L;
    private final String SAVE_LOCATION = "/home/www/download/blog/ajaxUpload/"; 

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException {
        InputStream in  = null;
        try {
            String fileName = req.getParameter("fileName");
            in  = new FileInputStream(SAVE_LOCATION+fileName);
            
            // 設置輸出格式
            resp.setCharacterEncoding("utf-8");
            resp.addHeader("Content-Disposition", "attachment; filename=\"" + URLEncoder.encode(fileName, "UTF-8") + "\"");
            
            // 讀取數據
            byte[] b = new byte[100];
            int len = 0;
            while ((len = in.read(b)) > 0)
                resp.getOutputStream().write(b, 0, len);
        } catch (UnsupportedEncodingException e2) {
            e2.printStackTrace();
        } catch (FileNotFoundException e1) {
            e1.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if(in != null)
                    in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }
    
}

配置

1、項目配置  web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:jsp="http://java.sun.com/xml/ns/javaee/jsp" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>upload-download-demo</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>
   <servlet>
    <servlet-name>fileUpload</servlet-name>
    <servlet-class>com.yuejia.servlet.FileUpload</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>fileUpload</servlet-name>
    <url-pattern>/fileUpload</url-pattern>
  </servlet-mapping>
   <servlet>
    <servlet-name>fileDownload</servlet-name>
    <servlet-class>com.yuejia.servlet.FileDownload</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>fileDownload</servlet-name>
    <url-pattern>/fileDownload</url-pattern>
  </servlet-mapping>
</web-app>

2、tomcat配置url支持utf-8  server.xml

<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8" />

三、總結

本Demo適合一次性上傳小文件,多數情況下需要先上傳文件再進行表單提交,視需求而定。

在保存文件建議在文件名后面加上時間戳,保證同名文件不會被覆蓋。

以上!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM