SpringMVC笔记(五)

作者: linzeliang
  1. 拦截器

    1.1 拦截器和过滤器

SpringMVC的处理器拦截器类似于Servlet开发过程中的过滤器Filter,用于对处理器进行预处理和后处理。们可以自定义一些拦截器来实现特定的功能

过滤器和拦截器的区别:拦截器是AOP思想的具体应用

过滤器:

  • Servlet规范中的一部分,任何JavaWeb工程都可以使用
  • 在url-pattern中配置了/*之后,可以对所有要访问的资源进行拦截

拦截器:

  • 拦截器是SpringMVC框架自己的,只有使用了SpringMVC框架的工程才能使用

  • 拦截器指挥拦截访问的控制器方法,如果访问的是jsp/html/css/img/js是不会进行拦截的

    1.2 自定义拦截器

  • 首先编写一个类,实现HandlerInterceptor接口

    public class MyInterceptor implements HandlerInterceptor {
    
       /**
        * 在业务处理器处理请求之前被调用
        * 如果返回false
        *     从当前的拦截器往回执行所有拦截器的afterCompletion(),再退出拦截器链
        * 如果返回true
        *    执行下一个拦截器,直到所有的拦截器都执行完毕
        *    再执行被拦截的Controller
        *    然后进入拦截器链,
        *    从最后一个拦截器往回执行所有的postHandle()
        *    接着再从最后一个拦截器往回执行所有的afterCompletion()
        */
       @Override
       public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler) throws Exception {
           System.out.println("------------处理前------------");
           return true;
       }
    
       /**
        * 在业务处理器处理请求执行完成后,生成视图之前执行的动作
        * 可在modelAndView中加入数据,比如当前时间
        */
       @Override
       public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler, ModelAndView modelAndView) throws Exception {
           System.out.println("------------处理后------------");
       }
    
       /**
        * 在DispatcherServlet完全处理完请求后被调用,可用于清理资源等
        *
        * 当有拦截器抛出异常时,会从当前拦截器往回执行所有的拦截器的afterCompletion()
        */
       @Override
       public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler, Exception ex) throws Exception {
           System.out.println("------------清理------------");
       }
    }
    
  • 在springmvc配置文件中配置拦截器

    <!--关于拦截器的配置-->
    <mvc:interceptors>
       <mvc:interceptor>
           <!--/** 包括路径及其子路径-->
           <!--/admin/* 拦截的是/admin/add等等这种 , /admin/add/user不会被拦截-->
           <!--/admin/** 拦截的是/admin/下的所有-->
           <mvc:mapping path="/**"/>
           <!--bean配置的就是拦截器-->
           <bean class="com.kuang.interceptor.MyInterceptor"/>
       </mvc:interceptor>
    </mvc:interceptors>
    
  • 文件上传下载

    2.1 上传

  • 首先,表单中的enctype属性要设置为multipart/form-data,只有用这种方式,才会以二进制流的方式来处理表单数据,这种编码方式会把文件域指定文件的内容也封装到请求参数种,不会对字符进行编码,其他的一些格式:

  • application/x-www=form-urlencoded:默认方式,只处理表单中的value属性值,采用这种编码方式的表单会将表单域中的值处理成url编码方式

  • text/plain:处理个空格转换为'+'外,对其他字符都不做编码处理

  • 然后导入相关jar包,commons-fileupload

  • 配置bean:multipartResolver

    <!--文件上传配置,id必须为multipartResolver-->
    <bean id="multipartResolver"  class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
       <!-- 请求的编码格式,必须和jSP的pageEncoding属性一致,以便正确读取表单的内容,默认为ISO-8859-1 -->
       <property name="defaultEncoding" value="utf-8"/>
       <!-- 上传文件大小上限,单位为字节(10485760=10M) -->
       <property name="maxUploadSize" value="10485760"/>
       <property name="maxInMemorySize" value="40960"/>
    </bean>
    
  • CommonsMultipartFile 的 常用方法:

  • String getOriginalFilename():获取上传文件的原名

  • InputStream getInputStream():获取文件流

  • void transferTo(File dest):将上传文件保存到一个目录文件中

  • 编写Controller控制器

    @Controller
    public class FileController {
       //@RequestParam("file") 将name=file控件得到的文件封装成CommonsMultipartFile 对象
       //批量上传CommonsMultipartFile则为数组即可
       @RequestMapping("/upload")
       public String fileUpload(@RequestParam("file") CommonsMultipartFile file , HttpServletRequest request) throws IOException {
    
           //获取文件名 : file.getOriginalFilename();
           String uploadFileName = file.getOriginalFilename();
    
           //如果文件名为空,直接回到首页!
           if ("".equals(uploadFileName)){
               return "redirect:/index.jsp";
           }
           System.out.println("上传文件名 : "+uploadFileName);
    
           //上传路径保存设置
           String path = request.getServletContext().getRealPath("/upload");
           //如果路径不存在,创建一个
           File realPath = new File(path);
           if (!realPath.exists()){
               realPath.mkdir();
           }
           System.out.println("上传文件保存地址:"+realPath);
    
           InputStream is = file.getInputStream(); //文件输入流
           OutputStream os = new FileOutputStream(new File(realPath,uploadFileName)); //文件输出流
    
           //读取写出
           int len=0;
           byte[] buffer = new byte[1024];
           while ((len=is.read(buffer))!=-1){
               os.write(buffer,0,len);
               os.flush();
           }
           os.close();
           is.close();
           return "redirect:/index.jsp";
       }
    }
    
  • 或者采用file.Transto来上传文件

    @RequestMapping("/upload2")
    public String  fileUpload2(@RequestParam("file") CommonsMultipartFile file, HttpServletRequest request) throws IOException {
    
       //上传路径保存设置
       String path = request.getServletContext().getRealPath("/upload");
       //上传文件地址
       File realPath = new File(path);
       if (!realPath.exists()){
           realPath.mkdir();
       }
    
       //通过CommonsMultipartFile的方法直接写文件(注意这个时候)
       file.transferTo(new File(realPath +"/"+ file.getOriginalFilename()));
    
       return "redirect:/index.jsp";
    }
    

    2.2 下载

文件下载步骤:

  1. 设置response响应头
  2. 读取文件 -> InputStream
  3. 写出文件 -> OutputStream
  4. 执行操作
  5. 关闭流

代码实现:

@RequestMapping(value="/download")
public String downloads(HttpServletResponse response ,HttpServletRequest request) throws Exception{
    //要下载的图片地址
    String  path = request.getServletContext().getRealPath("/upload");
    String  fileName = "基础语法.jpg";

    //1、设置response 响应头
    response.reset(); //设置页面不缓存,清空buffer
    response.setCharacterEncoding("UTF-8"); //字符编码
    response.setContentType("multipart/form-data"); //二进制传输数据
    //设置响应头
    response.setHeader("Content-Disposition",
                       "attachment;fileName="+URLEncoder.encode(fileName, "UTF-8"));

    File file = new File(path,fileName);
    //2、 读取文件--输入流
    InputStream input=new FileInputStream(file);
    //3、 写出文件--输出流
    OutputStream out = response.getOutputStream();

    byte[] buff =new byte[1024];
    int index=0;
    //4、执行 写出操作
    while((index= input.read(buff))!= -1){
        out.write(buff, 0, index);
        out.flush();
    }
    out.close();
    input.close();
    return null;
}

原文创作:linzeliang

原文链接:https://www.cnblogs.com/linzeliang1222/p/14720386.html

更多推荐

更多
  • 程序计数器 M78 程序计数器简述特点作用似之处,都是取下一次的指令地址。 * PC Register在JVM里可以翻译成program counter register 程序计数器,在JVM里只存储当前执行的操作码的地址。也算是对CPU里寄存器的一种模拟
  • Java EE 学习 83 上 - SpringMVC - 基本使用方法 【Java EE 学习 83 上】【SpringMVC】【基本使用方法】一、SpringMVC框架概述二、第一个SpringMVC程序三、三种不同的URL处理器映射四、三种不同的控制器五、项目练习源代码地址  1.环境准备  2.需要的
  • Java EE 学习 83 下 - SpringMVC - 使用注解替代已过时的API - SpringMVC、Hibernate整合 - Java EE 学习 83 下SpringMVC使用注解替代已过时的APISpringMVC、Hibernate整合一、SpringMVC中注解的使用二、使用注解接收参数的方法三、重定向的方法四、SpringMVC和Hibernate的
  • 魔改swagger:knife4j的另外一种打开方式 魔改swagger:knife4j的另外一种打开方式一、两种文档聚合模式二、swagger-ui的实现原理三、swagger-register-server四、swagger-spring-boot-starter五、实战六、其它问题原
  • spring mvc请求体偷梁换柱:HandlerMethodArgumentResolver spring mvc请求体偷梁换柱:HandlerMethodArgumentResolver1.切面方法:行不通2.自定义参数解析器:偷梁换柱3.自定义参数解析器遇到的问题第一步:实现HandlerMethodArgumentReso
    狂盗一枝梅

  • 二叉树题解方法 二叉树-题解-方法递归二叉树的递归遍历二叉树的迭代遍历二叉树的统一迭代法二叉树的层序遍历翻转二叉树对称二叉树二叉树的最大深度二叉树的最小深度慢就是快!递归法迭代法递归法迭代法迭代法n叉树的最大深度使用队列使用栈/15056076.htm
  • 字符串题解方法 字符串-题解-方法反转字符串反转字符串II替换空格翻转字符串左旋转字符串实现 strStr()重复的子字符串慢就是快!KMP算法KMP有什么用什么是前缀表时间复杂度分析代码,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题
  • Hash题解方法 Hash-题解-方法有效的字母异位词两个数组的交集快乐数两数之和四数相加II赎金信三数之和慢就是快!m", t = "nagaram" 输出: true 示例 2: 输入: s = "rat", t = "car" 输出: false
  • 链表题解 链表-题解移除链表元素翻转指针两两交换链表中的节点删除链表的倒数第N个节点链表相交环形链表II慢就是快!双指针法递归实现判断链表是否有环bo/2020/2465789-20210910160233590-1213910246.png)
  • 双指针题解 双指针-题解移除元素慢就是快!数组空间,你必须仅使用 O(1) 额外空间并**原地**修改输入数组。 元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。 示例 1: 给定 nums = \[3,2,2,3\], ​ va
  • 近期文章

    更多
    文章目录

      推荐作者

      更多