• SpringMVC 12 登录拦截验证、文件上传和下载


    12.1 登录判断验证


    首先我们要知道一个常识,在 WEB-INF 下面的 所有页面和资源,只能通过Controller或Servlet 去请求访问。所以这就意味着 如果你不想让别人直接访问到 某个资源,那么就要 把这个资源 放到 WEB-INF 下面。

    比如 我们 这次 要做的 登录判断验证的相关页面资源,我们 就可以将其 放到 WEB-INF/jsp 下面。

    1. 写两个页面 login.jsp main.jsp
    <%--
      Created by IntelliJ IDEA.
      User: muqua
      Date: 2022/7/27
      Time: 6:06
      To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Titletitle>
    head>
    <body>
    <h1>登录页面h1>
    <form action="${pageContext.request.contextPath}/login" method="post">
        用户名:<input type="text" name="username">
        密码:<input type="text" name="password">
        <input type="submit" value="提交">
    form>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    <%--
      Created by IntelliJ IDEA.
      User: muqua
      Date: 2022/7/27
      Time: 6:06
      To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Titletitle>
    head>
    <body>
    <h1>首页h1>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    1. 写好跳转请求的 Controller,并且尝试存储一下 Session

    切记:Session 这个玩意,只能在 后端服务器上 拿到和看到。在前端浏览器上是无法直接看到的。它只会 在 cookie 那里 给你存储一个 SessionID

    package top.muquanyu.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    import javax.servlet.http.HttpSession;
    
    @Controller
    public class LoginController {
        @RequestMapping("/main")
        public String main(){
            return "main";
        }
    
        @RequestMapping("/goLogin")
        public String goLogin(){
            return "login";
        }
    
        @RequestMapping("/login")
        public String login(String username, String password, HttpSession session){
            // 把用户的信息存储到 session 中
    
            session.setAttribute("userLoginInfo",username);
            System.out.println(session.getAttribute("userLoginInfo"));
    
            return "main";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    在这里插入图片描述

    1. 写一个拦截器,解决没有登录就进入 main 页面的问题。
    package top.muquanyu.config;
    
    import org.springframework.web.servlet.HandlerInterceptor;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    public class LoginInterceptor implements HandlerInterceptor {
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    
            HttpSession session = request.getSession();
    
            // 登录页面是必须放行的,否则连 登录页面 也进不去了。。还登陆个屁
            if(request.getRequestURI().contains("goLogin")){
                return true;
            }
            
            // 并且 添加 session 的那个请求 url 也需要放行,否则 没办法 执行那个 Controller
            if(request.getRequestURI().contains("login")){
                return true;
            }
    
            if(session.getAttribute("userLoginInfo") != null){
                System.out.println("确实存在 userLoginInfo");
                return true;
            }
    
            request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request,response);
    
            return false;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    1. 配置 一下 这个 拦截器
    
        <mvc:interceptors>
            <mvc:interceptor>
                <mvc:mapping path="/**/"/>  
                <bean class="top.muquanyu.config.MyInterceptor">bean> 
            mvc:interceptor>
            <mvc:interceptor>
                <mvc:mapping path="/user/**"/>
                <bean class="top.muquanyu.config.LoginInterceptor">bean> 
            mvc:interceptor>
        mvc:interceptors>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    这样,我们的 登录拦截验证 就做好了。
    在这里插入图片描述


    12.2 文件上传

    文件上传是项目开发中最常见的功能之一,SpringMVC 可以很好的支持文件上传。但是 SpringMVC 上下文中默认没有装配 MultiparResolver,因此 默认情况下 是不能 处理文件上传的。如果想使用 Spring 的文件上传功能,必须 在 xml 中 配置 MultiparResolver

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

    1. 导入 commons-fileupload javax.servlet-api
    <dependencies>
            <dependency>
                <groupId>commons-fileuploadgroupId>
                <artifactId>commons-fileuploadartifactId>
                <version>1.3.3version>
            dependency>
            <dependency>
                <groupId>javax.servletgroupId>
                <artifactId>javax.servlet-apiartifactId>
                <version>4.0.1version>
            dependency>
        dependencies>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    1. 写 一个 upload 的 页面
    <%--
      Created by IntelliJ IDEA.
      User: muqua
      Date: 2022/7/27
      Time: 7:14
      To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Titletitle>
    head>
    <body>
    <form action="/upload" enctype="multipart/form-data" method="post">
        <input type="file" name="file">
        <input type="submit" value="upload">
    form>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    1. 比较原生态的 写法
    package top.muquanyu.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.multipart.commons.CommonsMultipartFile;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.*;
    
    @Controller
    public class FileController {
        @RequestMapping("/upload")
        public String upload(@RequestParam("file")CommonsMultipartFile file, HttpServletRequest req, HttpServletResponse resp) throws IOException {
            // 获取文件名 file.getOriginalFilename();
            String upLoadFileName = file.getOriginalFilename();
    
            // 如果文件名为空,直接回到首页
            if("".equals(upLoadFileName)){
                return "redirect/index2.jsp";
            }
    
            System.out.println("上传文件名:" + upLoadFileName);
    
            // 上传路径保存设置
            String path = req.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);
                os.flush();// 害怕堵塞,所以 要刷新
            }
            os.close();
            is.close();
            return "redirect:/index2.jsp";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    CommonsMultipartFile 会把我们 表单 的 file 组件 的所有关键信息和数据都传到和封装到这个对象里。

    1. SpringMVC 的写法
        @RequestMapping("/upload2")
        public String fileUpload2(@RequestParam("file") CommonsMultipartFile file,HttpServletRequest req) throws IOException {
            // 上传路径保存设置
            String path = req.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:index2.jsp";
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    在这里插入图片描述
    在这里插入图片描述


    12.3 文件下载

    文件下载的步骤:

    • 设置 response 响应头
    • 读取文件 – InputStream
    • 写出文件 – OutputStream
    • 执行操作
    • 关闭流(先开后关)
    1. 比较原生态的写法
     @RequestMapping("/download")
        public String downloads(HttpServletRequest req, HttpServletResponse resp) throws IOException {
    
            // 要下载 的 图片地址
            String path = req.getServletContext().getRealPath("/upload");
            String fileName = "c++API.chm";
    
            // 1. 设置 response 响应头
            resp.reset(); // 设置页面不能缓存,清空 buffer
            resp.setCharacterEncoding("UTF-8"); // 字符编码
            resp.setContentType("multipart/form-data"); // 二进制传输数据
            // 设置响应头
            resp.setHeader("Content-Disposition",
                    "attachment;fileName=" + URLEncoder.encode(fileName,"UTF-8"));
    
            File file = new File(path,fileName);
    
            // 2. 读取文件 -- 输入流
            InputStream is = new FileInputStream(file);
    
            // 3. 写出文件 -- 输出流
            OutputStream os = resp.getOutputStream();
    
            byte[] buff = new byte[1024];
            int len = 0;
    
            // 4. 执行 写出 操作
    
            while((len = is.read(buff)) != -1) {
                os.write(buff, 0, len);
                os.flush();
            }
            os.close();
            is.close();
            return null;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    在这里插入图片描述

  • 相关阅读:
    【Vue】vue先转化文章内容再去除标签 vue filters过滤器去除标签 js提取文字内容
    计算机系统/硬件
    从入门到进阶 之 ElasticSearch 文档、分词器 进阶篇
    [acwing周赛复盘] 第 63 场周赛20220806
    【iOS ARKit】RealityKit 中的物理组件
    继承的构造函数
    WebDAV之葫芦儿·派盘+纸间书摘
    51单片机学习:外部中断1实验
    科大讯飞 vue.js 语音听写流式实现 全网首发
    day5_redis学习
  • 原文地址:https://blog.csdn.net/qq_52606908/article/details/126006569