springboot系列十二:拦截器和文件上传

news2024/9/21 11:08:37

文章目录

  • 基本介绍
  • 拦截器应用实例
    • 需求分析
    • 代码实现
    • 注意事项和细节
  • 文件上传
    • 需求说明
    • 代码实现
    • 注意事项和细节
    • 课后扩展

在这里插入图片描述

基本介绍

1.在Spring Boot项目中, 拦截器是开发中常用手段, 要来做登陆验证, 性能检查, 日志记录等.

2.基本步骤:
√ 编写一个拦截器实现HandlerInterceptor接口
√ 拦截器注册到配置类中(实现WebMvcConfigureraddInterceptors)
√ 指定拦截器规则
√ 回顾SpringMVC中写到的Interceptor: SpringMVC系列十一: 文件上传与自定义拦截器

拦截器应用实例

需求分析

需求: 使用拦截器防止用户非法登录. 使用拦截器就不需要在每个方法验证了.

●浏览器输入 http://localhost:8080/manage.html, 如果用户没有登录, 则返回登录页面

在这里插入图片描述

1.修改AdminController.java

使用Lombok支持日志输出

@Controller
@Slf4j
public class AdminController {
    //响应用户的登录请求
    @PostMapping("/login")
    public String login(Admin admin, HttpSession session, Model model) {
    		//...
    }

    //处理用户请求 manage.html
    @GetMapping("/manage.html")
    public String mainPage(Model model,
                           @SessionAttribute(value = "loginAdmin", required = false) Admin admin) {
        //这里暂时在方法中验证, 后面我们统一使用拦截器

        log.info("进入mainPage()");

        //用集合模拟用户数据, 放入到request域中, 并显示
        List<User> users = new ArrayList<>();
        users.add(new User(1, "张三", "123456", 23, "张三@163.com"));
        users.add(new User(2, "李四", "123456", 24, "李四@163.com"));
        users.add(new User(3, "王五", "123456", 25, "王五@163.com"));
        users.add(new User(4, "赵六", "123456", 26, "赵六@163.com"));
        users.add(new User(5, "田七", "123456", 27, "田七@163.com"));

        //将数据放入到request域中
        model.addAttribute("users", users);
        return "manage";//这里是我们的视图解析器,到 templates/manage.html
    }
}

2.修改 templates/manage.html, 去掉 [[${session.loginAdmin.name}]], 大体代码如下.

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>管理后台</title>
</head>
<body bgcolor="#CED3FE">
<img src="images/1.GIF"/>
<a href='#'>返回管理界面</a>  <a href='#' th:href="@{/}">安全退出</a>   欢迎您:
<hr/>
<div style="text-align: center">
    <h1>管理雇员~</h1>
    <table border="1px" cellspacing="0" bordercolor="green" style="width:800px;margin: auto">
        <tr bgcolor="pink">
            <td>id</td>
            <td>name</td>
            <td>pwd</td>
            <td>age</td>
            <td>email</td>
        </tr>
        <tr bgcolor="#ffc0cb" th:each="user:${users}">
            <td th:text="${user.id}">a</td>
            <td th:text="${user.name}">b</td>
            <td th:text="${user.password}">c</td>
            <td th:text="${user.age}">d</td>
            <td th:text="${user.email}">e</td>
        </tr>
    </table>
    <br/>
</div>
<hr/>
<img src="images/logo.png"/>
</body>
</html>

3.浏览器/Postman, 能够访问 http://localhost:8080/manage.html

在这里插入图片描述

代码实现

1.创建src/main/java/com/zzw/springboot/interceptor/LoginInterceptor.java

@Slf4j
public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //为了让你们看到访问的URI
        String requestURI = request.getRequestURI();
        log.info("preHandle拦截到的请求的URI={}", requestURI);

        //进行登录的验证
        HttpSession session = request.getSession();
        Object loginAdmin = session.getAttribute("loginAdmin");
        if (loginAdmin != null) {//说明该用户已经成功登录
            //放行
            return true;
        }
        //拦截, 重新返回登陆页面
        request.setAttribute("error", "你没有登录, 请重新登录~");
        request.getRequestDispatcher("/").forward(request, response);
        return false;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.info("postHandle() 被执行...");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info("afterCompletion() 被执行...");
    }
}

2.注册拦截器到配置类中(实现WebMvcConfigurer接口的addInterceptors方法)

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //注册自定义拦截器 LoginInterceptor
        registry.addInterceptor(new LoginInterceptor())
                .addPathPatterns("/**") //拦截所有的请求
                .excludePathPatterns("/", "/login","/images/**"); //指定要放行的, 后面可以根据业务需求, 添加放行的请求路径
    }
}

3.测试

在这里插入图片描述

注意事项和细节

1.将/images/**去掉会有什么后果.

1)首先, 浏览器禁用缓存, 重启(是为了去掉保存在session里的登录信息).

在这里插入图片描述

2)其次, 刷新页面 http://localhost:8080/, 图片请求被拦截.

在这里插入图片描述

3)因为static是类路径下, 所谓的静态资源访问, 所以可以写成images/**, 而不用写成static/images/**

4)在前端代码中, 图片url可以写成<img src="images/1.GIF">, <img src="images/logo.png">

2.URIURL的区别. HttpServletRequest常用方法
URI: Universal Resource Identifier
URL: Universal Resource Locator
Identifier: 标识符. Locator: 定位器, 从字面上来看, URI可以在站点内唯一标识一个资源, URL可以在全网内提供找到该资源的路径.

举例

String requestURI = request.getRequestURI();
String requestURL = request.getRequestURL().toString();
log.info("preHandle拦截到的请求的URI={}", requestURI);// /manage.html
log.info("preHandle拦截到的请求的URL={}", requestURL);// http://localhost:8080/manage.html

3.注册拦截器, 依然可以使用如下方式, 参考注册自定义转换器

@Configuration
public class WebConfig {
    @Bean
    public WebMvcConfigurer webMvcConfigurer() {
        /*
        class WebConfig2$1 implements WebMvcConfigurer {
            @Override
            public void addInterceptors(InterceptorRegistry registry) {
                //注册自定义拦截器 LoginInterceptor
                registry.addInterceptor(new LoginInterceptor())
                        .addPathPatterns("/**") //拦截所有的请求
                        .excludePathPatterns("/", "/login", "/images/**"); //指定要放行的, 后面可以根据业务需求, 添加放行的请求路径
            }
        }
        WebMvcConfigurer webMvcConfigurer = new WebConfig2$1();
        return webMvcConfigurer;
         */
        return new WebMvcConfigurer() {
            @Override
            public void addInterceptors(InterceptorRegistry registry) {
                System.out.println("~~~~~匿名内部类注册拦截器~~~~~");
                //注册自定义拦截器 LoginInterceptor
                registry.addInterceptor(new LoginInterceptor())
                        .addPathPatterns("/**") //拦截所有的请求
                        .excludePathPatterns("/", "/login", "/images/**"); //指定要放行的, 后面可以根据业务需求, 添加放行的请求路径
            }
        };
    }
}

文件上传

需求说明

需求: 演示在SpringBoot 中通过表单注册用户, 并支持上传图片.

回顾 SpringMVC文件上传

代码实现

1.创建templates/upload.html, 要求头像只能选择一个, 而宠物可以上传多张图片

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>文件上传</title>
</head>
<body bgcolor="#CED3FE">
<img src="images/1.GIF">
<div style="text-align: center;">
    <h1>注册用户~</h1>
    <form action="#" th:action="@{/upload}" method="post" enctype="multipart/form-data">
        用户名:<input type="text" style="width: 150px" name="username"><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="avatar"><br/><br/>
        宠 物:<input type="file" style="width: 150px" name="pets" multiple><br/><br/>
        <input type="submit" value="注册"/>
        <input type="reset" value="重新填写">
    </form>
</div>
<img src="images/logo.png">
</body>
</html>

2.指定拦截器放行upload.html. upload

@Configuration
public class WebConfig {
    @Bean
    public WebMvcConfigurer webMvcConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addInterceptors(InterceptorRegistry registry) {
                System.out.println("~~~~~匿名内部类注册拦截器~~~~~");
                //注册自定义拦截器 LoginInterceptor
                registry.addInterceptor(new LoginInterceptor())
                        .addPathPatterns("/**") //拦截所有的请求
                        .excludePathPatterns("/", "/login", "/images/**", "/upload.html", "/upload"); //指定要放行的, 后面可以根据业务需求, 添加放行的请求路径
            }
        };
    }
}

3.创建src/main/java/com/zzw/springboot/controller/UploadController.java

@Controller
public class UploadController {

    //处理转发到用户注册页面upload.html-可以完成文件上传页面
    @RequestMapping("/upload.html")
    public String uploadPage() {
        return "upload";//thymeleaf进行视图解析, 转发到templates/upload.html
    }
}

4.浏览器访问 http://localhost:8080/upload.html, 测试

在这里插入图片描述

5.修改src/main/java/com/zzw/springboot/controller/UploadController.java

@Controller
@Slf4j
public class UploadController {

    //处理转发到用户注册页面upload.html-可以完成文件上传页面
    @RequestMapping("/upload.html")
    public String uploadPage() {
        return "upload";//thymeleaf进行视图解析, 转发到templates/upload.html
    }

    //处理用户的注册请求-包括处理文件上传
    @PostMapping("/upload")
    @ResponseBody
    public String upload(@RequestParam(value = "username") String name,
                         @RequestParam(value = "email") String email,
                         @RequestParam(value = "age") Integer age,
                         @RequestParam(value = "job") String job,
                         @RequestParam(value = "avatar") MultipartFile avatar,
                         @RequestParam(value = "pets") MultipartFile[] pets) {
        //输出获取到的信息
        log.info("上传的信息 name={}, email={}, age={}, job={}, avartar={}, pets={}",
                name, email, age, job, avatar.getSize(), pets.length);

        //如果信息都注册成功, 我们就将文件保存到指定的目录, 比如保存在d:\\temp_upload
        //1.我们先将文件保存到指定到指定的目录, 比如d:\\temp_upload
        //2.后面我们再演示把文件保存到动态创建的目录
        
        return "用户注册成功/文件上传成功";
    }
}

6.修改src/main/java/com/zzw/springboot/controller/UploadController.java
SpringMVC系列十一: 文件上传与自定义拦截器

@Controller
@Slf4j
public class UploadController {

    //处理转发到用户注册页面upload.html-可以完成文件上传页面
    @RequestMapping("/upload.html")
    public String uploadPage() {
        return "upload";//thymeleaf进行视图解析, 转发到templates/upload.html
    }

    //处理用户的注册请求-包括处理文件上传
    @PostMapping("/upload")
    @ResponseBody
    public String upload(@RequestParam(value = "username") String name,
                         @RequestParam(value = "email") String email,
                         @RequestParam(value = "age") Integer age,
                         @RequestParam(value = "job") String job,
                         @RequestParam(value = "avatar") MultipartFile avatar,
                         @RequestParam(value = "pets") MultipartFile[] pets) throws IOException {
        //输出获取到的信息
        log.info("上传的信息 name={}, email={}, age={}, job={}, avartar={}, pets={}",
                name, email, age, job, avatar.getSize(), pets.length);

        //如果信息都注册成功, 我们就将文件保存到指定的目录, 比如保存在d:\\temp_upload
        //1.我们先将文件保存到指定到指定的目录, 比如d:\\temp_upload
        //2.后面我们再演示把文件保存到动态创建的目录

        if (!avatar.isEmpty()) {//处理头像上传
            String originalFilename = avatar.getOriginalFilename();
            log.info("你要上传的文件名={}", originalFilename);
            //你要把文件上传到哪个路径[全路径: 包括文件名]
            String fileFullPath = "d:\\temp_upload\\" + originalFilename;
            File file = new File(fileFullPath);
            avatar.transferTo(file);
        }
        if (pets.length > 0) {//处理宠物图片[多张]
            for (MultipartFile pet : pets) {//循环遍历
                if (!pet.isEmpty()) {
                    String originalFilename = pet.getOriginalFilename();//宠物图片名
                    log.info("你要上传的宠物名={}", originalFilename);
                    String fileFullPath = "d:\\temp_upload\\" + originalFilename;
                    File file = new File(fileFullPath);
                    pet.transferTo(file);
                }
            }
        }
        return "用户注册成功/文件上传成功";
    }
}

7.测试

在这里插入图片描述

8.修改src/main/java/com/zzw/springboot/controller/UploadController.java

@Controller
@Slf4j
public class UploadController {

    //处理转发到用户注册页面upload.html-可以完成文件上传页面
    @RequestMapping("/upload.html")
    public String uploadPage() {
        return "upload";//thymeleaf进行视图解析, 转发到templates/upload.html
    }

    //处理用户的注册请求-包括处理文件上传
    @PostMapping("/upload")
    @ResponseBody
    public String upload(@RequestParam(value = "username") String name,
                         @RequestParam(value = "email") String email,
                         @RequestParam(value = "age") Integer age,
                         @RequestParam(value = "job") String job,
                         @RequestParam(value = "avatar") MultipartFile avatar,
                         @RequestParam(value = "pets") MultipartFile[] pets) throws IOException {
        //输出获取到的信息
        log.info("上传的信息 name={}, email={}, age={}, job={}, avartar={}, pets={}",
                name, email, age, job, avatar.getSize(), pets.length);

        //如果信息都注册成功, 我们就将文件保存到指定的目录, 比如保存在d:\\temp_upload
        //1.我们先将文件保存到指定到指定的目录, 比如d:\\temp_upload
        //2.后面我们再演示把文件保存到动态创建的目录
        //  比如E:\idea_project\zzw_springboot\springboot-usersys\target\classes\static\images\\upload\

        //得到类路径(运行的时候)
        String path = ResourceUtils.getURL("classpath:").getPath();
        //log.info("path={}", path);

        //动态创建指定的目录
        File parentFile = new File(path + "static/images/upload/");
        if (!parentFile.exists()) {//如果目录不存在, 就创建 java io
            parentFile.mkdirs();
        }

        if (!avatar.isEmpty()) {//处理头像上传
            String originalFilename = avatar.getOriginalFilename();
            log.info("你要上传的文件名={}", originalFilename);
            //你要把文件上传到哪个路径[全路径: 包括文件名]
            //String fileFullPath = "d:\\temp_upload\\" + originalFilename;
            //File file = new File(fileFullPath);
            //这里我们需要指定保存文件的绝对路径: E:\idea_project\zzw_springboot\springboot-usersys\target\classes\static\images\\upload\

            //log.info("保存文件的绝对路径={}", parentFile.getAbsolutePath());
            //保存到动态创建的目录
            avatar.transferTo(new File(parentFile, originalFilename));
        }
        if (pets.length > 0) {//处理宠物图片[多张]
            for (MultipartFile pet : pets) {//循环遍历
                if (!pet.isEmpty()) {
                    String originalFilename = pet.getOriginalFilename();//宠物图片名
                    log.info("你要上传的宠物名={}", originalFilename);
                    //String fileFullPath = "d:\\temp_upload\\" + originalFilename;
                    //File file = new File(fileFullPath);

                    //保存到动态创建的目录
                    pet.transferTo(new File(parentFile, originalFilename));
                }
            }
        }
        return "用户注册成功/文件上传成功";
    }
}

9.测试

在这里插入图片描述

注意事项和细节

1.根据项目需求修改文件上传的参数,否则文件上传会抛出异常。MultipartProperties.java

@ConfigurationProperties用法

properties自动配置

在这里插入图片描述

在这里插入图片描述

2.修改src/main/resources/application.yml

spring:
  servlet:
    multipart:
      max-file-size: 10MB
      max-request-size: 100MB

3.上传超大文件 8MB

在这里插入图片描述

在这里插入图片描述

课后扩展

1.解决文件覆盖问题, 如果文件名相同, 会出现覆盖问题, 如何解决.

2.解决文件分目录存放问题, 如果将文件都上传到一个目录下, 当上传文件很多时, 会造成访问文件速度变慢. 因此, 可以将文件上传到不同目录, 比如 一天上传的文件, 统一以年/月/日的形式放到一个文件夹, 比如2024/8/5目录.

3.参考 项目实战系列三: 家居购项目 第六部分
JavaWeb系列二十三: web 应用常用功能(文件上传下载)

代码实现
1.新建src/main/java/com/zzw/springboot/util/WebUtils.java

public class WebUtils {
    //定义一个文件上传的路径
    public static String UPLOAD_FILE_DIRECTORY = "static/images/upload/";
    
    //编写方法, 生成一个目录-根据当前日期, 生成 年/月/日
    public static String getUploadFileDirectory() {
        LocalDate ld = LocalDate.now();
        return ld.getYear() + "/" + ld.getMonthValue() + "/" + ld.getDayOfMonth() + "/";
    }
}

2.修改src/main/java/com/zzw/springboot/controller/UploadController.java

@Controller
@Slf4j
public class UploadController {

    //处理转发到用户注册页面upload.html-可以完成文件上传页面
    @RequestMapping("/upload.html")
    public String uploadPage() {
        return "upload";//thymeleaf进行视图解析, 转发到templates/upload.html
    }

    //处理用户的注册请求-包括处理文件上传
    @PostMapping("/upload")
    @ResponseBody
    public String upload(@RequestParam(value = "username", required = false) String name,
                         @RequestParam(value = "email", required = false) String email,
                         @RequestParam(value = "age", required = false) Integer age,
                         @RequestParam(value = "job", required = false) String job,
                         @RequestParam(value = "avatar", required = false) MultipartFile avatar,
                         @RequestParam(value = "pets", required = false) MultipartFile[] pets) throws IOException {
        //输出获取到的信息
        log.info("上传的信息 name={}, email={}, age={}, job={}, avartar={}, pets={}",
                name, email, age, job, avatar.getSize(), pets.length);

        //如果信息都注册成功, 我们就将文件保存到指定的目录, 比如保存在d:\\temp_upload
        //1.我们先将文件保存到指定到指定的目录, 比如d:\\temp_upload
        //2.后面我们再演示把文件保存到动态创建的目录
        //  比如E:\idea_project\zzw_springboot\springboot-usersys\target\classes\static\images\\upload\

        //得到类路径(运行的时候)
        String path = ResourceUtils.getURL("classpath:").getPath();
        //log.info("path={}", path);

        //动态创建指定的目录
        File parentFile = new File(path + WebUtils.getUploadFileDirectory());
        if (!parentFile.exists()) {//如果目录不存在, 就创建 java io
            parentFile.mkdirs();
        }

        if (!avatar.isEmpty()) {//处理头像上传
            String originalFilename = avatar.getOriginalFilename();
            log.info("你要上传的文件名={}", originalFilename);

            //对上传的文件名进行处理, 增加一个前缀, 保证是唯一的, 防止文件名重复造成覆盖
            String fileName = UUID.randomUUID().toString() + "_" + System.currentTimeMillis() + "_" + originalFilename;

            //你要把文件上传到哪个路径[全路径: 包括文件名]
            //String fileFullPath = "d:\\temp_upload\\" + originalFilename;
            //File file = new File(fileFullPath);
            //这里我们需要指定保存文件的绝对路径: E:\idea_project\zzw_springboot\springboot-usersys\target\classes\static\images\\upload\

            //log.info("保存文件的绝对路径={}", parentFile.getAbsolutePath());
            //保存到动态创建的目录
            File destPath = new File(parentFile, fileName);
            if (!destPath.exists()) {
                destPath.mkdirs();
            }
            avatar.transferTo(new File(destPath, fileName));
        }
        if (pets.length > 0) {//处理宠物图片[多张]
            for (MultipartFile pet : pets) {//循环遍历
                if (!pet.isEmpty()) {
                    String originalFilename = pet.getOriginalFilename();//宠物图片名
                    log.info("你要上传的宠物名={}", originalFilename);

                    //对上传的文件名进行处理, 增加一个前缀, 保证是唯一的, 防止文件名重复造成覆盖
                    String fileName = UUID.randomUUID().toString() + "_" + System.currentTimeMillis() + "_" + originalFilename;

                    //String fileFullPath = "d:\\temp_upload\\" + originalFilename;
                    //File file = new File(fileFullPath);

                    //保存到动态创建的目录
                    File destPath = new File(parentFile, fileName);
                    if (!destPath.exists()) {
                        destPath.mkdirs();
                    }
                    avatar.transferTo(new File(destPath, fileName));
                }
            }
        }
        return "用户注册成功/文件上传成功";
    }
}

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

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

相关文章

【简单】 猿人学web第一届 第3题 罗生门

请求逻辑分析 数据接口为https://match.yuanrenxue.cn/api/match/3?page1 这一题的 请求参数 与 cookie 都没有加密参数 每次请求数据接口前都会请求 jssm 接口 requests 照着请求逻辑去请求&#xff0c;发现是失败的&#xff08;数据接口返回包含 js标签 代码&#xff09;…

Unity数据持久化 之 Json序列化与反序列化

语法规则可以看这篇文章&#xff1a;Unity数据持久化 之 Json 语法速通-CSDN博客 Q:Unity是通过什么来对Json文件进行处理的&#xff1f; A:JsonUtility&#xff1a;Unity 提供了 JsonUtility 类&#xff0c;用于将对象序列化为 JSON 字符串或将 JSON 字符串反序列化为对象。…

从 MySQL 迁移到 TiDB:使用 SQL-Replay 工具进行真实线上流量回放测试 SOP

导读 在 MySQL 迁移至 TiDB 的过程中&#xff0c;兼容性和性能验证至关重要。SQL-Replay 是一款实用工具&#xff0c;用于评估数据库的兼容性和性能&#xff0c;支持日志解析、查询回放、性能测量和报告生成等功能。 本文介绍了 SQL-Replay 工具的安装和使用步骤&#xff0c;…

基于springboot的医院后台管理系统的设计与实现

TOC springboot167基于springboot的医院后台管理系统的设计与实现 第1章 绪论 1.1 研究背景 互联网概念的产生到如今的蓬勃发展&#xff0c;用了短短的几十年时间就风靡全球&#xff0c;使得全球各个行业都进行了互联网的改造升级&#xff0c;标志着互联网浪潮的来临。在这…

【C语言】格式化输出占位符及其标志字符详解(基于ISO/IEC 9899:2024)

目录 C语言格式化输出占位符及其标志字符详解&#xff08;基于ISO/IEC 9899:2024&#xff09;1. 格式说明符的基本结构1.1 标志字符&#xff08;Flags&#xff09;示例代码 1.2 宽度&#xff08;Width&#xff09;示例代码 1.3 精度&#xff08;Precision&#xff09;示例代码 …

一键换肤(Echarts 自定义主题)

一键换肤&#xff08;Echarts 自定义主题&#xff09; 一、使用官方主题配置工具 官方主题配置工具&#xff1a;https://echarts.apache.org/zh/theme-builder.html 如果以上主题不满足使用&#xff0c;可以自己自定义主题 例如&#xff1a;修改背景、标题等&#xff0c;可…

字节跳动飞书一面0715

进程间通信方式有哪些 1、管道通信&#xff0c;分为匿名管道和有名管道&#xff0c;匿名管道只能在有亲缘关系如父子进程间使用。有名管道可以允许无亲缘关系进程间的通信。它们都是半双工的通信方式&#xff0c;数据只能单向流动。 2、消息队列&#xff0c;用内核中的链表实现…

深入理解WAF(Web应用防火墙)及其安全防御策略

随着互联网的普及和发展&#xff0c;Web应用也面临着越来越多的安全威胁&#xff0c;如SQL注入、跨站脚本&#xff08;XSS&#xff09;、跨站请求伪造&#xff08;CSRF&#xff09;等。这些威胁不仅可能造成数据泄露&#xff0c;还可能导致业务中断和品牌受损。本文将以快快网络…

JavaEE 第9节 阻塞队列详解

一、概念 阻塞队列是在普通队列&#xff08;先进先出的数据结构&#xff09;的基础上增加了阻塞属性的特殊队列 1&#xff09;当阻塞队列空的时候&#xff0c;如果继续出队元素会进入阻塞状态&#xff0c;直到其他线程入队元素。 2&#xff09;当阻塞队列满的时候&#xff0c;…

瑞萨电子并购Altium 引领行业创新与发展

公开资料显示&#xff0c;2023 年 6 月&#xff0c;瑞萨电子曾宣布在 Altium 的 Altium 365 云平台上实现了所有 PCB 设计的标准化开发。瑞萨电子一直与 Altium 合作&#xff0c;将其所有产品的 ECAD 库发布到 Altium Public Vault。借助 Altium365 上的制造商零件搜索等功能&a…

ROW_NUMBER(), RANK(), DENSE_RANK() SQL排序函数图文详解

ROW_NUMBER(), RANK(), DENSE_RANK() ROW_NUMBER(): 为结果集中的每一行分配唯一的连续编号。即使有重复的值&#xff0c;ROW_NUMBER() 也会为它们分配不同的序号。 SELECT column_name, ROW_NUMBER() OVER (ORDER BY column_name) AS row_num FROM table_name;2. RANK(): 对结…

高可用集群keepalived从部署到实战一篇解决

目录 一.高可用集群 1.1 集群类型 1.2 系统可用性 1.3 系统故障 1.4 实现高可用 1.5.VRRP&#xff1a; 1.5.1 VRRP 相关术语 1.5.2 VRRP 相关技术 二.Keepalived 部署 2.1 keepalived 简介 2.2keepalived架构 2.3 Keepalived 环境准备 2.4 Keepalived 相关文件 2.…

java实现七牛云内容审核功能,文本、图片和视频的内容审核(鉴黄、鉴暴恐、敏感人物)

目录 1、七牛云内容审核介绍 2、查看内容审核官方文档 2.1、文本内容审核 2.1.1、文本内容审核的请求示例 2.1.2、文本内容审核的返回示例 2.2、图片内容审核 2.2.1、请求参数 2.2.2、返回参数 2.3、视频内容审核 3、代码实现 3.1、前期代码准备 3.2、文本内容审核…

基于Spring + Vue的旅游景区项目+源代码+文档说明

文章目录 源代码下载地址项目介绍项目功能界面预览 项目备注源代码下载地址 源代码下载地址 点击这里下载源码 项目介绍 基于Spring Vue的旅游景区项目 项目功能 民宿管理员&#xff1a;订单数量统计&#xff0c;订单交易额统计&#xff0c;客房统计饼图&#xff0c;酒店…

【STM32嵌入式系统设计与开发拓展】——14_定时器之输入捕获

参考哔站&#xff1a;链接: 铁头山羊 一、微控制器的高级定时与控制功能集合 1、时基单元 2、输入捕获 3、输出比较 4、从模式控制器 5、高级定时器的输出控制 二、问题集合 1、什么是定时器 定时器是一种专门负责定时功能的片上外设GPI0AFI0EXTIUSART RCC I2C) 2、定时器…

飞越现实:3D可视化引领飞行体验新纪元

在浩瀚的蓝天之下&#xff0c;飞机以优雅的姿态划破长空&#xff0c;每一次起降、每一次盘旋&#xff0c;都是对速度与科技的完美诠释。而今&#xff0c;随着科技的飞速发展&#xff0c;我们不再仅仅满足于仰望天际的壮丽景象&#xff0c;而是能够借助先进的3D可视化技术&#…

JavaEE 第10节 线程池(Thread Pool)介绍

目录 一、线程池是什么 二、为什么线程池中取线程会比直接向操作系统申请来的高效&#xff1f; 三、JAVA标准库中的线程池 &#xff08;1&#xff09;类&#xff1a;ThreadPoolExecutor 1、int corePoolSize与int maximumPoolSize 2、long keepAlive和TimeUnit unit 3、Blo…

MySQL第6讲--DQL(数据查询语言)的基本操作之基本和条件查询

文章目录 前言DQL(数据查询语言)基本操作查询操作基本查询示例1&#xff1a;查询表格的name&#xff0c;age&#xff0c;并返回&#xff1b;示例2&#xff1a;查询表格中的所有字段&#xff1b;示例3&#xff1a;查询所有员工的工号并返回&#xff0c;起别名&#xff1b;示例4&…

人工智能在新药研发领域中发挥着至关重要的作用

本综述主要介绍机器学习和深度学习方法在药物发现领域的应用进展以及相关企业。 声明&#xff1a;本文为火石创造原创文章&#xff0c;欢迎个人转发分享&#xff0c;网站、公众号等转载需经授权。 本文选自《药学进展》2021年第7期&#xff0c;作者黄芳 1&#xff0c;杨红飞 1…