一、背景

前段时间公司要求我做一个上传和下载固件的页面,以备硬件产品在线升级,现在我把这部分功能抽取出来作为一个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适合一次性上传小文件,多数情况下需要先上传文件再进行表单提交,视需求而定。

在保存文件建议在文件名后面加上时间戳,保证同名文件不会被覆盖。

以上!

【Demo Project】AjaxSubmit+Servlet表单文件上传和下载的更多相关文章

  1. 表单文件上传,ajax文件上传

    原创链接:http://www.cnblogs.com/yanqin/p/5345562.html html代码  index.jsp(表单文件上传) <form action="sh ...

  2. Ajax(form表单文件上传、请求头之contentType、Ajax传递json数据、Ajax文件上传)

    form表单文件上传 上菜 file_put.html <form action="" method="post" enctype="multi ...

  3. 使用jsp/servlet简单实现文件上传与下载

    使用JSP/Servlet简单实现文件上传与下载    通过学习黑马jsp教学视频,我学会了使用jsp与servlet简单地实现web的文件的上传与下载,首先感谢黑马.好了,下面来简单了解如何通过使用 ...

  4. 混合表单文件上传到数据库(基于TOMCAT)

    在实际的开发中在实现文件上传的同时肯定还有其他信息需要保存到数据库,就像混合表单在上传完毕之后需要将提交的基本信息插入数据库. 在这个demo中需要用到这个架包来帮助实现 1.定义一个公共类实现文件上 ...

  5. 2014-07-23 利用ASP.NET自带控件实现单文件上传与下载

    效果图 上传文件页面: 下载文件页面:  1.母版页site.Master <%@ Master Language="C#" AutoEventWireup="tr ...

  6. form表单文件上传 servlet文件接收

    需要导入jar包 commons-fileupload-1.3.2.jar commons-io-2.5.jar Upload.Jsp代码 <%@ page language="jav ...

  7. Servlet 表单及上传文件

    // 文件路径 D:\ApacheServer\web_java\HelloWorld\src\com\test\TestServletForm.java package com.test; impo ...

  8. 如何使用PHP上传文件,上传图片,php上传教程,php表单文件上传教程

    使用PHP进行文件上传,主要使用到表单功能和PHP内置的$_FILES函数功能.接下来我们看如何实现PHP上传功能.例子效果图,此例子是在Mac下进行调试成功的. PHP上传图片文件的功能代码如下: ...

  9. 表单文件上传编码方式(enctype 属性)

    enctype 属性规定在发送到服务器之前应该如何对表单数据进行编码. 如下: <form action="upload.php" method="post&quo ...

随机推荐

  1. Servlet3.0上传图片示例

    一.前端JSP页面 <%@page pageEncoding="UTF-8"%><!DOCTYPE html><html><head> ...

  2. 编程中&和&&的区别

    逻辑电路中用&: 与门电路,全真为真,有假为假. 编程中:&表示取地址符(C)和 按位与(非bool类型时,转换成二进制,按位与运算). &&表示逻辑与运算,& ...

  3. Hive分区表动态添加字段

    场景描述: 公司埋点项目,数据从接口服务写入kafka集群,再从kafka集群消费写入HDFS文件系统,最后通过Hive进行查询输出.这其中存在一个问题就是:埋点接口中的数据字段是变化,后续会有少量字 ...

  4. CodeForces-747E

    这几天好懒,昨天写的题,今天才来写博客.... 这题你不知道它究竟有多少层,但是知道字符串长度不超过10^6,那么它的总容量是被限定的,用一个二维动态数组就OK了.输入字符串后,可以把它按照逗号分割成 ...

  5. jQuery手机发送验证码倒计时代码

    <!DOCTYPE> <html> <head> <meta charset="UTF-8"> <script type=&q ...

  6. ORA-04028: cannot generate diana for object xxx

    在ORACLE数据库(10.2.0.5.0)上修改一个包的时候,编译有错误,具体错误信息为"ORA-04028: cannot generate diana for object xxx&q ...

  7. caffe+CPU︱虚拟机+Ubuntu16.04+CPU+caffe安装笔记

    由于本机是window10系统,所以想尝试caffe就在自己电脑上整了一个虚拟机(详情可见:win10系统搭建虚拟机:VMware Workstation Player 12环境+Ubuntu Kyl ...

  8. Excel 2010高级应用-气泡图(八)

    Excel 2010高级应用-气泡图(八) 基本操作如下: 1.新建空白文档,并命名为气泡图,找到插入中的气泡图样 2.在其他图表中找到气泡图图样 3.单击气泡图图样,生成空白气泡图框 4.在气泡图图 ...

  9. eclipse -解决Unhandled event loop exception GC overhead limit exceeded

    今天第一次遇到这个问题, 拿出来和大家分享一下. 首先说明下我发现这个错误的过程,  看下面的三张图片 1,在本地weblogic发布项目的时候 2 , 等待一段时间, 出现以下错误 3 ,  点击上 ...

  10. 4-20mA 意义

    工业上最广泛采用的标准模拟量电信号是用4~20mA直流电流来传输模拟量. 采用电流信号的原因是不容易受干扰.并且电流源内阻无穷大,导线电阻串联在回路中不影响精度,在普通双绞线上可以传输数百米.上限取2 ...