SpringMVC实现ajax上传图片实时预览

avatar 2017年11月30日22:47:04 12 7846 views
博主分享免费Java教学视频,B站账号:Java刘哥 ,长期提供技术问题解决、项目定制:本站商品点此
本文介绍使用 SpringMVC + ajaxfileupload.js 实现 ajax 上传文件。

先看效果图





点击上传文件框,触发上传文件方法,然后后台返回图片的 url,进行显示。


实现方法如下


一、前台代码


1、add.jsp (或者 html 文件)
  1. <input type="file" name="file" id="file" onchange="uploadImg()">
  2. <input type="hidden" name="avatar" id="avatar">
  3. <img src="" alt="" id="avatarShow" width="100px" height="100px">



2、引入 jquery 和 ajaxfileupload.js
  1. <script src="${pageContext.request.contextPath}/static/js/jquery.min.js"></script>
  2. <script src="${pageContext.request.contextPath}/static/js/ajaxfileupload.js"></script>

这里给出 ajaxfileupload.js 下载地址,网上也有下载

这里有个坑,详情看这里 使用ajaxfileupload.js上传文件成功之后,没有执行success方法



3、ajax 代码
  1. <script>
  2.     //ajax提交信息
  3.     function uploadImg() {
  4.         if($("#file").val() != "") {
  5.             $.ajaxFileUpload({
  6.                 type: "POST",
  7.                 url:"${pageContext.request.contextPath}/uploadFile",
  8.                 dataType: "json",
  9.                 fileElementId:"file",  // 文件的id
  10.                 success: function(d){
  11.                     if(d.code == 0) {
  12.                         //alert("上传成功");
  13.                         //图片显示
  14.                         $("#avatar").attr("value",d.data.url);
  15.                         $("#avatarShow").attr("src",d.data.url);
  16.                     }
  17.                 },
  18.                 error: function () {
  19.                     alert("上传失败");
  20.                 },
  21.             });
  22.         } else {
  23.             alert("请先选择文件");
  24.         }
  25.     }
  26. </script>

需要放在 上面两个库的后面

注意:

① type 填 post

② 第8行的 dataType 是小写的 json,不要写成大写的啦

③ 第9行的 fileElementId 填文件框的id

④ 先确保 url 没写错


二、后台代码


1、给 maven 添加依赖

①、首先需要导入 json 的依赖
  1. <!-- jackson -->
  2.     <dependency>
  3.       <groupId>com.fasterxml.jackson.core</groupId>
  4.       <artifactId>jackson-databind</artifactId>
  5.       <version>2.5.0</version>
  6.     </dependency>
  7.     <dependency>
  8.       <groupId>com.fasterxml.jackson.core</groupId>
  9.       <artifactId>jackson-core</artifactId>
  10.       <version>2.5.0</version>
  11.     </dependency>
  12.     <dependency>
  13.       <groupId>com.fasterxml.jackson.core</groupId>
  14.       <artifactId>jackson-annotations</artifactId>
  15.       <version>2.5.0</version>
  16.     </dependency>



②、然后需要上传文件的依赖
  1. <dependency>
  2.    <groupId>commons-fileupload</groupId>
  3.    <artifactId>commons-fileupload</artifactId>
  4.    <version>1.3.1</version>
  5.  </dependency>
  6.  <dependency>
  7.    <groupId>commons-io</groupId>
  8.    <artifactId>commons-io</artifactId>
  9.    <version>2.4</version>
  10.  </dependency>



2、spring-mvc.xml
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3.        xmlns:mvc="http://www.springframework.org/schema/mvc"
  4.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  5.        xmlns:context="http://www.springframework.org/schema/context"
  6.        xsi:schemaLocation="
  7.                 http://www.springframework.org/schema/beans
  8.                 http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
  9.                 http://www.springframework.org/schema/context
  10.                 http://www.springframework.org/schema/context/spring-context-3.1.xsd
  11.                 http://www.springframework.org/schema/mvc
  12.                 http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd" >
  13.     <!-- 启用SpringMVC的注解功能,它会自动注册HandlerMapping、HandlerAdapter、ExceptionResolver的相关实例 -->
  14.     <mvc:annotation-driven />
  15.     <!-- SpringMVC的扫描范围 -->
  16.     <context:component-scan base-package="com.liuyanzhao.blog.controller" use-default-filters="false">
  17.         <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
  18.         <context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
  19.     </context:component-scan>
  20.     <!-- 用于返回json格式 -->
  21.     <bean id="mappingJacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
  22.         <property name="supportedMediaTypes">
  23.             <list>
  24.                 <value>application/x-www-form-urlencoded;charset=UTF-8</value>
  25.             </list>
  26.         </property>
  27.     </bean>
  28.     <!-- 完成请求和注解POJO的映射 -->
  29.     <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
  30.         <property name="messageConverters">
  31.             <list >
  32.                 <ref bean="mappingJacksonHttpMessageConverter" />
  33.             </list>
  34.         </property>
  35.     </bean>
  36.     <!-- 配置SpringMVC的视图解析器 -->
  37.     <!-- 其viewClass属性的默认值就是org.springframework.web.servlet.view.JstlView -->
  38.     <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  39.         <!-- <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /> -->
  40.         <property name="prefix" value="/WEB-INF/views/" />
  41.         <property name="suffix" value=".jsp" />
  42.     </bean>
  43.     <!--文件上传-->
  44.     <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
  45.         <!--设置上传最大尺寸为50MB-->
  46.         <property name="maxUploadSize" value="52428800"/>
  47.         <property name="defaultEncoding" value="UTF-8"/>
  48.         <property name="resolveLazily" value="true"/>
  49.     </bean>
  50. </beans>

上面是 spring-mvc.xml 所有的代码

一定要添加 文件上传 那块代码(50-55行)

然后 31-38 行的 对象转成JSON 也要正确





3、UploadFileController.java
  1. package com.liuyanzhao.blog.controller;
  2. import com.liuyanzhao.blog.vo.ResultVO;
  3. import com.liuyanzhao.blog.vo.UploadFileVO;
  4. import org.springframework.data.repository.query.Param;
  5. import org.springframework.stereotype.Controller;
  6. import org.springframework.web.bind.annotation.RequestMapping;
  7. import org.springframework.web.bind.annotation.RequestMethod;
  8. import org.springframework.web.bind.annotation.ResponseBody;
  9. import org.springframework.web.multipart.MultipartFile;
  10. import java.io.File;
  11. import java.io.IOException;
  12. import java.util.Calendar;
  13. @Controller
  14. public class UploadFileController {
  15.     //上传文件
  16.     @RequestMapping(value = "/uploadFile",method = RequestMethod.POST)
  17.     @ResponseBody
  18.     public ResultVO uploadFile(@Param("file")MultipartFile file) throws IOException {
  19.         //本地使用,上传位置
  20.         String rootPath ="/Users/liuyanzhao/Documents/uploads/";
  21.         //String rootPath ="/www/uploads/";
  22.         //文件的完整名称,如spring.jpeg
  23.         String filename = file.getOriginalFilename();
  24.         //文件名,如spring
  25.         String name = filename.substring(0,filename.indexOf("."));
  26.         //文件后缀,如.jpeg
  27.         String suffix = filename.substring(filename.lastIndexOf("."));
  28.         //创建年月文件夹
  29.         Calendar date = Calendar.getInstance();
  30.         File dateDirs = new File(date.get(Calendar.YEAR)
  31.                 + File.separator + (date.get(Calendar.MONTH)+1));
  32.         //目标文件
  33.         File descFile = new File(rootPath+File.separator+dateDirs+File.separator+filename);
  34.         int i = 1;
  35.         //若文件存在重命名
  36.         String newFilename = filename;
  37.         while(descFile.exists()) {
  38.             newFilename = name+"("+i+")"+suffix;
  39.             String parentPath = descFile.getParent();
  40.             descFile = new File(parentPath+File.separator+dateDirs+File.separator+newFilename);
  41.             i++;
  42.         }
  43.         //判断目标文件所在的目录是否存在
  44.         if(!descFile.getParentFile().exists()) {
  45.             //如果目标文件所在的目录不存在,则创建父目录
  46.             descFile.getParentFile().mkdirs();
  47.         }
  48.         //将内存中的数据写入磁盘
  49.         file.transferTo(descFile);
  50.         //完整的url
  51.         String fileUrl =  "/uploads/"+dateDirs+ "/"+newFilename;
  52.         ResultVO resultVO = new ResultVO();
  53.         resultVO.setCode(0);
  54.         resultVO.setMsg("成功");
  55.         UploadFileVO uploadFileVO = new UploadFileVO();
  56.         uploadFileVO.setTitle(filename);
  57.         uploadFileVO.setUrl(fileUrl);
  58.         resultVO.setData(uploadFileVO);
  59.         return resultVO;
  60.     }
  61. }



注意:

① 一定要加  @ResponseBody   注解,加了 @ResponseBody 注解,我们返回的 resultVO 对象会转成 JSON 返回前台。这个依赖于前面说的 spirng-mvc.xml 里的 JSON 配置

② 返回给前台的 JSON 格式如下



所以我这里封装了对象 resultVO 和 uploadFileVO 具体类下面会给出

③ 记得要修改第30行的本地路径,这个路径待会儿还要配静态资源映射



4、ResultVO.java 和 UploadFileVO.java

① ResultVO.java
  1. package com.liuyanzhao.blog.VO;
  2. /**
  3.  * @author 言曌
  4.  * @date 2017/11/30 下午7:04
  5.  */
  6. public class ResultVO<T> {
  7.     //错误码
  8.     private Integer code;
  9.     //提示信息
  10.     private String msg;
  11.     //返回的具体内容
  12.     private T data;
  13.     public Integer getCode() {
  14.         return code;
  15.     }
  16.     public void setCode(Integer code) {
  17.         this.code = code;
  18.     }
  19.     public String getMsg() {
  20.         return msg;
  21.     }
  22.     public void setMsg(String msg) {
  23.         this.msg = msg;
  24.     }
  25.     public T getData() {
  26.         return data;
  27.     }
  28.     public void setData(T data) {
  29.         this.data = data;
  30.     }
  31. }

这里的 T 表示泛型

② UploadFileVO.java
  1. package com.liuyanzhao.blog.VO;
  2. /**
  3.  * @author 言曌
  4.  * @date 2017/11/30 下午7:41
  5.  */
  6. public class UploadFileVO {
  7.     private String url;
  8.     private String title;
  9.     public String getUrl() {
  10.         return url;
  11.     }
  12.     public void setUrl(String url) {
  13.         this.url = url;
  14.     }
  15.     public String getTitle() {
  16.         return title;
  17.     }
  18.     public void setTitle(String title) {
  19.         this.title = title;
  20.     }
  21. }

因为这里是上传图片,我们需要给前台返回返回一个 文件的URL,所以这里封装一个对象,用来拼接JSON。


三、设置静态资源映射,用于显示图片


我这里设置上传文件到 /Users/liuyanzhao/Documents/uploads 目录

比如有一张图片的本地路径为


/Users/liuyanzhao/Documents/uploads/2017/11/2017113021011541.jpg


我们想让它能在服务器上访问,需要给 Tomcat 配置静态资源映射



方法一、


使用 IDE 配置,比如我使用的是 IntelliJ IDEA 可以在 Tomcat 的配置 Development 里,如图



方法二、


如果你是直接启动本地的 Tomcat,而不是 IDE 的(不太记得 Eclipse 能不能直接设置),可以在 Tomcat 的目录下的 config/server.xml 里


我的是


/Users/liuyanzhao/Documents/JavaStudy/tomcat/apache-tomcat-7.0.37/conf/server.xml


在最后的 </Host> 里添加


  1. <!-- 增加的静态资源映射配置 -->
  2. <Context path="/uploads" docBase="/Users/liuyanzhao/Documents/uploads" reloadable="true" crossContext="true"></Context>

如图











如图,这张图片的 url 是

/uploads/2017/11/2017113022393913.jpg



http://localhost:8090/uploads/2017/11/2017113022393913.jpg





本文链接:https://liuyanzhao.com/6833.html
  • 微信
  • 交流学习,资料分享
  • weinxin
  • 个人淘宝
  • 店铺名:言曌博客咨询部

  • (部分商品未及时上架淘宝)
avatar

发表评论

avatar 登录者:匿名
匿名评论,评论回复后会有邮件通知

  

已通过评论:2   待审核评论数:0
  1. avatar 小小白

    有点看不懂,望大佬指点一下 首先异步中 function的d指的是什么,因为我异步走到那就停了, 还有controller中dateDirs 显示未定义 刚学java,希望博主不吝赐教

  2. avatar 老王

    直接复制代码就有这个效果?

    • avatar 言曌

      是的

      • avatar 言曌

        你debug调试一下

      • avatar 老王

        只能出现一个上传文本框达不到像你动图那样,