一、springmvc中的文件上传
1.配置文件
(1).pom文件,文件上传主要需要如下几个jar包
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
(2)mvc.xml
<?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"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 开启包扫描 -->
<context:component-scan base-package="controller"/>
<!-- 设置配置方案-->
<mvc:annotation-driven/>
<!-- 视图解析器 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- 文件上传解析器:需要注意的是这个bean的id必须是multipartResolver才能被识别,否则会报没有配置该解析器的错误 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="utf-8"></property>
<property name="maxUploadSize" value="10240000"/>
</bean>
</beans>
(3)web.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<servlet>
<servlet-name>uploadmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>uploadmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
2.编写控制类UploadController.java
第一种,单文件上传,使用MultipartFile作为方法参数接收传入的文件。
package controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
/**
* @author: **
* @date:2018/9/18 16:01
* @description:
*/
@Controller
@RequestMapping("/test")
public class UploadController {
//文件上传
@RequestMapping("/upload")
public String uploadfile(@RequestParam("file") MultipartFile multipartFile) throws IOException {
if(!multipartFile.isEmpty()){
//拼接你想存储的位置和文件名
String path = "D:/test/"+multipartFile.getOriginalFilename();
//获得项目路径即webapp所在路径,可选
//String pathRoot = request.getSession().getServletContext().getRealPath("");
File tempFile = new File(path);
if (!tempFile.exists()) {
tempFile.mkdirs();
}
try {
multipartFile.transferTo(tempFile);
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//这里除了transferTo方法,也可以用字节流的方式上传文件,但是字节流比较慢,所以还是建议用transferTo
// try {
// //获取输出流
// OutputStream os=new FileOutputStream(path);
// //获取输入流 CommonsMultipartFile 中可以直接得到文件的流
// InputStream is=multipartFile.getInputStream();
// byte[] buffer= new byte[1024];
// int len = is.read(buffer);
// while(len!=-1){
// os.write(buffer, 0, len);
// }
// os.flush();
// os.close();
// is.close();
// } catch (FileNotFoundException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
}
//可以用ModelMap或者request请求域来返回上传路径
//modelMap.addAttribute("fileUrl", path);
//或者request.setAttribute("fileUrl",path);
return "success";
}
//上传成功页面
@RequestMapping("/uploadpage")
public String uploadpage(){
return "upload";
}
}
第二种,单文件上传,利用MultipartHttpServletRequest来解析request中的文件
package controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
/**
* @author: ***
* @date:2018/9/18 16:01
* @description:
*/
@Controller
@RequestMapping("/test")
public class UploadController {
@RequestMapping("/upload")
public ModelMap upload(HttpServletRequest request, ModelMap model) {
// 先实例化一个文件解析器
CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
// 判断request请求中是否有文件上传
if (commonsMultipartResolver.isMultipart(request)) {
// 转换request
MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
// 获得文件
MultipartFile file = multiRequest.getFile("file");
if (!file.isEmpty()) {
//上传路径
String path = "D:/test/"+file.getOriginalFilename();
// 创建文件实例
File tempFile = new File(path);
if (!tempFile.exists()) {
tempFile.mkdir();
}
try {
//同样可以用流文件方式上传文件
file.transferTo(tempFile);
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//返回上传路径,方法一
model.addAttribute("fileUrl", path);
// 方法二:Request域属性
// request.setAttribute("fileUrl", path);
}
}
return model;
}
}
第三种是多文件上传,传入参数是数组或者request,多文件只是需要将上传的单个文件从数组或者request中遍历出来,然后进行单文件上传操作。
package controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
/**
* @author: ***
* @date:2018/9/18 16:01
* @description:
*/
@Controller
@RequestMapping("/test")
public class UploadController {
/**
* 多文件上传,方式一:利用MultipartFile[]作为方法的参数接收传入的文件
* 用 transferTo方法来保存图片,保存到本地磁盘。
* @author chunlynn
*/
@RequestMapping("/upload")
public ModelMap upload3(@RequestParam("file") MultipartFile[] files, ModelMap model) {
List<String> fileUrlList = new ArrayList<String>(); //用来保存文件路径
// 先判断文件files不为空
if (files != null && files.length > 0) {
for (MultipartFile file : files) { //循环遍历取出单个文件
if (!file.isEmpty()) {
String fileName = file.getOriginalFilename();
String path = "D:/test/"+fileName; //这里D:/test/可以修改为自己的路径,也可以对fileName进行修改。
// 创建文件实例
File tempFile = new File(path);
//判断父级文件夹是否存在
if (!tempFile.getParentFile().exists()) {
tempFile.getParentFile().mkdir();
}
if (!tempFile.exists()) {
tempFile.mkdir();
}
try {
//这里也可以用流实现
file.transferTo(tempFile);
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
fileUrlList.add(path);
}
}
// 方法一:model属性保存图片路径
model.addAttribute("fileUrlList", fileUrlList);
// 方法二:request域属性保存图片路径
// request.setAttribute("fileUrlList", fileUrlList);
}
return model;
}
/**
* 多文件上传,方式二:利用MultipartHttpServletRequest来解析Request中的文件
*/
@RequestMapping("/upload2")
public ModelMap upload2(HttpServletRequest request,ModelMap model) {
List<String> fileUrlList = new ArrayList<>(); //用来保存文件路径
// 先实例化一个文件解析器
CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
// 判断request请求中是否有文件上传
if (commonsMultipartResolver.isMultipart(request)) {
// 转换Request
MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
// 获得文件,方式一
List<MultipartFile> files = multiRequest.getFiles("file");
for (MultipartFile file : files) { //循环遍历取出单个文件上传
if (!file.isEmpty()) {
// 获得原始文件名,拼接需要上传的位置得到路径
String fileName = file.getOriginalFilename();
String path = "D:/test/"+fileName;
// 创建文件实例
File tempFile = new File(path); //文件保存路径为pathRoot + path
if (!tempFile.getParentFile().exists()) {
tempFile.getParentFile().mkdir();
}
if (!tempFile.exists()) {
tempFile.mkdir();
}
try {
//也可用流的方式上传
file.transferTo(tempFile);
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
fileUrlList.add(path);
}
}
model.addAttribute("fileUrlList", fileUrlList);
// 方法二:request域属性保存
// request.setAttribute("fileUrlList", fileUrlList);
}
return model;
}
}
文件下载,在这里我是写死了文件的下载路径和下载文件名的,实际项目中,这两个字段下载路径一般会配置在配置文件中,下载文件的名称则是前台通过request传递到后台的,所以这个可以将这两个字段作为传入参数,写成接口。
package controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
/**
* @author: ***
* @date:2018/9/18 16:01
* @description:
*/
@Controller
@RequestMapping("/test")
public class UploadController {
/* *
* @description: 文件下载列表
*/
@RequestMapping("/list")
public ModelAndView getlist(){
String path = "D:/test";
File directory = new File(path);
List list = new ArrayList();
File[] files = directory.listFiles();
for (File file:files) {
if (file.isFile()){
String filename = file.getName();
list.add(filename);
}
}
ModelMap modelMap = new ModelMap();
modelMap.addAttribute("list",list);
return new ModelAndView("list",modelMap);
}
/**
* 文件下载功能
* @param request,response
* @throws Exception
*/
@RequestMapping("/down")
@ResponseBody
public void down(HttpServletRequest request,HttpServletResponse response) throws Exception {
try{
String fileName = request.getParameter("filename");
String path = "D:/test/" + fileName;
File file = new File(path);
//流的形式下载文件
InputStream in = new BufferedInputStream(new FileInputStream(file));
byte[] buffer = new byte[in.available()];
in.read(buffer);
in.close();
//清空response
response.reset();
// 设置response的Header
response.addHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes()));
response.addHeader("Content-Length", "" + file.length());
OutputStream os = new BufferedOutputStream(response.getOutputStream());
response.setContentType("application/octet-stream");
os.write(buffer);
os.flush();
os.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
3.页面
upload.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>文件上传页</title>
</head>
<body>
<form action="/mvc/test/upload" method="post" enctype="multipart/form-data">
<label>上传文件</label>
<input type="file" name="file">
<input type="submit" value="提交">
</form>
</body>
</html>
注意,form表单里,enctype="multipart/form-data",一定要配置。action是你方法的访问路径,由于我在tomcat中配置了项目访问名称是mvc,所以我这里的路径会是“/mvc/test/upload”,具体路径由个人的配置而定。
还有个上传成功的提示页,自己写一个就行,不贴代码了。
list.jsp
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="java.util.*" %>
<% String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%>
<html>
<head>
<title>列表</title>
<script type="text/javascript" src="<%=basePath%>js/jquery-1.8.3.min.js"></script>
</head>
<body>
<%
List<String> list1 = (List<String>) request.getAttribute("list");
int i =1;
for (String name:list1) {
i++;
%>
<a href="/mvc/test/down/?filename=<%=name%>"><%=name%></a>
<%
}
%>
</body>
</html>