本文介紹使用 SpringMVC + ajaxfileupload.js 實現 ajax 上傳檔案。
先看效果圖
點選上傳檔案框,觸發上傳檔案方法,然後後臺返回圖片的 url,進行顯示。
實現方法如下
一、前臺程式碼
1、add.jsp (或者 html 檔案)
- <input type="file" name="file" id="file" onchange="uploadImg()">
- <input type="hidden" name="avatar" id="avatar">
- <img src="" alt="" id="avatarShow" width="100px" height="100px">
2、引入 jquery 和 ajaxfileupload.js
- <script src="${pageContext.request.contextPath}/static/js/jquery.min.js"></script>
- <script src="${pageContext.request.contextPath}/static/js/ajaxfileupload.js"></script>
這裡給出 ajaxfileupload.js 下載地址,網上也有下載
這裡有個坑,詳情看這裡 使用ajaxfileupload.js上傳檔案成功之後,沒有執行success方法
3、ajax 程式碼
- <script>
- //ajax提交資訊
- function uploadImg() {
- if($("#file").val() != "") {
- $.ajaxFileUpload({
- type: "POST",
- url:"${pageContext.request.contextPath}/uploadFile",
- dataType: "json",
- fileElementId:"file", // 檔案的id
- success: function(d){
- if(d.code == 0) {
- //alert("上傳成功");
- //圖片顯示
- $("#avatar").attr("value",d.data.url);
- $("#avatarShow").attr("src",d.data.url);
- }
- },
- error: function () {
- alert("上傳失敗");
- },
- });
- } else {
- alert("請先選擇檔案");
- }
- }
- </script>
需要放在 上面兩個庫的後面
注意:
① type 填 post
② 第8行的 dataType 是小寫的 json,不要寫成大寫的啦
③ 第9行的 fileElementId 填檔案框的id
④ 先確保 url 沒寫錯
二、後臺程式碼
1、給 maven 新增依賴
①、首先需要匯入 json 的依賴
- <!-- jackson -->
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-databind</artifactId>
- <version>2.5.0</version>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-core</artifactId>
- <version>2.5.0</version>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-annotations</artifactId>
- <version>2.5.0</version>
- </dependency>
②、然後需要上傳檔案的依賴
- <dependency>
- <groupId>commons-fileupload</groupId>
- <artifactId>commons-fileupload</artifactId>
- <version>1.3.1</version>
- </dependency>
- <dependency>
- <groupId>commons-io</groupId>
- <artifactId>commons-io</artifactId>
- <version>2.4</version>
- </dependency>
2、spring-mvc.xml
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:mvc="http://www.springframework.org/schema/mvc"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:context="http://www.springframework.org/schema/context"
- xsi:schemaLocation="
- http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
- http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context-3.1.xsd
- http://www.springframework.org/schema/mvc
- http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd" >
- <!-- 啟用SpringMVC的註解功能,它會自動註冊HandlerMapping、HandlerAdapter、ExceptionResolver的相關例項 -->
- <mvc:annotation-driven />
- <!-- SpringMVC的掃描範圍 -->
- <context:component-scan base-package="com.liuyanzhao.blog.controller" use-default-filters="false">
- <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
- <context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
- </context:component-scan>
- <!-- 用於返回json格式 -->
- <bean id="mappingJacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
- <property name="supportedMediaTypes">
- <list>
- <value>application/x-www-form-urlencoded;charset=UTF-8</value>
- </list>
- </property>
- </bean>
- <!-- 完成請求和註解POJO的對映 -->
- <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
- <property name="messageConverters">
- <list >
- <ref bean="mappingJacksonHttpMessageConverter" />
- </list>
- </property>
- </bean>
- <!-- 配置SpringMVC的檢視解析器 -->
- <!-- 其viewClass屬性的預設值就是org.springframework.web.servlet.view.JstlView -->
- <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
- <!-- <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /> -->
- <property name="prefix" value="/WEB-INF/views/" />
- <property name="suffix" value=".jsp" />
- </bean>
- <!--檔案上傳-->
- <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
- <!--設定上傳最大尺寸為50MB-->
- <property name="maxUploadSize" value="52428800"/>
- <property name="defaultEncoding" value="UTF-8"/>
- <property name="resolveLazily" value="true"/>
- </bean>
- </beans>
上面是 spring-mvc.xml 所有的程式碼
一定要新增 檔案上傳 那塊程式碼(50-55行)
然後 31-38 行的 物件轉成JSON 也要正確
3、UploadFileController.java
- package com.liuyanzhao.blog.controller;
- import com.liuyanzhao.blog.vo.ResultVO;
- import com.liuyanzhao.blog.vo.UploadFileVO;
- import org.springframework.data.repository.query.Param;
- import org.springframework.stereotype.Controller;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RequestMethod;
- import org.springframework.web.bind.annotation.ResponseBody;
- import org.springframework.web.multipart.MultipartFile;
- import java.io.File;
- import java.io.IOException;
- import java.util.Calendar;
- @Controller
- public class UploadFileController {
- //上傳檔案
- @RequestMapping(value = "/uploadFile",method = RequestMethod.POST)
- @ResponseBody
- public ResultVO uploadFile(@Param("file")MultipartFile file) throws IOException {
- //本地使用,上傳位置
- String rootPath ="/Users/liuyanzhao/Documents/uploads/";
- //String rootPath ="/www/uploads/";
- //檔案的完整名稱,如spring.jpeg
- String filename = file.getOriginalFilename();
- //檔名,如spring
- String name = filename.substring(0,filename.indexOf("."));
- //檔案字尾,如.jpeg
- String suffix = filename.substring(filename.lastIndexOf("."));
- //建立年月資料夾
- Calendar date = Calendar.getInstance();
- File dateDirs = new File(date.get(Calendar.YEAR)
- + File.separator + (date.get(Calendar.MONTH)+1));
- //目標檔案
- File descFile = new File(rootPath+File.separator+dateDirs+File.separator+filename);
- int i = 1;
- //若檔案存在重新命名
- String newFilename = filename;
- while(descFile.exists()) {
- newFilename = name+"("+i+")"+suffix;
- String parentPath = descFile.getParent();
- descFile = new File(parentPath+File.separator+dateDirs+File.separator+newFilename);
- i++;
- }
- //判斷目標檔案所在的目錄是否存在
- if(!descFile.getParentFile().exists()) {
- //如果目標檔案所在的目錄不存在,則建立父目錄
- descFile.getParentFile().mkdirs();
- }
- //將記憶體中的資料寫入磁碟
- file.transferTo(descFile);
- //完整的url
- String fileUrl = "/uploads/"+dateDirs+ "/"+newFilename;
- ResultVO resultVO = new ResultVO();
- resultVO.setCode(0);
- resultVO.setMsg("成功");
- UploadFileVO uploadFileVO = new UploadFileVO();
- uploadFileVO.setTitle(filename);
- uploadFileVO.setUrl(fileUrl);
- resultVO.setData(uploadFileVO);
- return resultVO;
- }
- }
注意:
① 一定要加 @ResponseBody 註解,加了 @ResponseBody 註解,我們返回的 resultVO 物件會轉成 JSON 返回前臺。這個依賴於前面說的 spirng-mvc.xml 裡的 JSON 配置
② 返回給前臺的 JSON 格式如下
所以我這裡封裝了物件 resultVO 和 uploadFileVO 具體類下面會給出
③ 記得要修改第30行的本地路徑,這個路徑待會兒還要配靜態資源對映
4、ResultVO.java 和 UploadFileVO.java
① ResultVO.java
- package com.liuyanzhao.blog.VO;
- /**
- * @author 言曌
- * @date 2017/11/30 下午7:04
- */
- public class ResultVO<T> {
- //錯誤碼
- private Integer code;
- //提示資訊
- private String msg;
- //返回的具體內容
- private T data;
- public Integer getCode() {
- return code;
- }
- public void setCode(Integer code) {
- this.code = code;
- }
- public String getMsg() {
- return msg;
- }
- public void setMsg(String msg) {
- this.msg = msg;
- }
- public T getData() {
- return data;
- }
- public void setData(T data) {
- this.data = data;
- }
- }
這裡的 T 表示泛型
② UploadFileVO.java
- package com.liuyanzhao.blog.VO;
- /**
- * @author 言曌
- * @date 2017/11/30 下午7:41
- */
- public class UploadFileVO {
- private String url;
- private String title;
- public String getUrl() {
- return url;
- }
- public void setUrl(String url) {
- this.url = url;
- }
- public String getTitle() {
- return title;
- }
- public void setTitle(String title) {
- this.title = title;
- }
- }
因為這裡是上傳圖片,我們需要給前臺返回返回一個 檔案的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> 裡新增
- <!-- 增加的靜態資源對映配置 -->
- <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