SpringMVC:文件上传,文件下载,SpringMVC的拦截器,poi组件导出excel文件

 文件上传

web开发中一般会有文件上传的操作

一般JavaWeb开发中文件上传使用的 Apache(阿帕奇)组织的Commons FileUpload组件

SpringMVC中使用  MultipartFile file对象接受上传文件,必须保证 后台参数的名称和表单提交的文件的名称一致

文件上传必须条件

  1. 表单必须post
  2. 表单必须有 file 文件域
  3. 表单的 enctype="multipart/form-data"

后台代码

SpringMVC中使用  MultipartFile file对象接受上传文件,必须保证 后台方法MultipartFile 参数的名称和表单提交的文件的名称一致

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_3_0.xsd" id="WebApp_ID" version="3.0">
  <!-- 配置SpringMVC的前端控制器(总控) -->
  <servlet>
  <servlet-name>MVC</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <init-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>classpath:springmvc.xml</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
  <servlet-name>MVC</servlet-name>
  <url-pattern>*.do</url-pattern>
  </servlet-mapping>
</web-app>

springmvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    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/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
           http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        ">
    <context:component-scan
        base-package="cn.sxt"></context:component-scan>

    <!-- 开启SpringMVC的注解驱动 -->
    <mvc:annotation-driven />
<!-- 配置文件上传解析器:bean的名字是固定的,底层使用的名称注入 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 配置属性,文件大小,内存中最大能保存多少内容 -->
    
    <!-- 设置上传文件的最大尺寸为1MB 单位 字节 -->
    <property name="maxUploadSize" value="#{1024 * 1024}"></property>

</bean>



</beans>
package cn.sxt;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

import org.apache.commons.io.FilenameUtils;
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 org.springframework.web.servlet.ModelAndView;
@Controller
public class springmvc {

    /*
     * 如果是文件上传,后台使用 MultipartFile 来接受前台对应的文件
     *     具体的文件接受使用的 Commons FileUpdate 组件 的实现类
     *  org.springframework.web.multipart.commons.CommonsMultipartFile 
     *  来完成接受文件上传的
     * 注意:前台jsp页面文件域表单的名称必须和后台参数名称一致
     *         <input type="file" name="headImg"><br>
     *         MultipartFile headImg
     * 
     * 问题: 什么文件的MIME类型?
     * 计算机上面所有的文件都有一个类型,这个类型叫做MIME类型
     * MIME类型的格式    xxx/xxx
     * tomcat/conf/web.xml有目前计算机上面所有数据类型的MIME的描述
     * 因为Tomcat要进行文件上传,要解析文件类型,所有在web.xml才有这些mieme的配置
     * 
     */
    
    @RequestMapping("/upload")
    public ModelAndView upload(@RequestParam String username,MultipartFile headImg) {
        System.out.println(username);
        String name = headImg.getName();//表单名称 <input type="file" name="headImg">
        System.out.println(name);
        String originalFilename = headImg.getOriginalFilename();//文件全名7.jpg
        System.out.println(originalFilename);
        /*
         * 文件的MIME类型
         * 判断文件是否是上传的类型
         * 
         *
         */
        String contentType = headImg.getContentType();
        System.out.println(contentType);//image/jpeg
        System.out.println(headImg.getSize());//文件大小
        
        //允许文件上传的类型
        List<String> asList = Arrays.asList("image/jpeg","image/png");
        if(!asList.contains(contentType)) {
            ModelAndView mo = new ModelAndView();
            mo.addObject("erroryMsg","no!!!!!!!!!");
            mo.setViewName("/request.jsp");
            return mo;
        }
        
        File file = new File("D:/gameproject/b");
        //判断文件是否存在,否则创建文件
        if(!file.exists()) {
            file.mkdirs();
        }
        //把用户上传的文件保存的服务器的某一个磁盘位置
        //最终把文件名称保存到对应的数据库
        try {
        //使用UUID生成新的随机文件名
        String replaceAll = UUID.randomUUID().toString().replaceAll("-", "");
        //获取文件名后缀
        String extension = FilenameUtils.getExtension(originalFilename);
        //创建新的文件名称
        String newFilename=replaceAll+"."+extension;
        File file2 = new File(file,newFilename);
        //保存文件
        
            headImg.transferTo(file2);
        } catch (IllegalStateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        return null;
        
    }
}

 多个文件上传:

package cn.sxt;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

import org.apache.commons.io.FilenameUtils;
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 org.springframework.web.servlet.ModelAndView;
@Controller
public class springmvc {
    //多个文件上传
    @RequestMapping("/uploads")
    public ModelAndView uploads(MultipartFile[] headImgs) {
        File file = new File("D:/gameproject/b");
        if(!file.exists()) {
            file.mkdirs();
        }
        
    for (MultipartFile headImg : headImgs) {

        //获取文件名称
        String filename = headImg.getOriginalFilename();
        
        //把用户上传的文件保存的服务器的某一个磁盘位置
        //最终把文件名称保存到对应的数据库
        try {
        //使用UUID生成新的随机文件名
        String string = UUID.randomUUID().toString();
        //获取文件名后缀
        String extension = FilenameUtils.getExtension(filename);
        //创建新的文件名称
        String newFilename=string+"."+extension;
        File dest = new File(file,newFilename);
        
            headImg.transferTo(dest);
        } catch (IllegalStateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }    
        
        return null;
        
    }
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<fieldset>
    <legend>单个文件上传</legend>
    <form action="${pageContext.request.contextPath}/upload.do" method="post" enctype="multipart/form-data">
        姓名: <input name="username"><br>
        头像: <input type="file" name="headImg"><span style="color:red">${erroryMsg}</span><br>
        <button type="submit">提交</button>
    </form>
</fieldset>
<fieldset>
<legend>单个文件上传</legend>
<form action="${pageContext.request.contextPath}/uploads.do" method="post" enctype="multipart/form-data">
        文件1: <input type="file" name="headImgs"><br>
        文件2: <input type="file" name="headImgs"><br>
        文件3: <input type="file" name="headImgs"><br>
        <button type="submit">提交</button>
    </form>
</fieldset>
</body>
</html>

题外:文件名称处理

    public static void main(String[] args) {
        
        //commons-io 包中有一个工具类 FilenameUtils 专门对文件名称处理
    
        String filePath = "d:/updateFile/a/b/c/d/girl.jpg";
        
        System.out.println(FilenameUtils.getBaseName(filePath));//girl
        System.out.println(FilenameUtils.getExtension(filePath));//jpg
        System.out.println(FilenameUtils.getName(filePath)); //gril.jp
        System.out.println(FilenameUtils.getFullPath(filePath)); //d:/updateFile/a/b/c/d/
        
        
        
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        
        String newFileName = uuid +"."+FilenameUtils.getExtension(filePath);
        
        System.out.println(newFileName);
        
        
        
        
        
    }

文件下载

文件下载,SpringMVC并没有做过多的封装,还是使用原来的下载方式

<a href="${pageContext.request.contextPath}/download.do?fileName=我爱.mp4">1111</a>
<a href="${pageContext.request.contextPath}/download.do?fileName=1.mp4">1111</a>
package cn.sxt;

import java.io.FileInputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;


@Controller
public class springmvc {
    /*
     * 文件下载思路
     * 1.接受前台要下载的资源的名称
     * 
     * 2.将对应的资源读取的程序内存中来
     *     Web开发不适合下载大型文件(几G的电影)
     *  只适合小型文件
     *  
     * 3.使用HttpServletReponse 把文件响应给浏览器(下载)
     * 
     */
    @RequestMapping("/download")
    public void download(String fileName,HttpServletResponse resp) throws Exception {
        //0.业务判断 (VIP,积分,充值)
        System.out.println(fileName);
     //1.根据文件名把对应的资源读取到内存来形成输入
        FileInputStream in = new FileInputStream("D:/gameproject/b/"+fileName);
        
        //2.获取文件输出流对象(用于响应数据给浏览器)
        ServletOutputStream out = resp.getOutputStream();
        

        /*
         * 浏览器分类
         *  IE 标准
         *  W3C 标准
         *   W3C 标准文件下载时候,响应给浏览器文件名称必须是 ISO-8859-1编码
         *  
         *  如果文件名称是中文,接受的时候必须是UTF-8,不然乱码
         *  
         *  所以在响应文件给浏览器的时候,我们必须将文件名的字符串编码转换成ISO-8859-1编码进行下载
         *  这样就不会出现乱码
         * 
         */
        //先以UTF-8将字符串转换成字节数组
        byte[] bytes = fileName.getBytes("UTF-8");
        
        //再以ISO-8859-1将二进制数组转换成字符串
        String string = new String(bytes,"ISO-8859-1");
        
        //响应的内容应该是以附件的形式响应给浏览器(设置响应头)
        resp.setHeader("Content-Disposition", "attachment;filename="+fileName);
        /*
         * 使用 Apache的  commons-io 工具包
         * 专门对文件的输入输出进行了封装
         * 开发者使用起来非常简单
         */
        
        IOUtils.copy(in, out);
    }
    

}

 SpringMVC的拦截器

拦截器  Interceptor

Spring MVC 的拦截器类似于Servlet 开发中的过滤器Filter,用于对Controller进行预处理和后处理。

使用SpringMVC拦截器步骤:

1)定义拦截器类,实现接口 org.springframework.web.servlet.HandlerInterceptor

2)applicationContext.xml中配置拦截器

拦截器方法的执行时机:

1):preHandle:控制器方法执行之前执行,返回结果为true表示放行,如果返回为false,表示拦截(可以做权限拦截,登录检查拦截).

2):postHandle:控制器方法执行后,视图渲染之前执行(可以加入统一的响应信息).

3):afterCompletion:视图渲染之后执行(处理Controller异常信息,记录操作日志,清理资源等)

package cn.sxt.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import cn.sxt.pojo.User;

public class CheckLoginInterceptor implements HandlerInterceptor {

    /*
     * 在控制器方法执行之前执行
     * 返回 true 放行
     * 返回 false 不放行
     * 
     */
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        /*
         * 拦截思路,从session中获取 共享的 user对象,
         * 如果有,说明已经登录
         *     放行
         * 如果对象为null,说明没有登录
         *  不放行,跳转到登录让其登录
         */
        //1.从session获取user对象
        User user =(User) request.getSession().getAttribute("user");
        if(user == null) {
            //跳转到登录页面
            //request.getRequestDispatcher("/login.jsp").forward(request, response);
            //重定向
            response.sendRedirect(request.getContextPath()+"/login.jsp");
            return false;
        }
        
        
        return true;
    }
    //postHandle:控制器方法执行后,视图渲染之前执行(可以加入统一的响应信息).
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        // TODO Auto-generated method stub
        
    }
    //afterCompletion:视图渲染之后执行(处理Controller异常信息,记录操作日志,清理资源等
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        // TODO Auto-generated method stub
        
    }

    
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    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
        ">

    <!-- 开启SpringMVC的注解驱动 -->
    <mvc:annotation-driven />
    <!-- 配置SpringMVC对静态资源的处理 -->
    <mvc:default-servlet-handler />
    <!-- 配置视图解析器 -->
    <bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- 前缀 -->
        <property name="prefix" value="/WEB-INF/view/" />
        <!-- 后缀 -->
        <property name="suffix" value=".jsp" />
    </bean>


    <!-- 配置springMVC的拦截器 -->
    <mvc:interceptors>
        <!-- 具体拦截器配置 -->
        <mvc:interceptor>
            <!-- 配置拦截的地址 ,只会拦截控制器请求(不会拦截非控制器请求 jsp,html,css,js) /* 只会拦截一级 如 /list.do 
                /delet.do /** 可以拦截多级(两级以及两级以上) /user/list.do /user/delete.do -->
            <mvc:mapping path="/**" />
            <!-- 配置放行的地址 如果放行多个地址 使用 逗号隔开 /xx/a.do,/xxx/b.do,/xxx/c.do -->
            <mvc:exclude-mapping path="/user/login.do" />
            <!-- 拦截器 -->
            <bean class="cn.sxt.interceptor.CheckLoginInterceptor"></bean>
        </mvc:interceptor>

    </mvc:interceptors>

</beans>

使用poi组件导出excel文件

使用POI组件实现Excel数据的处理.

下载路径:http://poi.apache.org/

1.导包poi

package cn.sxt.test;
import java.io.File;

import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.junit.Test;

public class POITest {

    @Test
    public void testName() throws Exception {
        //1.创建一个工作集
        HSSFWorkbook book = new HSSFWorkbook();
        //2.创建一个Sheet
        HSSFSheet sheet = book.createSheet();
        //3.创建一行,从0开始
        HSSFRow createRow = sheet.createRow(0);
        //3.1创建单元格(列)
        createRow.createCell(0).setCellValue("姓命");
        createRow.createCell(1).setCellValue("年龄");
        createRow.createCell(2).setCellValue("性别");
        for (int i = 1; i < 10; i++) {
            //没循环一次创建一行
            HSSFRow createRow2 = sheet.createRow(i);
            //创建列
            createRow2.createCell(0).setCellValue("reh命");
            createRow2.createCell(1).setCellValue("20");
            createRow2.createCell(2).setCellValue("v");
            
        }
        //同步数据到本地磁盘形成 Excel 文件
        book.write(new File("D:/用户信息.xlsx"));
    }
}

使用POI导出数据库的所有用户信息

// 导出用户信息
    @RequestMapping("/exprot")
    public void export(HttpServletResponse response) {
        
        
        //创建POI的数据对象
        HSSFWorkbook book = new HSSFWorkbook();
        //创建sheet
        HSSFSheet sheet = book.createSheet();
        //创建标题列
        HSSFRow titleRow = sheet.createRow(0);
        //创建表单单元格并设置值
        titleRow.createCell(0).setCellValue("编号");
        titleRow.createCell(1).setCellValue("姓名");
        titleRow.createCell(2).setCellValue("邮箱");
        titleRow.createCell(3).setCellValue("电话");
        
        List<User> users = service.list();
        //循环学生
        for (int i = 0; i < users.size(); i++) {
            //获取每个学生
            User user = users.get(i);
            //创建学生列
            HSSFRow row = sheet.createRow(i+1);
            //创建学生信息对应的单元格并设置数据
            row.createCell(0).setCellValue(user.getId());
            row.createCell(1).setCellValue(user.getName());
            row.createCell(2).setCellValue(user.getEmail());
            row.createCell(3).setCellValue(user.getPhone());
        }
        
        try {
            //设置响应头,响应的内容是为附件形式
            response.addHeader("Content-Disposition",
                    "attachment;filename=" + new String("学生信息.xlsx".getBytes(), "ISO-8859-1"));
            
            book.write(response.getOutputStream());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

SpringMVC 控制器 Controller的生命周期

Spring 容器创建的对象默认 都是单例 对象

SpringMVC对象 Controller的对象的创建有三种情况

Request : 在用户的一次请求中生效(用户每次请求都会创建Controller对象)多例

Session : Controller对象在一次会话中创建一个对象

如果控制器中有成员变量 设置或者赋值操作,必须使用 request 返回

原文地址:https://www.cnblogs.com/406070989senlin/p/11172467.html