SpringMVC详解(二)

1.     文件上传

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

一般JavaWeb开发中文件上传使用的 Apache组织的Commons FileUpload组件

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

 

文件上传必须条件

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

 

1.1.  拷贝jar包

 

1.2.  准备jsp页面

<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"><br>

             <button type="submit">提交</button>

         </form>

    </fieldset>

1.3.  后台代码

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

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

    @RequestMapping("/upload")

    public String singleUpload(MultipartFile headImg,@RequestParam("username")String username) throws IOException {

        

         System.out.println(headImg.getName());//获取上传文件的表单名称

         System.out.println(headImg.getContentType());//MIME类型

         System.out.println(headImg.getSize());//文件大小

         System.out.println(headImg.getOriginalFilename());//获取上传文件的完整名称

         //获取上传文件对应的输入流

         //InputStream in = headImg.getInputStream();

        

         //创建一个磁盘目录用于保存文件

         File destFile= new File("c:/upload");

         if(!destFile. ) {

             destFile.mkdir();

         }

         //使用uuid作为文件随机名称

         String fileName = UUID.randomUUID().toString().replaceAll("-", "");

         //使用FileNameUtils获取上传文件名的后缀

         String extension = FilenameUtils.getExtension(headImg.getOriginalFilename());// jpg , png 等等

         //创建新的文件名称

         String newFileName = fileName + "."+extension;

        

         //创建要保存文件的File对象

         File file = new File(destFile, newFileName);

         //保存文件到本地磁盘

         headImg.transferTo(file);

        

         return "redirect:/upload.jsp";

    }

 

 

1.4.  配置文件上传解析器

配置文件上传解析器:bean的名字是固定的

使用spring表达式 #{1024*1024}

 

<!-- 配置文件上传解析器:bean的名字是固定的,底层使用的名称注入 -->

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">

    <!-- 设置上传文件的最大尺寸为1MB -->

    <property name="maxUploadSize" value="#{1024 * 1024}"></property>

</bean>

1.5.  多文件上传

<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>

@RequestMapping("/uploads")

    public String singleUploads(MultipartFile[] headImgs) throws IOException {

        

 

         //创建一个磁盘目录用于保存文件

         File destFile= new File("c:/upload");

         if(!destFile.exists()) {

             destFile.mkdir();

         }

         for (int i = 0; i < headImgs.length; i++) {

             MultipartFile headImg = headImgs[i];

            

             //使用uuid作为文件随机名称

             String fileName = UUID.randomUUID().toString().replaceAll("-", "");

             //使用FileNameUtils获取上传文件名的后缀

             String extension = FilenameUtils.getExtension(headImg.getOriginalFilename());// jpg , png 等等

             //创建新的文件名称

             String newFileName = fileName + "."+extension;

            

             //创建要保存文件的File对象

             File file = new File(destFile, newFileName);

             //保存文件到本地磁盘

             try {

                  headImg.transferTo(file);

             } catch (Exception e) {

                  e.printStackTrace();

             }

         }

         return "redirect:/upload.jsp";

    }

2.     文件下载

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

package cn.zj.springmvc.controller;

 

import java.io.FileInputStream;

import java.io.IOException;

 

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 DownloadController {

    /*

     * 下载文件思路

     * 1. 接受需要下载文件名称,根据文件名称,找到磁盘对应的文件,读取到内存中形成一个输入流

     * 2. 将输入流通过响应对象(HttpServletResponse)响应给浏览器(下载)

     *

     * 注意:Web一般只会下载小型文件

     *

     */

    @RequestMapping("/download")

    public void upload(String fileName ,HttpServletResponse response) throws IOException {

         //0. 判断是否vip,有积分,金豆

         //TODO

        

         //1. 接受文件名,读取磁盘对应的文件,创建输入流对象

        

         FileInputStream inputStream = new FileInputStream("C:/"+fileName);

        

         //2.获取响应对象的输出流

         ServletOutputStream outputStream = response.getOutputStream();

        

        

         //3.文件下载文件名的编码使用ISO-08859-1编码

         //我们需要将我们UTF-8的 filename转换ISO-8859-1编码

         //3.1先将字符串以UTF-8转换成字节数组

         byte[] bytes = fileName.getBytes("UTF-8");

         //3.2再将字节数组以 ISO-8859-1转换字符串

         fileName = new String(bytes, "ISO-8859-1");

        

        

         //4.响应的内容应该是以附件的形式响应给浏览器(设置响应头)

         response.setHeader("Content-Disposition", "attachment;filename="+fileName);

        

         //5.响应文件给浏览器

         IOUtils.copy(inputStream, outputStream);

        

    }

   

}

 

 

3.     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异常信息,记录操作日志,清理资源等)

 

3.1.  自定义拦截器

public class CheckLoginInterceptor implements HandlerInterceptor {

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

    // true : 放行  false :不放行

    @Override

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)

             throws Exception {

        

         System.out.println("拦截器执行了......");

         //从Session中获取登录信息

         String username = (String)request.getSession().getAttribute("username");

         System.out.println(username);

        

         if(username !=null) {

             //放行

             return true;

         }else {

             //跳转到登录页面去

             response.sendRedirect(request.getContextPath()+"/login.jsp");

             return false;

         }

    }

   

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

    @Override

    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,

             ModelAndView modelAndView) throws Exception {

    }

   

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

    @Override

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)

             throws Exception {

    }

}

 

3.1.1.  拦截器的配置的配置

<?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/>

   

        

        

         <!-- 配置拦截器 :可以有多个拦截器-->

         <mvc:interceptors>

             <!--配置检查登录拦截器  -->

             <mvc:interceptor>

                 

                  <!-- 配置拦截的规则

                      只会拦截 控制器请求,不会拦截jsp页面

                      /* 

                          只能拦截一级 如 : /list.do /delete.do

                          如:/user/list.do , /user/delete.do 二级 不能拦截

                      /**

                          可以拦截多级 无论几级都可以 如  /a/b/c/d/list.do

                   -->

                  <mvc:mapping path="/**"/>

                 

                  <!-- 排除拦截的地址,多个地址使用逗号隔开

                      /user/login.do

                     

                     

                   -->

                  <mvc:exclude-mapping path="/user/login.do"/>

            

                  <!-- 拦截器的类型 -->

                  <bean class="cn.zj.ssm.interceptor.CheckLoginInterceptor"/>

            

             </mvc:interceptor>

         </mvc:interceptors>

        

        

</beans>

 

4.     使用poi组件导出excel文件

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

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

 

4.1.  入门案例

4.1.1.  导入jar包

 

4.1.2.  案例代码

    //使用POI创建excel文件到本地

    @Test

    public void testName() throws Exception {

         //1.创建数据,用于本地创建excel

         HSSFWorkbook book = new HSSFWorkbook();

         //2.创建一个sheet 工作区域

         HSSFSheet sheet = book.createSheet();

         //3.创建一行: 从0开始,代表第一行

         HSSFRow row = sheet.createRow(0);

         //4.创建一个个单元格

         HSSFCell cell1 = row.createCell(0);

         //5.设置单元格的数据

         cell1.setCellValue("张三");

        

         HSSFCell cell2 = row.createCell(1);

         cell2.setCellValue(20);

        

         //将数据保存到本地

         try {

             book.write(new File("d:/测试.xlsx"));

         } catch (Exception e) {

             e.printStackTrace();

             // TODO: handle exception

         }

    }

 

4.2.  使用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();

       }

    }

 

5.     SpringMVC 控制器 Controller的生命周期

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

 

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

 

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

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

 

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

 

posted @ 2019-07-11 18:52  沈振辉  阅读(224)  评论(0编辑  收藏  举报