SpringBoot学习笔记【part18】拦截器与文件上传

news2025/1/11 2:39:09

一、拦截器Interceptor

拦截器 Interceptor 多用于登录检查与静态资源放行场景。

拦截器的实现步骤

  1. 编写一个拦截器实现 HandlerInterceptor 接口

    @Slf4j
    public class LoginInterceptor implements HandlerInterceptor {
    
        /**
         * 目标方法执行之前
         */
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    
            String requestURI = request.getRequestURI();
            log.info("preHandle拦截的请求路径是{}",requestURI);
    
            //登录检查逻辑
            HttpSession session = request.getSession();
            Object loginUser = session.getAttribute("loginUser");
    
            if(loginUser != null){
                //放行
                return true;
            }
    
            //拦截住。未登录。跳转到登录页
            request.setAttribute("msg","请先登录");
            request.getRequestDispatcher("/").forward(request,response);
            return false;
        }
    
        /**
         * 目标方法执行完成以后
         */
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            log.info("postHandle执行{}",modelAndView);
        }
    
        /**
         * 页面渲染以后
         */
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            log.info("afterCompletion执行异常{}",ex);
        }
    }
    
  2. 拦截器注册到容器中(实现 WebMvcConfigureraddInterceptors()

    @Configuration
    public class AdminWebConfig implements WebMvcConfigurer{
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(new LoginInterceptor());//拦截器注册到容器中
    }
    
  3. 指定拦截规则(注:若设置为拦截所有,则静态资源也会被拦截)

    @Configuration
    public class AdminWebConfig implements WebMvcConfigurer{
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(new LoginInterceptor())//拦截器注册到容器中
                    .addPathPatterns("/**")  //所有请求都被拦截包括静态资源
                    .excludePathPatterns("/","/login","/css/**","/fonts/**","/images/**",
                            "/js/**","/aa/**"); //放行的请求
    }
    

拦截器的执行原理

  1. 根据当前请求,找到HandlerExecutionChain(可以处理请求的handler以及handler的所有拦截器)

  2. 先来顺序执行所有拦截器的 preHandle()方法。

    ​ 如果当前拦截器preHandle()返回为true,则执行下一个拦截器的preHandle()

    ​ 如果当前拦截器返回为false。直接倒序执行所有已经执行了的拦截器的 afterCompletion();

  3. 如果任何一个拦截器返回false,直接跳出不执行目标方法。

  4. 所有拦截器都返回true,才执行目标方法。

  5. 倒序执行所有拦截器的postHandle()方法。

  6. 前面的步骤有任何异常都会直接倒序触发 afterCompletion()

  7. 页面成功渲染完成以后,也会倒序触发 afterCompletion()

在这里插入图片描述


二、文件上传

文件上传可以有单文件与多文件的形式。

文件上传实现事例

页面事例代码:

<form role="form" th:action="@{/upload}" method="post" enctype="multipart/form-data">
    <div class="form-group">
        <label for="exampleInputEmail1">邮箱</label>
        <input type="email" name="email" class="form-control" id="exampleInputEmail1" placeholder="Enter email">
    </div>
    
    <div class="form-group">
        <label for="exampleInputPassword1">名字</label>
        <input type="text" name="username" class="form-control" id="exampleInputPassword1" placeholder="Password">
    </div>
    
    <div class="form-group">
        <label for="exampleInputFile">头像</label>
        <input type="file" name="headerImg" id="exampleInputFile">
    </div>
    
    <div class="form-group">
        <label for="exampleInputFile">生活照</label>
        <input type="file" name="photos" multiple>
    </div>
    
    <div class="checkbox">
        <label>
            <input type="checkbox"> Check me out
        </label>
    </div>
    <button type="submit" class="btn btn-primary">提交</button>
</form>

控制层代码:(上述页面存放位置:/static/admin/form.html)

@Slf4j
@Controller
public class FormController {

    @GetMapping("/form")
    public String form_layouts(){
        return "admin/form";
    }

    @PostMapping("/upload")
    public String upload(@RequestParam("email") String email,
                         @RequestParam("username") String username,
                         @RequestPart("headerImg") MultipartFile headerImg,
                         @RequestPart("photos") MultipartFile[] photos) throws IOException {

        log.info("上传的信息:email={},username={},headerImg={},photos={}",
                 email,username,headerImg.getSize(),photos.length);

        if(!headerImg.isEmpty()){
            //保存到文件到磁盘某处
            String originalFilename = headerImg.getOriginalFilename();
            headerImg.transferTo(new File("H:\\cache\\"+originalFilename));
        }

        if(photos.length > 0){
            for (MultipartFile photo : photos) {
                if(!photo.isEmpty()){
                    //保存到文件到磁盘某处
                    String originalFilename = photo.getOriginalFilename();
                    photo.transferTo(new File("H:\\cache\\"+originalFilename));
                }
            }
        }


        return "main";
    }
}

相关配置类与配置项

SpringBoot中的文件上传配置类:

  • org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration
  • org.springframework.boot.autoconfigure.web.servlet.MultipartProperties

常用相关配置项:

spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=100MB

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/337605.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Redis 分布式基础——主从复制其实挺简单

Redis 主从同步 redis-master-slave-index 一、主从复制是啥 主从复制&#xff0c;或者叫 主从同步&#xff0c;是指将一台 Redis 服务器的数据&#xff0c;复制到其他的 Redis 服务器。前者称为 主节点(master)&#xff0c;后者称为 从节点(slave)。且数据的复制是 单向 的&…

GitLab CI-CD 学习笔记

概述 1. CI/CD CI&#xff08;持续集成&#xff09;指开发人员一天内进行多次合并和提交代码操作&#xff0c;并通过自动化测试&#xff0c;完成构建 CD&#xff08;持续部署&#xff09;指每次代码更改都会自动部署到对应环境 CI/CD 结合在一起&#xff0c;可以加快开发团…

如何写出优雅的代码

最近在做代码审查时&#xff0c;发现一个问题&#xff0c;就是代码不够优雅。代码可以有bug&#xff0c;但不能不优雅&#xff0c;毕竟代码不只是运行程序&#xff0c;凡是需要维护的代码都是给人看的&#xff0c;你的代码风格侧面反映了你的编码习惯、思维逻辑和专业性。那么如…

【强化学习】马尔可夫决策过程MDP

1.马尔可夫决策过程MDP 1.1 MDP五元组 MDP<S,A,P,R,γ>MDP<\mathcal{S},\mathcal{A},\mathcal{P},\mathcal{R},\mathcal{\gamma}>MDP<S,A,P,R,γ>&#xff0c;其中&#xff1a; S\mathcal{S}S&#xff1a;状态空间A\mathcal{A}A&#xff1a;动作空间P\mathc…

【VictoriaMetrics】VictoriaMetrics单机版部署(二进制版)

1、下载安装包git路径,本文基于1.87.1版本 进入git地址 :https://github.com/VictoriaMetrics/VictoriaMetrics/tags 2、下载其中linux下的 amd64架构

【数据结构】单向链表的练习题

目录 前言 1、删除链表中等于给定值val的所有节点。 【题目描述】 【代码示例】 【 画图理解】 2、反转一个点链表 【题目描述】 【 代码思路】 【代码示例】 【画图理解】 3、给定一个带有头节点head的非空单链表&#xff0c;返回链表的中间节点&#xff0c;如果有两个…

三维重建——NeuralRecon项目源码解读

代码链接见文末 首先,需要指明的是NeuralRecon项目不支持windows,主要是使用到的例如torchsprase等不支持windows,您也可以在网上查找相应的替代方法。 1.数据与环境配置 ScanNet数据的获取首先需要向作者发送邮件,作者会回复一个下载的脚本,在提供的代码中,提供了…

Mysql数据库09——分组聚合函数

类似pandas里面的groupby函数&#xff0c;SQL里面的GROUP BY子句也是可以达到分组聚合的效果。 常用的聚合函数有COUNT(),SUM(),AVG(),MAX(),MIN()&#xff0c;其用法看名字都看的出来&#xff0c;下面一一介绍 聚合函数 COUNT()计数 统计student表中计科系学生的人数。 SE…

基于nodejs+vue疫情网课管理系统

疫情网课也都将通过计算机进行整体智能化操作,对于疫情网课管理系统所牵扯的管理及数据保存都是非常多的,例如管理员&#xff1a;首页、个人中心、学生管理、教师管理、班级管理、课程分类管理、课程表管理、课程信息管理、作业信息管理、请假信息管理、上课签到管理、论坛交流…

企业微信应用授权,第一次不授权手机号后如何再次开启

文章目录前言一、关于企业微信应用授权1、新建一个应用2、企业微信应用授权二、第一次拒绝后如何手动开启总结前言 简单记录一下&#xff1a; 最近做了几个企业微信应用授权web&#xff0c;和普通微信公众号授权差不多&#xff0c;记录一下 一、关于企业微信应用授权 1、新建…

失手删表删库,赶紧跑路?!

在数据资源日益宝贵的数字时代公司最怕什么&#xff1f;人还在&#xff0c;库没了是粮库、车库&#xff0c;还是小金库&#xff1f;实际上&#xff0c;这里的“库”是指的数据库Ta是公司各类信息的保险柜小到企业官网和客户信息大到金融机构的资产数据和国家秘密即便没有跟数据…

Linux服务器开发-2. Linux多进程开发

文章目录1. 进程概述1.1 程序概览1.2 进程概念1.3 单道、多道程序设计1.4 时间片1.5 并行与并发1.6 进程控制块&#xff08;PCB&#xff09;2. 进程的状态转换2.1 进程的状态2.2 进程相关命令查看进程实时显示进程动态杀死进程进程号和相关函数3. 进程的创建-fork函数3.1 进程创…

抖音线索信息自动汇总到SeaTable流程搭建示例

每当抖音有新意向用户添加时&#xff0c;往往被企业视为意向客户&#xff0c;常需要运营人员查看后同步到SeaTable表单系统进行汇总&#xff0c;但运营人员时常会遗忘&#xff0c;并且难免会遗漏掉部分信息&#xff0c;导致部分意向客户无人跟进&#xff0c;最终流失。 那么&a…

GO语音-切片使用的雷区与性能优化相关

文章目录前言一、切片是什么&#xff1f;二、切片使用注意项1.避免复制数组2.切片初始化3.切片GC三、切片使用注意什么1. 大家来思考一个代码示例&#xff1a;2. 修改切片的值3. 降低切片重复申请内存总结前言 在 Go 语言中&#xff0c;切片(slice)可能是使用最为频繁的数据结…

数据结构 | 线性表

&#x1f525;Go for it!&#x1f525; &#x1f4dd;个人主页&#xff1a;按键难防 &#x1f4eb; 如果文章知识点有错误的地方&#xff0c;请指正&#xff01;和大家一起学习&#xff0c;一起进步&#x1f440; &#x1f4d6;系列专栏&#xff1a;数据结构与算法 &#x1f52…

Wise-IoU 作者导读:基于动态非单调聚焦机制的边界框损失

论文地址&#xff1a;Wise-IoU: Bounding Box Regression Loss with Dynamic Focusing Mechanism GitHub&#xff1a;https://github.com/Instinct323/wiou 摘要&#xff1a;目标检测作为计算机视觉的核心问题&#xff0c;其检测性能依赖于损失函数的设计。边界框损失函数作为…

153、【动态规划】leetcode ——416. 分割等和子集:滚动数组(C++版本)

题目描述 原题链接&#xff1a;1049. 最后一块石头的重量 II 解题思路 本题要找的是最小重量&#xff0c;我们可以将石头划分成两个集合&#xff0c;当两个集合的重量越接近时&#xff0c;相减后&#xff0c;可达到的装量就会是最小&#xff0c;此时本题的思路其实就类似于 4…

【光伏功率预测】基于EMD-PCA-LSTM的光伏功率预测模型(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

MSI_MSI-X中断之体验与使用

MSI_MSI-X中断之体验与使用 文章目录MSI_MSI-X中断之体验与使用1. 怎么发出MSI/MSI-X中断1.1 在RK3399上体验1.1.1 安装工具1.1.2 查看设备MSI-X信息1.1.3 验证MSI-X信息2. 怎么使用MSI/MSI-X3. MSI/MSI-X中断源码分析3.1 IRQ Domain创建流程3.1.1 GIC3.1.2 ITS3.1.3 PCI MSI3.…

【Flutter】【Unity】使用 Flutter + Unity 构建(AR 体验工具包)

使用 Flutter Unity 构建&#xff08;AR 体验工具包&#xff09;【翻译】 原文&#xff1a;https://medium.com/potato/building-with-flutter-unity-ar-experience-toolkit-6aaf17dbb725 由于屡获殊荣的独立动画工作室 Aardman 与讲故事的风险投资公司 Fictioneers&#x…