[TOC]
# 上傳文件
## 步驟 1 : 先運行,看到效果,再學習
先將完整的項目(向老師要相關資料),配置運行起來,確認可用之后,再學習做了哪些步驟以達到這樣的效果。
## 步驟 2 : 模仿和排錯
在確保可運行項目能夠正確無誤地運行之后,再嚴格照著教程的步驟,對代碼模仿一遍。
模仿過程難免代碼有出入,導致無法得到期望的運行結果,此時此刻通過比較**正確答案** ( 可運行項目 ) 和自己的代碼,來定位問題所在。
采用這種方式,**學習有效果,排錯有效率**,可以較為明顯地提升學習速度,跨過學習路上的各個檻。
## 步驟 3 : 效果
訪問地址:
`http://127.0.0.1:8080/springmvc/upload.jsp`
這個通過springmvc上傳圖片,選擇jpg文件進行上傳,并顯示的效果

## 步驟 4 : 配置web.xml允許訪問*.jpg
在web.xml中新增加一段
~~~
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.jpg</url-pattern>
</servlet-mapping>
~~~
表示允許訪問*.jpg。
為什么要加這一段呢? 因為配置springmvc的servlet的時候,使用的路徑是"/",導致靜態資源在默認情況下不能訪問,所以要加上這一段,**允許訪問**jpg。 并且必須加在springmvc的servlet之前
如果你配置spring-mvc使用的路徑是/*.do,就不會有這個問題了。
注: 這里僅僅是允許訪問jpg,如果你要顯示png,gif那么需要額外進行配置,注意允許訪問是指瀏覽通過地址可以直接訪問。不加這段不影響上傳到服務器,也就是無論有沒有這段,都可以上傳到服務器,只是影響訪問。本身這個語句是對靜態資源是否可訪問的配置,和上傳沒有關系。
~~~
<?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" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>springmvc</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.jpg</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
~~~
## 步驟 5 : 配置springmvc-servlet.xml
新增加一段配置
~~~
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
~~~
開放對上傳功能的支持
~~~
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="com.dodoke.controller"></context:component-scan>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/page/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!-- id必須是multipartResolver,內部綁定好,不能改動 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
</beans>
~~~
## 步驟 6 : upload.jsp 上傳頁面
在WebContent中,創建upload.jsp,注意不是WEB-INF文件夾。
上傳頁面,需要注意的是form 的兩個屬性必須提供
method="post" 和 enctype="multipart/form-data" 缺一不可
上傳組件 增加一個屬性 `accept="image/*" `表示只能選擇圖片進行上傳
留意 `<input type="file" name="image" accept="image/*" />` 這個image,后面會用到這個image
~~~
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="uploadImage" method="post" enctype="multipart/form-data">
選擇圖片:<input type="file" name="image" accept="image/*" /><br>
<input type="submit" value="上傳">
</form>
</body>
</html>
~~~
## 步驟 7 : 準備UploadedImageFile
在UploadedImageFile中封裝MultipartFile類型的字段 image ,用于接受頁面的注入。
這里的字段 image必須和上傳頁面upload.jsp中的image
<input type="file" name="image" accept="image/*" />
保持一致
~~~
package com.dodoke.pojo;
import org.springframework.web.multipart.MultipartFile;
public class UploadedImageFile {
MultipartFile image;
public MultipartFile getImage() {
return image;
}
public void setImage(MultipartFile image) {
this.image = image;
}
}
~~~
## 步驟 8 : UploadController 上傳控制器
新建類UploadController 作為上傳控制器
準備方法upload 映射上傳路徑/uploadImage
1. 方法的第二個參數UploadedImageFile 中已經注入好了 image
2. 通過 RandomStringUtils.randomAlphanumeric(10);獲取一個隨機文件名。 因為用戶可能上傳相同文件名的文件,為了不覆蓋原來的文件,通過隨機文件名的辦法來規避
3. 根據request.getServletContext().getRealPath 獲取到web目錄下的image目錄,用于存放上傳后的文件。
4. 調用file.getImage().transferTo(newFile); 復制文件
5. 把生成的隨機文件名提交給視圖,用于后續的顯示
~~~
package com.dodoke.controller;
import java.io.File;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.xwork.RandomStringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import com.dodoke.pojo.UploadedImageFile;
@Controller
public class UploadController {
@RequestMapping("/uploadImage")
public ModelAndView upload(HttpServletRequest request, UploadedImageFile file)
throws IllegalStateException, IOException {
// 獲取隨機文件名
String name = RandomStringUtils.randomAlphanumeric(10);
// 獲取原有文件名稱(包括文件類型)
String fileName = file.getImage().getOriginalFilename();
// 截取文件類型
int indexdot = fileName.indexOf(".");
String suffix = fileName.substring(indexdot);
// 創建文件,給文件起名字
String newFileName = name + suffix;
// 創建 File對象,并設定存放位置和存放文件的文件名
File newFile = new File(request.getServletContext().getRealPath("/image"), newFileName);
// 調用newFile這個實例的getParentFile方法, 返回它的父目錄對象的實例,得到父目錄實例后,接著調用.mkdirs()(是父目錄這個實例調用的),創建文件夾。
newFile.getParentFile().mkdirs();
// 復制文件,把圖片寫入磁盤
file.getImage().transferTo(newFile);
ModelAndView mav = new ModelAndView("showUploadedFile");
mav.addObject("imageName", newFileName);
return mav;
}
}
~~~
## 步驟 9 : showUploadedFile.jsp 顯示圖片的頁面
在WEB-INF/page 下新建文件showUploadedFile 顯示上傳的圖片
~~~
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<img alt="" src="image/${imageName }">
</body>
</html>
~~~
## 步驟 10 : 測試
訪問頁面
`http://127.0.0.1:8080/springmvc/upload.jsp`
選擇jpg文件進行上傳

## 常見問題
1. 上傳之后跳轉頁面報錯
> 檢查下你的UploadController, 是否加上了@Controller注解,或者檢查下展示圖片的jsp的路徑名(showUploadedFile)是否和UploadController中返回的一致。
2. 圖片上傳到哪里
> 因為是在Eclpise中啟動的內置Tomcat,而內置Tomcat部署web應用,就是會上傳到服務器上,如果是默認tomcat配置,我的是在下列文件中D:\project\spring\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\springmvc\image,其實圖片是在你配置Tomcat那個server.xml配置的路徑的項目下的image文件夾中。
> **注意不是上傳到項目中**
- 數據庫
- 數據庫介紹
- MySQL的安裝
- SQL
- 表基本操作
- 修改數據語句
- 數據檢索操作
- 多表數據操作
- 練習題
- JAVA
- JAVA 介紹
- JAVA 運行原理
- JDK 配置
- 類和對象
- 數據類型
- 變量
- 直接量
- 運算符
- 流程控制
- 數組結構
- 面向對象
- 隱藏和封裝
- 深入構造器
- 類的繼承
- 多態
- 包裝類
- final 修飾符
- 抽象類
- 接口
- 集合框架
- 常用類學習
- 設計模式-單例模式
- 異常處理
- JDBC
- JSP&Servlet
- Web應用
- Tomcat
- JSP
- Scriptlet
- Page 指令
- 包含指令
- 跳轉指令
- 用戶注冊實例
- JSP練習
- 內置對象
- Servlet
- 過濾器
- Web分層思想
- EL表達式
- JSTL
- 分頁實現
- AJAX&JSON
- 開發步驟
- 路徑問題
- Log4j
- Mybatis框架
- 框架介紹
- Mybatis簡單實現
- 表基本操作
- 優化配置文件
- 表字段名與實體類屬性名不同的解決方案
- 一對一關聯
- 一對多關聯
- Spring框架
- IOC/DI
- 注入對象
- 注解方式 IOC/DI
- AOP
- 注解方式AOP
- 注解方式測試
- Spring MVC框架
- Hello SpringMVC
- 視圖定位
- 注解方式
- 接受表單數據
- 客戶端跳轉
- Session
- 中文問題
- 上傳文件
- SSM整合
- 整合步驟
- 分頁
- PageHelper
- 連接池
- CRUD
- 事務管理
- JSON
- Maven
- 介紹
- 下載與配置MAVEN
- MAVEN倉庫
- ECLIPSE中的MAVEN設置
- ECLIPSE下創建MAVEN風格的JAVA項目
- 添加JAR包
- 創建MAVEN風格的JAVA WEB項目
- 創建SSM項目
- 使用ECLIPSE導入一個MAVEN風格的SSM項目
- 教學管理
- 學員名錄
- 周測統計
- 20180608
- 20180706
- 20180721
- 課堂作業
- 練習