文件的上传和下载
本文讲解的是如何使用SpringMVC框架进行单文件上传,多文件以及文件下载。文件上传是Web应用经常需要面对的问题。对于Java应用而言上传文件有多种方式,包括使用文件流手工编程上传,基于commons-fileupload组件的文件上传,基于Servlet3及以上版本的文件上传等方式。本文重点介绍如何使用SpringMVC框架进行文件上传。
github项目代码:https://github.com/chegy218/ssm-review/tree/master/fileupload
文件上传
Spring MVC框架的文件上传是基于commons-fileupload组件的文件上传,只不过Spring MVC框架在原有文件上传组件上做了进一步封装,简化了文件上传的代码实现,取消了不同上传组件上的编程差异。
因此,需要commons-fileupload-1.3.1.jar和commons-io-2.4.jar。
现在,讲述一下如何下载JAR包,搞不懂****上为什么有那么多人C币去下载别人上传的JAR包,现在介绍一个免费方法去下载JAR包,使用Maven Repository(JAR包仓库)
1,进入Maven官网(百度搜索Maven就可找到官网)
https://mvnrepository.com/
2,官网搜索JAR包的名字
点击红圈内的链接。
3,选择点击JAR版本(一般选下载人数较多的)4,点击jar即可下载
----单文件上传
1,POJO类
public class FileDomain {
private String description;
private MultipartFile myfile;
//省略setter和getter
2,控制器类
@Controller
public class FileUploadController {
//得到一个用来记录日志的对象,这样在打印信息时能够标记打印的是哪个类的信息
private static final Log logger = LogFactory.getLog(FileUploadController.class);
/**
* 单文件上传
* @param fileDomain
* @param request
* @return
*/
@RequestMapping("/onefile")
public String oneFileUpload(@ModelAttribute FileDomain fileDomain,
HttpServletRequest request){
String realpath = request.getServletContext().getRealPath("uploadfiles");
logger.info(realpath);
String fileName = fileDomain.getMyfile().getOriginalFilename();
File targetFile = new File("C:/Users/Administrator/Downloads",fileName);
if(!targetFile.exists()){
targetFile.mkdirs();
}
//上传
try{
fileDomain.getMyfile().transferTo(targetFile);
logger.info("成功");
}catch(Exception e){
e.printStackTrace();
}
return "showOne";
}
3,SpringMVC配置文件
<?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:util="http://www.springframework.org/schema/util" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p"
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/util
http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 使用扫描机制扫描控制器类,控制器类都在包及其子包下 -->
<context:component-scan base-package="controller"></context:component-scan>
<!-- 视图解析器 -->
<bean id="jspViewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 前缀 -->
<property name="prefix" value="/WEB-INF/jsp/"></property>
<!-- 后缀 -->
<property name="suffix" value=".jsp"></property>
</bean>
<!-- 使用Spring的CommosMultipartResolver配置MultipartResolver用于文件上传 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"
p:defaultEncoding="UTF-8"
p:maxUploadSize="5400000"
p:uploadTempDir="fileUpload/temp">
</bean>
<!-- p:defaultEncoding="UTF-8"是请求的编码格式
p:maxUploadSize="5400000"是允许上传文件的最大值,单位为字节
p:uploadTempDir="fileUpload/temp"为上传文件的临时路径 -->
</beans>
----多文件上传
1,创建POJO类
public class MultiFileDomain {
private List<String> description;
private List<MultipartFile> myfile;
2,多文件上传处理方法
/**
* 多文件上传
*/
@RequestMapping("/multifile")
public String multiFileUpload(@ModelAttribute MultiFileDomain multiFileDomain,HttpServletRequest request){
String realpath = null;
realpath="C:/Users/Administrator/Downloads";
File targetDir = new File(realpath);
if(!targetDir.exists()){
targetDir.mkdirs();
}
List<MultipartFile> files = multiFileDomain.getMyfile();
for(int i=0; i < files.size();i++){
MultipartFile file = files.get(i);
String fileName = file.getOriginalFilename();
File targetFile = new File(realpath,fileName);
//上传
try{
file.transferTo(targetFile);
}catch(Exception e){
e.printStackTrace();
}
}
logger.info("成功");
return "showMulti";
}
文件下载
实现文件下载有两种方法:一种是通过超链接实现下载,另一种是利用程序编程实现下载。通过超链接实现下载固然简单,但暴露了下载文件的真实位置,并且只能下载存放在Web应用程序所在的目录下的文件。利用程序编码实现下载可以增加安全访问控制,还可以从任意位置提供下载的数据,可以将文件存放到Web应用程序以为的目录中,也可以将文件保存到数据库中。
@Controller
public class FileDownController {
//得到一个用来记录日志的对象,在打印时标记打印的是哪个类的信息
private static final Log logger = LogFactory.getLog(FileDownController.class);
//文件下载(图片展示)
@RequestMapping("file/download.do")
public ResponseEntity<byte[]> filedownload(String fileName) throws IOException {
String path = "C:/Users/Administrator/Downloads/"+fileName;
File file = new File(path);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file), headers, HttpStatus.CREATED);
}
/**
* 显示要下载的文件
*/
@RequestMapping("showDownFiles")
public String show(HttpServletRequest request,Model model){
String realpath = null;
realpath = "C:/Users/Administrator/Downloads";
File dir = new File(realpath);
File files[] = dir.listFiles();
//获取该目录下的所有文件名
ArrayList<String> fileName = new ArrayList<String>();
for(int i=0;i < files.length;i++){
fileName.add(files[i].getName());
}
model.addAttribute("files",fileName);
return "showDownFiles";
}
//文件下载
@RequestMapping("download.do")
public ResponseEntity<byte[]> download(String fileName) throws IOException {
String path = "C:/Users/Administrator/Downloads"+fileName;
// System.out.println("------------>哈哈哈哈哈");
File file = new File(path);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file), headers, HttpStatus.CREATED);
}
/**
* 执行下载
*/
@RequestMapping("down")
public String down(@RequestParam String filename,HttpServletRequest request,HttpServletResponse response){
String aFilePath = null; //要下载的文件路径
FileInputStream in = null; //输入流
ServletOutputStream out = null; //输出流
try {
aFilePath = "C:/Users/Administrator/Downloads";
//设置下载文件使用的报头
response.setHeader("Content-Type", "application/x-msdownload");
response.setHeader("Content-Disposition", "attachment;filename="+toUTF8String(filename));
//读入文件
in = new FileInputStream(aFilePath + "\\" +filename);
//得到响应对象的输出流,用于向客户端输出二进制数据
out = response.getOutputStream();
out.flush();
int aRead = 0;
byte b[] = new byte[1024];
while((aRead = in.read(b))!=-1 & in!=null){
out.write(b,0,aRead);
}
out.flush();
in.close();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
logger.info("下载成功");
return null;
}
/**
* 下载保存时中文文件名的字符编码转换方法
* @param str
* @return
*/
public String toUTF8String(String str){
StringBuffer sb = new StringBuffer();
int len = str.length();
for(int i=0; i < len; i++){
//取出字符中的每个字符
char c = str.charAt(i);
//Unicode码值为0~255时,不做处理
if(c>=0 && c<=255){
sb.append(c);
}else{
//转换UTF-8编码
byte b[];
try {
b = Character.toString(c).getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
b = null;
}
//转换为%HH的字符串形式
for(int j=0; j < b.length; j++){
int k = b[j];
if(k<0){
k&=255;
}
sb.append("%" + Integer.toHexString(k).toUpperCase());
}
}
}
return sb.toString();
}
}
注意:realpath,aFilePath,path都是本地的绝对路径