SpringMVC实现文件上传下载

91 阅读2分钟

1、文件上传的步骤实现:

操作步骤1,添加jar包到工程中来;

<!-- 文件上传 commons-fileupload -->
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.4</version>
</dependency>
<!-- 文件上传 commons-io -->
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.6</version>
</dependency>

步骤2:在SpringMVC配置文件中定义一个bean 类型为CommonsMultipartResolver

在SpringMVC中专门封装了一个类CommonsMultipartResolver来处理文件上传,所以需要在 SpringMVC的配置件中加入一个bean;配置bean的代码如下:

<!--文件上传-->
<!--加入一个bean用来处理文件上传,这里采用的是commons-fileupload:commons-fileupload:1.4-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">

</bean>

步骤3:编写前台html页面:特别要注意这个action的值,确保是正确的url路径;

步骤4:编写文件上传的控制器代码:

@Controller
public class UpLoadController {

    @RequestMapping(value = "myupload", method = RequestMethod.POST)
    public String upload(HttpServletRequest request) {

        //将request 转换为 MultipartHttpServletRequest
        MultipartHttpServletRequest req = (MultipartHttpServletRequest) request;
        //得到上传的文件
        MultipartFile file = req.getFile("myfile");
        //得到文件域的名字file.getName()   得到文件名file.getOriginalFilename()
        System.out.println(file.getName()+","+file.getOriginalFilename());
        //上传的目标路径
        String path = request.getRealPath("/imgs")+"/"+file.getOriginalFilename();
        System.out.println("path :"+path);
        //创建目标文件
        File destFile = new File(path);
        try {
            //直接使用封装好的 copyInputStreamToFile 实现文件的上传功能
            FileUtils.copyInputStreamToFile(file.getInputStream(), destFile);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return "succ";
    }
}

2、文件上传的问题和扩展:

测试可以发现文件能够正常上传,只有短短的几行代码,就实现了文件的上传功能,但是依然存在如下的问题列表:

1、 除了上传文件,此表单中还传递了名字和密码元素,在控制器一侧如何进行接收?

解决方案:参数列表中增加如下代码即可.

@RequestMapping(value = "myupload", method = RequestMethod.POST)
//这两个为表单元素名字
public String upload(HttpServletRequest request, String name,String pwd) {
    System.out.println("name :"+name+",pwd :"+pwd);

2、 对上传的文件要进行类型和大小的限制该如何实现?

<bean id="multipartResolver"
      class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!-- 指定所上传文件的总大小不能超过200KB。注意maxUploadSize属性的限制不是针对单个文件,而是所有文件的容量之和 -->
    <!-- 如果超过200kb会报一个异常 -->
    <property name="maxUploadSize" value="200000"></property>
</bean>

3、异常

如果上传文件超过限制,会报一个异常,异常信息如下:

我们发现,在CommonsMultipartResolver的父类: CommonsFileUploadSupport

处理异常方案:

<!-- SpringMVC在超出上传文件限制时,会抛出org.springframework.web.multipart.MaxUploadSizeExceededException -->
<!-- 该异常是SpringMVC在检查上传的文件信息时抛出来的,而且此时还没有进入到Controller方法中 -->
<bean id="exceptionResolver"
      class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <property name="exceptionMappings">
        <props>
            <!-- 遇到MaxUploadSizeExceededException异常时,自动跳转到/WEB-INF/jsp/error_fileupload.jsp页面 --> <propkey="org.springframework.web.multipart.MaxUploadSizeExceededException">error_fileupload</prop>
        </props>
    </property>
</bean>

4、文件类型的判断:

//得到上传的文件名
MultipartFile file = req.getFile("myfile");
//得到文件的contentType
System.out.println("contentType :"+file.getContentType());

5、 如果是多文件上传代码应该如何修改呢?

【参考代码】

// 前台表单中的所有<input type="file"/>的name都应该是myfiles
@RequestMapping(value = "myuploadmulti", method = RequestMethod.POST)
public String uploadMulti(HttpServletRequest request,@RequestParam MultipartFile[] myfiles,
                          String name, String pwd) {

    System.out.println("name :" + name + ",pwd :" + pwd);
    // 将request 转换为 MultipartHttpServletRequest
    for (MultipartFile file : myfiles) {

        // 得到文件的contentType
        System.out.println("contentType :" + file.getContentType());
        // 得到文件域的名字file.getName() 得到文件名file.getOriginalFilename()
        System.out.println(file.getName() + ","
                           + file.getOriginalFilename());
        // 上传的目标路径
        String path = request.getRealPath("/imgs") + "/"
            + file.getOriginalFilename();
        System.out.println("path :" + path);
        // 创建目标文件
        File destFile = new File(path);
        try {
            // 直接使用封装好的 copyInputStreamToFile 实现文件的上传功能
            FileUtils
                .copyInputStreamToFile(file.getInputStream(), destFile);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    return "succ";
}

3、文件下载

@RequestMapping(value = "dw", method = RequestMethod.GET)
public void download(HttpServletRequest request,HttpServletResponse response,@RequestParam("fileName") String fileName) throws IOException {

    String realPath = request.getServletContext().getRealPath("/");
    File file = new File(realPath,fileName);
    //response.setContentType("application/force-download");// 设置强制下载不打开
    response.addHeader("Content-Disposition", "attachment;fileName=" + fileName);// 设置文件名
    FileInputStream is = new FileInputStream(file);
    byte[] bytes = new byte[is.available()];
    is.read(bytes);
    OutputStream os = response.getOutputStream();
    os.write(bytes);
    is.close();
    os.close();
}