zoukankan      html  css  js  c++  java
  • 拦截器、过滤器(个人笔记)

    过滤器和拦截器的区别:拦截器是AOP思想的具体应用,采用横切,不影响原来功能实现一个拦截功能

    过滤器:
    servlet规范中的一部分,任何java web工程都可以使用
    在url-pattern配置/*以后,可以对访问的资源进行拦截

    拦截器:
    拦截器是SpringMVC框架自己的,只有使用SpringMVC框架的工程才能使用
    拦截器只会拦截访问的控制器方法(controller中的请求),如果访问的是jsp/html/css/image/js是不会进行拦截的

    那如何实现拦截器呢?
    想要自定义拦截器,必须实现 HandlerInterceptor 接口。
    1、新建一个Moudule , springmvc-07-Interceptor , 添加web支持
    2、配置web.xml 和 springmvc-servlet.xml 文件
    3、编写一个拦截器

    package com.kuang.interceptor;
    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class MyInterceptor implements HandlerInterceptor {
    
       //在请求处理的方法之前执行
       //如果返回true执行下一个拦截器
       //如果返回false就不执行下一个拦截器
       public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
           System.out.println("------------处理前------------");
           return true;
      }
    
       //在请求处理方法执行之后执行
       public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
           System.out.println("------------处理后------------");
      }
    
       //在dispatcherServlet处理后执行,做清理工作.
       public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
           System.out.println("------------清理------------");
      }
    }
    

    4、在springmvc的配置文件中配置拦截器

    mvc:interceptors
    mvc:interceptor



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


    </mvc:interceptor>
    </mvc:interceptors>
    5、编写一个Controller,接收请求

    package com.kuang.controller;

    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;

    //测试拦截器的控制器
    @Controller
    public class InterceptorController {

    @RequestMapping("/interceptor")
    @ResponseBody
    public String testFunction() {
    System.out.println(“控制器中的方法执行了”);
    return “hello”;
    }
    }
    6、前端 index.jsp

    拦截器测试
    7、启动tomcat 测试一下!

    验证用户是否登录 (认证用户)
    实现思路

    1、有一个登陆页面,需要写一个controller访问页面。

    2、登陆页面有一提交表单的动作。需要在controller中处理。判断用户名密码是否正确。如果正确,向session中写入用户信息。返回登陆成功。

    3、拦截用户请求,判断用户是否登陆。如果用户已经登陆。放行, 如果用户未登陆,跳转到登陆页面

    测试:

    1、编写一个登陆页面 login.jsp

    <%@ page contentType=“text/html;charset=UTF-8” language=“java” %>

    Title

    登录页面


    用户名:
    密码:
    2、编写一个Controller处理请求

    package com.kuang.controller;

    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;

    import javax.servlet.http.HttpSession;

    @Controller
    @RequestMapping("/user")
    public class UserController {

    //跳转到登陆页面
    @RequestMapping("/jumplogin")
    public String jumpLogin() throws Exception {
    return “login”;
    }

    //跳转到成功页面
    @RequestMapping("/jumpSuccess")
    public String jumpSuccess() throws Exception {
    return “success”;
    }

    //登陆提交
    @RequestMapping("/login")
    public String login(HttpSession session, String username, String pwd) throws Exception {
    // 向session记录用户身份信息
    System.out.println(“接收前端===”+username);
    session.setAttribute(“user”, username);
    return “success”;
    }

    //退出登陆
    @RequestMapping(“logout”)
    public String logout(HttpSession session) throws Exception {
    // session 过期
    session.invalidate();
    return “login”;
    }
    }
    3、编写一个登陆成功的页面 success.jsp

    <%@ page contentType=“text/html;charset=UTF-8” language=“java” %>

    Title

    登录成功页面


    u s e r < a h r e f = " {user} <a href=" user<ahref="{pageContext.request.contextPath}/user/logout">注销

    4、在 index 页面上测试跳转!启动Tomcat 测试,未登录也可以进入主页!

    <%@ page contentType=“text/html;charset=UTF-8” language=“java” %>

    $Title$

    首页


    <%--登录--%> 登录 成功页面 5、编写用户登录拦截器

    package com.kuang.interceptor;

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

    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    import java.io.IOException;

    public class LoginInterceptor implements HandlerInterceptor {

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException {
    // 如果是登陆页面则放行
    System.out.println("uri: " + request.getRequestURI());
    if (request.getRequestURI().contains(“login”)) {
    return true;
    }

       HttpSession session = request.getSession();
    
       // 如果用户已登陆也放行
       if(session.getAttribute("user") != null) {
           return true;
      }
    
       // 用户没有登陆跳转到登陆页面
       request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
       return false;
    

    }

    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }
    }
    6、在Springmvc的配置文件中注册拦截器

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

    </mvc:interceptor>
    </mvc:interceptors>
    7、再次重启Tomcat测试!

    OK,测试登录拦截功能无误.

    文件上传和下载
    准备工作
    文件上传是项目开发中最常见的功能之一 ,springMVC 可以很好的支持文件上传,但是SpringMVC上下文中默认没有装配MultipartResolver,因此默认情况下其不能处理文件上传工作。如果想使用Spring的文件上传功能,则需要在上下文中配置MultipartResolver。

    前端表单要求:为了能上传文件,必须将表单的method设置为POST,并将enctype设置为multipart/form-data。只有在这样的情况下,浏览器才会把用户选择的文件以二进制数据发送给服务器;

    对表单中的 enctype 属性做个详细的说明:

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

    multipart/form-data:这种编码方式会以二进制流的方式来处理表单数据,这种编码方式会把文件域指定文件的内容也封装到请求参数中,不会对字符编码。

    text/plain:除了把空格转换为 “+” 号外,其他字符都不做编码处理,这种方式适用直接通过表单发送邮件。

    一旦设置了enctype为multipart/form-data,浏览器即会采用二进制流的方式来处理表单数据,而对于文件上传的处理则涉及在服务器端解析原始的HTTP响应。在2003年,Apache Software Foundation发布了开源的Commons FileUpload组件,其很快成为Servlet/JSP程序员上传文件的最佳选择。

    Servlet3.0规范已经提供方法来处理文件上传,但这种上传需要在Servlet中完成。

    而Spring MVC则提供了更简单的封装。

    Spring MVC为文件上传提供了直接的支持,这种支持是用即插即用的MultipartResolver实现的。

    Spring MVC使用Apache Commons FileUpload技术实现了一个MultipartResolver实现类:

    CommonsMultipartResolver。因此,SpringMVC的文件上传还需要依赖Apache Commons FileUpload的组件。

    文件上传
    1、导入文件上传的jar包,commons-fileupload , Maven会自动帮我们导入他的依赖包 commons-io包;

    commons-fileupload commons-fileupload 1.3.3 javax.servlet javax.servlet-api 4.0.1 2、配置bean:multipartResolver

    【注意!!!这个bena的id必须为:multipartResolver , 否则上传文件会报400的错误!在这里栽过坑,教训!】

    CommonsMultipartFile 的 常用方法:

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

    InputStream getInputStream():获取文件流

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

    我们去实际测试一下

    3、编写前端页面

    4、Controller

    package com.kuang.controller;

    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.multipart.commons.CommonsMultipartFile;

    import javax.servlet.http.HttpServletRequest;
    import java.io.*;

    @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";
    

    }
    }
    5、测试上传文件,OK!

    采用file.Transto 来保存上传的文件

    1、编写Controller

    /*

    • 采用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();
      }
      //上传文件地址
      System.out.println(“上传文件保存地址:”+realPath);

      //通过CommonsMultipartFile的方法直接写文件(注意这个时候)
      file.transferTo(new File(realPath +"/"+ file.getOriginalFilename()));

      return “redirect:/index.jsp”;
      }
      2、前端表单提交地址修改

    3、访问提交测试,OK!

    文件下载
    文件下载步骤:

    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;
    }
    前端

    点击下载
    测试,文件下载OK,大家可以和我们之前学习的JavaWeb原生的方式对比一下,就可以知道这个便捷多了!

  • 相关阅读:
    SPOJ 694 (后缀数组) Distinct Substrings
    POJ 2774 (后缀数组 最长公共字串) Long Long Message
    POJ 3693 (后缀数组) Maximum repetition substring
    POJ 3261 (后缀数组 二分) Milk Patterns
    UVa 1149 (贪心) Bin Packing
    UVa 12206 (字符串哈希) Stammering Aliens
    UVa 11210 (DFS) Chinese Mahjong
    UVa (BFS) The Monocycle
    UVa 11624 (BFS) Fire!
    HDU 3032 (Nim博弈变形) Nim or not Nim?
  • 原文地址:https://www.cnblogs.com/kiki-study/p/13656105.html
Copyright © 2011-2022 走看看