SpringBoot(拦截器+文件上传)

news2024/10/5 14:16:55

文章目录

    • 1.拦截器
        • 1.基本介绍
        • 2.应用实例
          • 1.去掉Thymeleaf案例中使用session进行权限验证的部分
          • 2.编写自定义拦截器 LoginInterceptor.java 实现HandlerInterceptor接口的三个方法
          • 3.注册拦截器
            • 1.第一种方式 配置类直接实现WebMvcConfigurer接口,重写addInterceptors方法
            • 2.第二种方式 注入一个WebMvcConfigurer接口类型的bean,使用匿名内部类实现接口的方法
            • 3.注册拦截器方式小结
        • 3.注意事项和细节
          • 1.关于图片资源
          • 2.uri和url的区别
    • 2.文件上传
        • 1.需求分析
        • 2.具体实现
          • 1.编写upload.html
          • 2.编写UploadController.java 可以请求转发到upload.html
          • 3.编写Controller来将上传的文件保存到D:\temp_upload
          • 4.升级版,将上传的文件保存到动态创建的目录(常用)
          • 5.测试
        • 3.注意事项和细节
          • 1.文件上传的限制
            • 1.MultipartProperties
            • 2.修改文件上传的限制大小 application.yml
          • 2.同名文件覆盖问题
          • 3.分目录存放
            • 1.WebUtils.java
            • 2.修改代码

1.拦截器

1.基本介绍

image-20240315132915030

2.应用实例
1.去掉Thymeleaf案例中使用session进行权限验证的部分
2.编写自定义拦截器 LoginInterceptor.java 实现HandlerInterceptor接口的三个方法
package com.sun.springboot.interceptor;

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

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * @author 孙显圣
 * @version 1.0
 */
public class LoginInterceptor implements HandlerInterceptor {
    @Override
    //在Controller之前调用
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("uri=" + request.getRequestURI());
        //对登录的校验
        HttpSession session = request.getSession();
        //如果session中有LoginAdmin则登录成功
        if (session.getAttribute("LoginAdmin") != null) {
            return true;
        } else {
            //如果登录失败则将信息请求转发到首页面
            request.setAttribute("msg", "登录失败,请重新登录");
            request.getRequestDispatcher("/").forward(request, response);
            return false;
        }
    }

    @Override
    //在Controller之后调用
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle被调用");
    }

    @Override
    //视图解析器将信息请求转发到某个页面,然后将那个页面相应给浏览器时调用
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion被调用");
    }
}

3.注册拦截器
1.第一种方式 配置类直接实现WebMvcConfigurer接口,重写addInterceptors方法
package com.sun.springboot.config;

import com.sun.springboot.interceptor.LoginInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * @author 孙显圣
 * @version 1.0
 */

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
        public void addInterceptors(InterceptorRegistry registry) {
        //注册拦截器并且设置拦截路径和排除路径,这里的/是根路径
        registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**").excludePathPatterns("/", "/login", "/images");
    }
}

2.第二种方式 注入一个WebMvcConfigurer接口类型的bean,使用匿名内部类实现接口的方法
package com.sun.springboot.config;

import com.sun.springboot.interceptor.LoginInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * @author 孙显圣
 * @version 1.0
 */
@Configuration
public class WebConfig02 {
    //注册拦截器
    @Bean //注入一个WebMvcConfigurer接口类型的bean,使用匿名内部类实现接口的方法
    public WebMvcConfigurer webMvcConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addInterceptors(InterceptorRegistry registry) {

                registry.addInterceptor(new LoginInterceptor()).
                        addPathPatterns("/**").excludePathPatterns("/", "/login", "/images");
            }
        };
    }
}

3.注册拦截器方式小结
  • 第一种方式是配置类实现WebMvcConfigurer接口,利用配置类的特性来注入bean
  • 第二种方式是在配置类中注入一个bean,是WebMvcConfigurer接口类型的
  • 他们的共通点就是:都向容器中注入了一个实现了WebMvcConfigurer接口的bean
3.注意事项和细节
1.关于图片资源
  • 如果不放行,则在第一次进入登录界面时,还会向服务器申请图片资源,此时会被拦截
  • 图片资源路径的设置是按照设置的访问路径,默认是http://localhost:8080/下的资源
2.uri和url的区别
  • uri就是服务器内部的路径/代表的是服务器根路径
  • url是浏览器地址栏的路径

image-20240315160850884

2.文件上传

1.需求分析

image-20240315163842285

2.具体实现
1.编写upload.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>upload</title>
</head>
<body bgcolor="#CED3FE">
<img src="images/1.GIF"/>
<hr/>
<div style="text-align: center">
    <h1>注册用户~</h1>
    <form action="#" method="post" th:action="@{/upload}" enctype="multipart/form-data">
        用户名:<input type="text" style="width:150px" name="name"/><br/><br/>
        电 邮:<input type="text" style="width:150px" name="email"/><br/><br/>
        年 龄:<input type="text" style="width:150px" name="age"/><br/><br/>
        职 位:<input type="text" style="width:150px" name="job"/><br/><br/>
        头 像:<input type="file" style="width:150px" name="header"><br/><br/>
        <!--这里使用的multiple表示可以一次上传多个文件-->
        宠 物:<input type="file" style="width:150px" name="photos" multiple><br/><br/>
        <input type="submit" value="注册"/>
        <input type="reset" value="重新填写"/>
    </form>
</div>
<hr/>
<img src="images/logo.png"/>
</body>
</html>

2.编写UploadController.java 可以请求转发到upload.html
package com.sun.springboot.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

/**
 * @author 孙显圣
 * @version 1.0
 */
@Controller
@Slf4j
public class UploadController {
    @GetMapping("/upload.html")
    public String uploadPage() {
        //请求转发到upload.html
        return "upload";

    }
}

3.编写Controller来将上传的文件保存到D:\temp_upload
   //处理有文件的表单
    @ResponseBody
    @PostMapping("/upload")
    //获取上传的表单信息
    public String upload(@RequestParam("name") String name,
                         @RequestParam("email") String email,
                         @RequestParam("age") Integer age,
                         @RequestParam("job") String job,
                         @RequestParam("header") MultipartFile header,
                         @RequestParam("photos") MultipartFile[] photos) throws IOException {
        //显示获取到的信息
        log.info("name={} email={} age={} job={} header={} photos={}",
                name, email, age, job, header, photos);
        //首先处理单个文件
        if (!header.isEmpty()) {
            //文件不为空则获取文件的名字
            String originalFilename = header.getOriginalFilename();
            //将文件转存在磁盘的指定位置D:\temp_upload
            header.transferTo(new File("D:\\temp_upload\\" + originalFilename));
        }
        //处理文件数组
        if (photos.length > 0) {
            //只要长度大于0,就遍历
            for (MultipartFile photo : photos) {
                //获取当前文件的名字
                String originalFilename = photo.getOriginalFilename();
                if (!photo.isEmpty()) {
                    //只要文件不为空就转存
                    photo.transferTo(new File("D:\\temp_upload\\" + originalFilename));
                }
            }
        }
        return "文件上传成功!";
    }
4.升级版,将上传的文件保存到动态创建的目录(常用)
    //处理有文件的表单
    @ResponseBody
    @PostMapping("/upload")
    //获取上传的表单信息
    public String upload(@RequestParam("name") String name,
                         @RequestParam("email") String email,
                         @RequestParam("age") Integer age,
                         @RequestParam("job") String job,
                         @RequestParam("header") MultipartFile header,
                         @RequestParam("photos") MultipartFile[] photos) throws IOException {
        //处理单个文件,存到动态创建的文件夹下
        if (!header.isEmpty()) {
            //1.文件不为空则获取文件的名字
            String originalFilename = header.getOriginalFilename();

            //2.动态创建一个类路径下的自定义目录
            //2.1 获取类路径的绝对路径
            // /D:/Intelij_IDEA_Project/springboot/springboot-usersys/target/classes/
            String classPath = ResourceUtils.getURL("classpath:").getPath();
            //2.2 拼接目录,得到想要创建的目录的文件对象
            File targetFile = new File(classPath + "static\\upload\\");
            //2.3 只要目录不存在就动态创建目录
            if (!targetFile.exists()) {
                targetFile.mkdirs(); //注意这里是多级目录必须加s
            }

            //3.将文件转存到这个自定义目录下
            //3.1 获取这个目录的绝对路径
            String targetAbsolutePath = targetFile.getAbsolutePath();
            //3.2 将文件转存到这个路径下
            // D:\Intelij_IDEA_Project\springboot\springboot-usersys\target\classes\static\(注意upload没有\)upload
            header.transferTo(new File(targetAbsolutePath + "\\" + originalFilename));
        }

        //处理文件数组,存到磁盘指定位置
        if (photos.length > 0) {
            //只要长度大于0,就遍历
            for (MultipartFile photo : photos) {
                //获取当前文件的名字
                String originalFilename = photo.getOriginalFilename();
                if (!photo.isEmpty()) {
                    //只要文件不为空就转存
                    photo.transferTo(new File("D:\\temp_upload\\" + originalFilename));
                }
            }
        }
        return "文件上传成功!";
    }
5.测试

image-20240315175132772

3.注意事项和细节
1.文件上传的限制
1.MultipartProperties

image-20240315175524538

2.修改文件上传的限制大小 application.yml
spring:
  servlet:
    multipart:
      max-file-size: 10MB #单个文件大小上限
      max-request-size: 50MB #一次请求的文件大小上限
2.同名文件覆盖问题

image-20240315191141767

3.分目录存放
1.WebUtils.java
package com.sun.springboot.utils;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Stack;

/**
 * @author 孙显圣
 * @version 1.0
 */
public class WebUtils {
    //上传文件的前缀
    public static String UPLOAD_FILE_DIRECTORY = "static\\upload\\";

    //编写方法,根据当前日期生成一个目录
    public static String getUploadFileDirectory() {
        return UPLOAD_FILE_DIRECTORY +
                new SimpleDateFormat("yyyy\\MM\\dd").format(new Date()) + "\\";
    }

}

2.修改代码

image-20240315192653677

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

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

相关文章

本地知识库的底层逻辑是什么?为什么企业需要它?

如果我们将企业比作一座繁华的城市&#xff0c;那么信息就像是城市的建筑&#xff0c;知识库则是城市的地图。知识库不仅可以帮我们存储整理和搜寻信息&#xff0c;而且还可以为我们提供信息的结构以便我们能够更好地理解和利用这些信息。今天&#xff0c;我们要探讨的就是这个…

一维坐标的移动(bfs)

在一个长度为n的坐标轴上&#xff0c;小S想从A点移动B点。 他的移动规则如下&#xff1a; 向前一步&#xff0c;坐标增加1。 向后一步&#xff0c;坐标减少1。 跳跃一步&#xff0c;使得坐标乘2。 小S不能移动到坐标小于0或大于n的位置。 小S想知道从A点移动到B点的最少步数是多…

Layui实现删除及修改后停留在当前页

1、功能概述&#xff1f; 我们在使用layui框架的table显示数据的时候&#xff0c;会经常的使用分页技术&#xff0c;这个我们期望能够期望修改数据能停留在当前页&#xff0c;或者删除数据的时候也能够停留在当前页&#xff0c;这样的用户体验会更好一些&#xff0c;但往往事与…

compile→错误: 不支持发行版本 17

错误: 不支持发行版本 17 具体错误描述如下&#xff1a; [ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.11.0:compile (default-compile) on project big-event: Fatal error compiling: 错误: 不支持发行版本 17 -> [Help 1] [ERROR] …

被 AI 写的游戏代码砸中是什么感觉 | 10 分钟打造你的超级 AI 编码助手

近年来&#xff0c;人工智能得到了迅猛的发展&#xff0c;并在各行各业都得到了广泛应用。尤其是近两年来&#xff0c;AI开发工具逐渐成为开发者们的新宠&#xff0c;其中通义灵码&#xff08;阿里云发布的一款基于通义大模型的 AI 编码助手&#xff09;更是引发了无限可能性的…

后端工程师快速使用axios

文章目录 01.AJAX 概念和 axios 使用模板目标讲解代码解析案例前端后端结果截图 02.URL 查询参数模板目标讲解案例前端后端结果截图 03.常用请求方法和数据提交模板目标讲解案例前端后端结果截图 04.axios 错误处理模板目标讲解案例前端后端结果截图 01.AJAX 概念和 axios 使用…

手写简易操作系统(十)--中断概述

前情提要 我们还是总结一下前面做了什么 1、计算机启动&#xff0c;BIOS将MBR导入到内存&#xff0c;并跳转到相应位置执行 2、MBR将Loader导入到内存&#xff0c;并跳转执行 3、Loader中开启保护模式&#xff0c;准备好GDT表&#xff0c;开启内存分页&#xff0c;从此之后…

07|链(下):想学“育花”还是“插花”用RouterChain确定客户意图

任务设定 鲜花养护&#xff08;保持花的健康、如何浇水、施肥等&#xff09;鲜花装饰&#xff08;如何搭配花、如何装饰场地等&#xff09; 如果接到的是第一类问题&#xff0c;你要给ChatBot A指示&#xff1b;如果接到第二类的问题&#xff0c;你要给ChatBot B指示。 整体…

Window部署AgileConfig

AgileConfig&#xff1a;分布式配置中心 github&#xff1a;GitHub - dotnetcore/AgileConfig: 基于.NET Core开发的轻量级分布式配置中心 / .NET Core lightweight configuration server 下载部署包&#xff1a;Releases dotnetcore/AgileConfig GitHub 版本&#xff1a;…

MateBook D 14 SE版(2022版)使用体验

试用了一下华为的笔记本电脑&#xff0c;我觉得是出乎意料的好用&#xff0c;配置不算高&#xff0c;但是特别流程&#xff0c;而且自带了正版的office等软件&#xff0c;生产力杠杠的&#xff0c;外观也很不错&#xff0c;设计语言很高级&#xff0c;价格不贵&#xff0c;但是…

QGIS中天地图插件的安装与使用

概述 在QGIS中可添加xyz类型的切片为数据源&#xff0c;一般作为底图加载到地图上。在QGIS中添加xyz类型的切片的操作可参考QGIS CookBook。天地图提供的服务也是xyz类型的切片&#xff0c;但是为提高其加载速度&#xff0c;一般采用了t0-t7多个节点&#xff0c;在QGIS中添加x…

rocky9 编写一键安装mysql 的sh脚本

基本操作步骤 1、虚拟机最小化安装rocky9系统&#xff0c;安装后克隆一个系统&#xff1b;1个用来获取下载的rpm包&#xff0c;一个用来编写sh 测试脚本&#xff1b; 2、修改虚拟机的 yum配置文件&#xff0c;获取获取rpm程序 &#xff1a;启用缓存&#xff0c;并修改yum下载…

高效使用git流程分享

准备 假设你已经 clone 了当前仓库&#xff0c;并且你的终端位置已经位于仓库目录中。 查询状态 查询状态常用的命令有 git status 和 git branch。 前者用于查询更改文件情况&#xff0c;后者用于展示所有分支。 chatbot-system$ git status On branch develop Your bran…

RedisCluster集群中的插槽为什么是16384个?

RedisCluster集群中的插槽为什么是16384个&#xff1f; CRC16的算法原理。 1.根据CRC16的标准选择初值CRCIn的值2.将数据的第一个字节与CRCIn高8位异或3.判断最高位&#xff0c;若该位为0左移一位&#xff0c;若为1左移一位再与多项式Hex码异或4.重复3至9位全部移位计算结束5…

PHP姓名快速匿名化工具(重组脱敏)

PHP姓名重组工具(脱敏/匿名化工具) 将excel数据姓名列粘贴提交&#xff0c;得到随机姓随机中间字随机尾字的重组姓名 那些年自用瞎搞的代码&#xff0c;今日整理成网页交提交得到结果的交互功能分享。 <?php //PHP姓名重组工具(脱敏/匿名化工具) //将excel数据姓名列粘贴…

前端面试拼图-知识广度

摘要&#xff1a;最近&#xff0c;看了下慕课2周刷完n道面试题&#xff0c;记录并添加部分可参考的文档&#xff0c;如下... 1. 移动端H5 click有300ms延迟&#xff0c; 如何解决&#xff1f; 背景&#xff1a;double tap to zoom 移动端H5中的300ms点击延迟问题通常是由浏览…

Obsidian使用200+插件与70+种主题分享

主题资源 下载方式一&#xff1a; 网盘下载 密码:a3eu 下载方式二&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1fOgP8lY29sYxkUAbTlQQCw 提取码&#xff1a;qhxa 下载解压打开红色框文件夹 上面的是插件&#xff0c;下面的是主题 以下介绍安装主题 打开Obsidi…

定义一个符号常量,并计算

这段代码的输出结果是什么 #include <stdio.h> #define PI 32 int main() { int iPI*2; printf("i%d\n",i);} 是7。 我问了一下AI&#xff0c;AI也回答错了&#xff0c;这是个值得注意的地方。

华为鸿蒙生态杀疯了 大厂高薪急聘鸿蒙开发者

前言 最近有接收到个别小伙伴的疑惑&#xff0c;说鸿蒙现在前景不好就业又困难&#xff0c;为什么我偏偏选择了他呢&#xff1f; 但其实真正了解鸿蒙前景的小伙伴都知道&#xff0c;鸿蒙系统强势来袭&#xff0c;华为“纯血鸿蒙”技术开发人员急缺&#xff0c;薪资待遇极好&a…

云原生(四)、Docker-Compose

Docker-Compose Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。它使用一个简单的 YAML 文件来配置应用程序的服务、网络和卷&#xff0c;从而使得在不同环境中轻松部署应用程序变得更加简单和可靠。 Docker Compose 主要由以下几个核心组件组成&#xf…