1.demo效果
2.需要特别配置的地方
3.需要的jar包
4.目录树
5.程序基本架构
6.具体代码
一,demo效果
文件上传:
文件下载:
点击即可下载。
二,需要特别配置的地方
1.负责上传文件的表单和一般表单有区别,负责上传文件的表单的编码类型必需是“multipart/form-data”
2.POJO类要设置代表文件的文件变量,类型为:MultipartFile
3.修改Springmvc的核心配置文件
Springmvc上下文中默认没有装配MultipartResolver,因此默认情况下其不能处理文件上传工作。如果想使用Spring的文件上传功能,则需要在上下文中配置MultipartResolver
(1).配置上传文件大小
(2).配置编码方式
<!-- MultipartResolver的配置 --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="maxUploadSize"><!-- 设置上传文件大小限制(10MB) --> <value>10485760</value> </property> <property name="defaultEncoding"><!-- 设置编码方式 --> <value>UTF-8</value> </property> </bean>
三,需要的jar包
四,目录树
5.程序基本架构
基于MVC结构:用户的任何请求都会映射到控制器中对应的方法进行处理
六,具体代码
(1)首先,先配置web项目自带的web.xml:主要是用来配置springmvc中的 前端控制器
前端控制器用于根据用户的请求,在控制器中找出相应的方法。(web.xml)
<?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_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>pro4</display-name> <!-- 定义springMVC的前端控制器(相当于一个servlet) --> <servlet> <!-- springMVC 控制器配置 --> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <!-- 为spring核心文件起一个别名,可任意起 --> <param-value>/WEB-INF/spring-mvc.xml</param-value> <!-- 指定spring的核心配置文件的位置 --> </init-param> <load-on-startup>1</load-on-startup> <!-- 设置启动服务器后马上进行配置 --> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <!-- 控制器的别名,要与上面的<servlet-name>一样--> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
(2)spring的核心配置文件:(spring-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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 上面是固定约束,下面是进行springmvc配置 -->
<!-- 下三行分别是,开启注解扫描,配置映射器,配置适配器,配置视图解析器 -->
<context:component-scan base-package="controller"></context:component-scan>
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"></bean>
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"></bean>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/</value> <!-- 表示要调用的文件前缀,即表示要调用的文件在/WEB-INF/路径下 -->
</property>
<property name="suffix">
<value>.jsp</value> <!-- 表示要调用的文件后缀,即表示是jsp文件 -->
</property>
</bean>
<!-- MultipartResolver的配置 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize"><!-- 设置上传文件大小限制(10MB) -->
<value>10485760</value>
</property>
<property name="defaultEncoding"><!-- 设置编码方式 -->
<value>UTF-8</value>
</property>
</bean>
</beans>
(3)POJO对象,代表文件,用于传输(User.java)
package po;
import java.io.Serializable;
import org.springframework.web.multipart.MultipartFile;
public class User implements Serializable{
private MultipartFile file; //文件,必需用MultipartFile类型
public MultipartFile getFile() {
return file;
}
public void setFile(MultipartFile file) {
this.file = file;
}
}
(4)控制器(FileController.java)
package controller; import java.io.File; import javax.servlet.http.HttpServletRequest; import org.apache.commons.io.FileUtils; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import po.User; @Controller public class FileController { /* /upload的映射,且只适用于POST方法*/ @RequestMapping(value="/upload",method=RequestMethod.POST) //参数里的user 是用来接收传来的文件的 //因为对应上传的文件,类型为MultipartFile,上传文件会自动绑定到 方法参数user里的MultipartFile成员变量 public String upload(HttpServletRequest request,User user,Model model) throws Exception{ if(!user.getFile().isEmpty()){ //path为项目目录下的files目录的路径,(getRealPath()获取绝对路径) String path = request.getSession().getServletContext().getRealPath("/files/"); //getOriginalFilename()获取上传文件的原名 String filename = user.getFile().getOriginalFilename(); File filepath = new File(path,filename); if(!filepath.getParentFile().exists()){ filepath.getParentFile().mkdirs(); } /*transferTo()将上传文件保存到一个目标文件中,separator为目录与目录之间的分隔符,如/a/b/c.txt 中的 \ 将user中的文件保存到目标位置*/ user.getFile().transferTo(new File(path+File.separator+filename)); model.addAttribute("user",user); //向模型model中加入user作为数据,给页面调用 return "downloadFile"; //返回到下载文件的页面 } return "error"; } //处理单一文件下载 @RequestMapping(value="/downloadd") public ResponseEntity<byte[]> download(HttpServletRequest request, @RequestParam("filename") String filename,Model model)throws Exception{ //获得要文件所在父目录的绝对路径 String path = request.getSession().getServletContext().getRealPath("/files/"); //获得要下载的文件的对象 File file = new File(path+File.separator+filename); HttpHeaders headers = new HttpHeaders(); //解决中文显示的编码问题,后一个UTF-8是要转编码成的编码,若前后都是一样的(如下),就需要写这句,我下面那句只是演示用 String downloadFileName = new String(filename.getBytes("UTF-8"),"UTF-8"); //通知浏览器以attachment(下载方式)打开文件 headers.setContentDispositionFormData("attachment",downloadFileName); //设置文件的MIME类型 headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); //download方法收到页面传递的文件名filename后,使用FileUpload组件的FileUtils读取项目的files文件夹下的该文件 //并将其构成ResponseEntity对象返回客户端下载 return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),headers,HttpStatus.CREATED); } /* /upload的映射,且只适用于GET方法*/ @RequestMapping(value="/upload",method=RequestMethod.GET) public String uploadForm(){ return "uploadForm"; } }
(5)文件上传视图(uploadForm.jsp)
<%@ 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> <h2>文件上传</h2> <form action="upload" enctype="multipart/form-data" method="post"><!-- 必需设置multipart/form-data编码 --> <table> <tr> <td>请选择文件:</td> <td><input type="file" name="file"></td> </tr> <tr><td><input type="submit" value="上传"></td></tr> </table> </form> </body> </html>
上述的表格是通过POST方式映射到控制器的RequestMapping值为upload 的方法中。
(6)文件下载视图(downloadFile.jsp)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@page import="java.io.File" %> <!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> <h3>文件下载</h3> <% String path = request.getSession().getServletContext().getRealPath("/files/"); File file = new File(path); File[] fs = file.listFiles(); for(File f:fs){ if(!f.isDirectory()){ String filename = f.getName(); //取出文件的名字(非绝对路径名) %> <a href="downloadd?filename=${requestScope.user.file.originalFilename}"><%out.print(filename);%></a><br> <%} }%> </body> </html>
(7)错误页面error.jsp
<%@ 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> <h1>上传失败</h1> </body> </html>