框架搭建

我们在之前的文章中已经实现了 单张图片的上传,使用的是最基本的 File类型的input提交的方式,上传到远程静态资源器和七牛云。

之前的文章关注的地方 主要是后端,也就是图片上传保存到哪里:

上传到自己的远程静态资源服务器参考:

java上传文件到远程服务器(一)---HttpURLConnection方式

java上传文件到远程服务器(二)---HttpClient方式

上传到七牛云服务器参考:

java上传文件到远程服务器七牛云

本章主要关注单张图片上传在Bootstrap框架中的布局和实现。(因为原生的input样式跟Bootstrap不搭,而且不支持一次上传多张图片)。

我们在之前的文章中已经在SpringMVC基础框架的基础上应用了BootStrap的后台框架,在此基础上记录 Bootstrap框架 中单张图片上传的 布局和实现。

应用bootstrap模板

基础项目源码下载地址为:

SpringMVC+Shiro+MongoDB+BootStrap基础框架

我们在基础项目中已经做好了首页index的访问。
现在就在index.jsp页面和index的路由Controller上做修改,实现Bootstrap框架 单张图片上传的 布局。

图片上传到当前项目的本地服务器路径中,如果要上传到七牛云或者远程服务器请参考前几篇文章修改后端代码。

Uploadify插件介绍

Uploadify是jQuery的一个上传插件,主要功能是批量上传文件,实现的效果非常不错,带进度显示。而且是Ajax的,省去了自己写Ajax上传功能的麻烦。不过官方提供的实例是PHP版本的,本文将详细介绍Uploadify在J2EE中的使用。

Uploadify的官网链接:http://www.uploadify.com/

里面可以看到PHP的示例,属性说明,以及控件下载地址。

分flash版(免费)和HTML5版(收费)。
官网上可以看到效果演示。

需要注意的是flash版在Safari不支持。

会报错:

Uploadify Flash Safari wrong JSESSIONID

处理起来比较麻烦。
所以建议使用HTML5版的。
HTML5版是收费的,在网上找到一个直接可用html5版本的JS。
下载地址:

uploadifyHtml5

下载解压后放到项目路径中
这里还需要一张样式图片,我们放在/res/assets/img/demoUpload.jpg路径。

JSP页面

<%@ include file="./include/header.jsp"%>
<style>
/*uploadfive上传插件背景按钮图样式*/
.upload-image {height: 200px;width: 200px;background-image: url(/res/assets/img/demoUpload.jpg);background-color: white;background-repeat: no-repeat;background-size: contain;background-origin: content-box;background-position: center;background-size: contain;background-origin: content-box;
}
</style><div id="page-wrapper"><div id="page-inner"><div class="row"><div class="col-md-12"><h1 class="page-header">单张图片上传 <small>Uploadify</small></h1></div></div><!-- /. ROW  --><form class="form-horizontal" id="test"><input type="text" value="${pic.id}" id="id" name="id" hidden/><div class="form-group"><label for="name" class="col-sm-2 control-label">名称:</label><div class="col-sm-10"><input type="text" class="form-control" id="name" name="name" value="${pic.name}"placeholder="路线名称,例如:A-F"></div></div><div class="form-group"><label class="col-sm-2 control-label">描述:</label><div class="col-sm-10"><textarea id="description" name="description" class="form-control"rows="8">${pic.description}</textarea></div></div><div class="form-group"><label for="icon" class="col-sm-2 control-label">图片</label><div class="col-sm-10"><input type="text" class="form-control" id="icon_upload_filePath" value="${pic.img}"name="img" placeholder="图片地址" readonly ref-selector=".ref-icon"/></div></div><c:if test="${pic.img!=null&&pic.img!=''}"><div class="form-group"><div class="col-sm-6 col-sm-offset-2"><button type="button" class="btn btn-danger  delete"data-loading-text="删除中..." id="img-del">删除图片</button></div></div></c:if><div class="form-group"><div class="col-sm-6 col-sm-offset-2"><imgsrc="${pic.img!=null?pic.img:'/res/assets/img/demoUpload.jpg'}"id="icon_upload_uploader"class="img-thumbnail"style="width:300px; height:300px;"></div></div><div class="form-group"><div class="col-sm-6 col-sm-offset-2"><button type="button" class="btn btn-default cancel"data-dismiss="modal">取消</button><button type="button" class="btn btn-primary save"data-loading-text="Saving...">确认</button></div></div></form>  <!-- /. ROW  --></div><!-- /. PAGE INNER  --></div><!-- /. PAGE WRAPPER  --><%@ include file="./include/footer.jsp"%>
<script type="text/javascript" src="/plugins/uploadify/jquery.uploadifive.js"></script>
<script type="text/javascript">$(document).ready(function () {//图片容器的显示图片切换var updateUploadButtonBackground = function (id, path) {path? $('#uploadifive-' + id).css('background-image', 'url(' + path + ')'): $('#uploadifive-' + id).css('background-image', 'url(/res/assets/img/demoUpload.jpg)');};//初始化图片上传容器var initImageUploader = function () {var selfId = $('#icon_upload_uploader').attr("id");var $input = $('#icon_upload_filePath');console.log($input);$('#icon_upload_uploader').uploadifive({'height': 300,'width': 300,'uploadScript': '/upload;_sid=${pageContext.session.id}','fileSizeLimit': '1200KB','buttonClass': 'upload-image img-thumbnail','buttonText': '','multi': false,'onInit': function(instance) {updateUploadButtonBackground(selfId, $input.val());},'removeCompleted': true,'onUploadComplete': function (file, data, response) {data = JSON.parse(data);if (data.code) {var url = '${hostname}' + data.result;$input.val(url);updateUploadButtonBackground(selfId, url);}}});};initImageUploader();//删除图片$('#img-del').on('click', function () {if (confirm('是否删除图片?')) {updateUploadButtonBackground('icon_upload_uploader', '/res/assets/img/demoUpload.jpg');$('#icon_upload_filePath').val('');}});$('button.save').on('click', function () {debugger;var data = $('#test').formGet();if (!data.name || (data.name.trim()).length == 0) {alert("名称不能为空.");return false;}$.ajax({type: "POST",url: "/pic/save",contentType: "application/json",data: JSON.stringify(data),success: function (result) {console.log(result);if (!result.code) {$('#test').formSet(data);alert(result.msg);} else {alert(result.msg);}},error: function (result) {alert("出错了,请稍后重试");}});});});</script></body></html>

返回信息辅助实体类

AjaxResult.java

package com.test.util;import org.springframework.data.annotation.Transient;/*** AjaxResult* * 标准化的ajax响应, 取代之前直接返回结果的方式。* */
public class AjaxResult {@Transientpublic static final int CODE_SUCCESS = 1;@Transientpublic static final int CODE_FAILURE = 0;@Transientpublic static final AjaxResult RESULT_ERROR = new AjaxResult(CODE_FAILURE, "执行出错了", null);@Transientpublic static final AjaxResult RESULT_SUCCESS = new AjaxResult(CODE_SUCCESS, null, null);@Transientpublic static final AjaxResult RESULT_INVAILD_PARAMETER = new AjaxResult(CODE_FAILURE, "参数格式不正确", null);private int code = CODE_FAILURE;private String error;private Object result;public static AjaxResult resultError(String error) {return new AjaxResult(CODE_FAILURE, error, null);}public static AjaxResult resultSuccess(Object result) {return new AjaxResult(CODE_SUCCESS, null, result);}/*** @param code* @param error* @param result*/public AjaxResult(int code, String error, Object result) {super();this.code = code;this.error = error;this.result = result;}/*** @return the code*/public int getCode() {return code;}/*** @param code*            the code to set*/public void setCode(int code) {this.code = code;}/*** @return the error*/public String getError() {return error;}/*** @param error*            the error to set*/public void setError(String error) {this.error = error;}/*** @return the result*/public Object getResult() {return result;}/*** @param result*            the result to set*/public void setResult(Object result) {this.result = result;}
}

JSONResult.java

package com.test.util;/*** JSONResult* 标准化的JSON响应* * <pre>* {@link JSONResult#success(Object)}* {@link JSONResult#error(String)}* </pre>* * */
public class JSONResult {/*** 成功的代码*/public static final int            CODE_SUCCESS            = 0;/*** 错误的代码,可根据错误类型进行详细分类*/public static final int           CODE_ERROR              = -1;/*** 空白的成功响应*/public static final JSONResult  RESULT_SUCCESS_NO_DATA  = new JSONResult(CODE_SUCCESS, null, null);private int                     code;private String                 msg;private Object                  data;/*** 创建一个成功的响应* * @param data* @return*/public static JSONResult success(Object data) {return new JSONResult(CODE_SUCCESS, null, data);}/*** 创建一个错误的响应* * @param msg* @return*/public static JSONResult error(String msg) {return new JSONResult(CODE_ERROR, msg, null);}/*** @param code* @param msg* @param data*/public JSONResult(int code, String msg, Object data) {this.code = code;this.setMsg(msg);this.data = data;}public int getCode() {return code;}public JSONResult setCode(int code) {this.code = code;return this;}public Object getData() {return data;}public JSONResult setData(Object data) {this.data = data;return this;}public String getMsg() {return msg;}public JSONResult setMsg(String msg) {this.msg = msg;return this;}}

Pic.java

package com.test.domain.entity;public class Pic {private String id;private String name;private String description;private String img;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getDescription() {return description;}public void setDescription(String description) {this.description = description;}public String getImg() {return img;}public void setImg(String img) {this.img = img;}
}

页面路由控制器

IndexController.java

package com.test.web.controller;import java.io.IOException;import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;import com.test.domain.entity.Pic;
import com.test.util.JSONResult;/*** IndexController* * */
@Controller
public class IndexController {@RequestMapping("/")public String index(Model model) throws IOException {model.addAttribute("hostname", "http://127.0.0.1:8080/");return "/index";}@RequestMapping("/pic/save")@ResponseBodypublic JSONResult saveMigrateLine(@RequestBody Pic pic) {//保存pic记录//int result = save(pic);int result =1;return result > 0 ? JSONResult.success(pic):JSONResult.error("保存失败!");}
}

文件上传接收控制器

UploadController.java

package com.test.web.controller;import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;import com.test.util.AjaxResult;/*** 通用的上传(保存到本地服务器)* */
@Controller
public class UploadController {private final Logger logger = LoggerFactory.getLogger(getClass().getName());/*** 上传到服务器,文件名称随机生成(基本可以保证不重复)* * @param request* @param response* @return AjaxResult 存储的文件的相对路径* @throws IOException */@RequestMapping("/upload")@ResponseBodypublic AjaxResult upload(HttpServletRequest request, HttpServletResponse response) throws IOException {try {String filePath="/uploadfile";//获取文件存储路径  (虚拟目录映射为本机服务器的实际目录)String path = request.getSession().getServletContext().getRealPath(filePath); //如果保存在ROOT里,重新发包后静态资源会丢失,所以保存在ROOT包的上级路径webapp中path=path.replace("ROOT\\", "");String fileNameResult ="";// 判断enctype属性是否为multipart/form-data  boolean isMultipart = ServletFileUpload.isMultipartContent(request);  if (!isMultipart)  throw new IllegalArgumentException(  "上传内容不是有效的multipart/form-data类型.");  // Create a factory for disk-based file items  DiskFileItemFactory factory = new DiskFileItemFactory();  // Create a new file upload handler  ServletFileUpload upload = new ServletFileUpload(factory);  // Parse the request  List<?> items = upload.parseRequest(request);  Iterator iter = items.iterator();  while (iter.hasNext()) {  FileItem item = (FileItem) iter.next();  if (item.isFormField()) {  // 如果是普通表单字段  String name = item.getFieldName();  String value = item.getString();  // ...  } else {  // 如果是文件字段  String fieldName = item.getFieldName();  String fileName = item.getName();  String contentType = item.getContentType();  boolean isInMemory = item.isInMemory();  long sizeInBytes = item.getSize();  String fileExt = fileName.substring(fileName.lastIndexOf('.'));String fileNameNew =getFileNameNew()+fileExt;fileNameResult=fileNameNew;//保存到本地InputStream uploadedStream = item.getInputStream();  savePic(path,uploadedStream,fileNameNew);uploadedStream.close();  }  }  return AjaxResult.resultSuccess(filePath+"/"+fileNameResult);} catch (FileUploadException e) {logger.warn(e.getMessage(), e);return AjaxResult.resultError(e.getMessage());}}private void savePic(String path,InputStream inputStream, String fileName) {OutputStream os = null;try {// 2、保存到临时文件// 1K的数据缓冲byte[] bs = new byte[1024];// 读取到的数据长度int len;// 输出的文件流保存到本地文件File tempFile = new File(path);if (!tempFile.exists()) {tempFile.mkdirs();//如果图片是保存在ROOT项目外,首次创建目录,tomcat加载需要时间,所以需要延迟10秒Thread.sleep(10000);}os = new FileOutputStream(tempFile.getPath() + File.separator + fileName);// 开始读取while ((len = inputStream.read(bs)) != -1) {os.write(bs, 0, len);}} catch (IOException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();} finally {// 完毕,关闭所有链接try {os.close();inputStream.close();} catch (IOException e) {e.printStackTrace();}}}private String getFileNameNew() {SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMddHHmmssSSS");return fmt.format(new Date());}}

目前上传的文件是接收后保存到本地服务器中,如果要上传到远程服务器或者七牛云等,只需要修改UploadController.java即可。

这里只给出了 uploadify 上传图片的案例。 但其实 这个DEMO也可以用于上传 zip等文件。 只需要稍微调整jsp页面把图片显示去掉即可。

效果图

Bootstrap框架----单张图片上传实现---Uploadify插件相关推荐

  1. 为什么手机上传图片这么慢 前端_解决BootStrap Fileinput手机图片上传显示旋转问题_心病_前端开发者...

    最近因为项目需要用到了bootstrap fileinput的插件,在使用苹果手机上传图片预览时,发现图片方向和手机本地存储方向不一致问题.后来通过查询资料了解图片具有EXIF(Exchangeabl ...

  2. 单张图片上传预览【超简洁,未完待续】

    http://www.cnblogs.com/ordinaryk/p/6277451.html 1.单张图片上传之前前端预览 <!DOCTYPE html PUBLIC "-//W3C ...

  3. python修改图片大小为30kb_Python的Tornado框架实现图片上传及图片大小修改

    图片的上传 上传图片使用了表单提交, 下面是html部分, enctype="multipart/form-data"表示不对字节进行编码,上传文件类型时需指定. input标签的 ...

  4. Layui框架实现图片上传

    Layui框架实现图片上传 前言: 一直以来,图片上传总是件很麻烦的事.最近在学layui,发现layui真是极大简化了各种复杂的操作,避免了繁琐的开发. layui图片上传和传统的图片上传不同,它并 ...

  5. ssm上传文件获取路径_ssm框架实现图片上传显示并保存地址到数据库(示例代码)...

    本案例是通过springmvc+spring+mybatis框架以商品上传为例,实现的图片上传功能,并把图片的地址保存到数据库并在前台显示上传的图片. 本项目是使用maven搭建的项目,首先看下项目结 ...

  6. Django框架实现图片上传,存储和显示功能

    在django框架中,前端页面不能直接使用相对路径或绝对路径显示图片,需要通过urls.py来提供每个URL 对应的django的函数来显示在页面 . 思路:将form表单上传的文件,后台接受后创建文 ...

  7. 商城项目笔记一:搭建Maven工程,利用Dubbo实现SOA面向服务框架,部署zookeeper注册中心,FastDFS框架实现图片上传,部署nginx服务器。

    文章目录 1. 商城项目总结笔记: 1.1. 第一天工作记录:搭建Maven工程 1.2. 第二天工作记录:创建SOA面向服务架构,通过工具类实现分页技术 1.3. 第三天工作记录:部署nginx服务 ...

  8. spring框架的图片上传

    使用MultipartFile实现图片上传 MultipartFile为org.springframework.web.mutipart包下的一个类是spring框架为我们提供的, 我们就使用它来完成 ...

  9. 微信头像单张图片上传

    后台配置 public function upload_img($img){import('ORG.Tencent.Weixin');$wx = new Weixin(get_app_config() ...

最新文章

  1. 混合云备份利用自定义Workflow保护MySQL的实践
  2. python 二维数组赋值_python日常注意小知识集锦
  3. SAP:查找某个请求号的传输者是谁
  4. Oracle笔记之表空间
  5. mysql获取当前时间,及其相关操作
  6. python去重且顺序不变_Python中list去重且保持原顺序不变的方法
  7. 除了工商银行,目前中国还有那些宇宙级别的企业?
  8. 可以闭眼入的O'REILLY机器学习神书出新版了!
  9. 编写一个脚本判断某个用户是否处在活动模式_使用 TypeScript 编写爬虫
  10. JAVA之NIO按行读写大文件,完美解决中文乱码问题
  11. linux无缝升级的版本,Angular 1 和 Angular 2 集成:无缝升级的方法
  12. Spring Security(5):自定义决策
  13. UnityShader30:预编译指令multi_complie和shader_feature
  14. python websocket django vue_Python Django Vue 项目创建过程详解
  15. calipso是什么意思_library是什么意思_library的翻译_音标_读音_用法_例句_爱词霸在线词典...
  16. 分享几个不错的流程图制作网站
  17. 35岁后,互联网数据分析人的出路在哪里?
  18. Windows 10系统时间显示不正确
  19. 地理信息系统(GIS)系列——绪论
  20. 360搜索“触链”聚焦版权领域,“图刻”是噱头还是不忘安全初心?

热门文章

  1. IOS 传感器Core Motion相关简述
  2. django项目创建命令
  3. 计算机网络-层级架构
  4. php计算用户实际付的金额,复盘微信支付金额不正确问题—PHP浮点型计算
  5. 智慧城市-物联网的衍生物
  6. 【知识总结】数学必修四、必修五三角函数公式总结
  7. JS实现随机数验证码
  8. 关于屏幕背光无法达到标准值
  9. 编译原理之语法分析(预测分析法)
  10. 如何做好企业流程管理,提高团队工作效率