拦截器和过滤器

news/2024/5/10 4:44:47/文章来源:https://blog.csdn.net/weixin_46685542/article/details/127425888

拦截器和过滤器

参考:

过滤器和拦截器的区别_至今没搞明白的博客-CSDN博客_过滤器和拦截器的区别

拦截器与过滤器的区别_℡tang的博客-CSDN博客_拦截器和过滤器的区别

文章目录

  • 拦截器和过滤器
      • 过滤器
          • 概念
          • 作用
          • Filter链与Filter生命周期
        • SpringBoot 实现过滤器
          • 方式一:@WebFilter注解
          • 方式二:自定义配置类注入
      • 拦截器
        • SpringBoot 实现拦截器
      • 区别
        • 触发时机不同
      • 使用场景

过滤器

概念

Filter 过滤器,Servlet规范中三个技术 Servlet Listener Filter(顺序为L F S)

Filter是sun公司中servlet2.3后增加的一个新功能,在javaEE中定义了一个接口 javax.servlet.Filter来描述过滤器

作用

通过Filter可以拦截访问web资源的请求与响应操作,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。

在java web中,针对传入的request,或response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet进行业务逻辑,比如过滤掉非法url(不是login.do的地址请求,如果用户没有登陆都过滤掉),或者在传入servlet或者 struts的action前统一设置字符集,或者去除掉一些非法字符。

相当于:一大堆请求中,只要选择符合要求的请求留下。定义这个要求的工具就是过滤器

(一堆字母中,取一个A)

Filter是javax.servlet包下的一个接口主要有以下三个方法

destory()
doFilter(ServletRequest request,ServletResponse response,FilterCjain chain)
init(FilterConfig filterConfig)

Filter链与Filter生命周期

在这里插入图片描述

多个Filter对同一个资源进行了拦截,那么当我们在开始的Filter中执行chain.doFilter(request,response)时,是访问下一个Filter,直到最后一个Filter执行时,它后面没有了Filter,才会访问web资源

那么怎么保证顺序的?

执行顺序取决于在web.xml文件中配置的先后顺序

Filter生命周期

  1. init(): 初始化Filter 实例,Filter 的生命周期与 Servlet 是相同的,也就是当 Web 容器(tomcat)启动时,调用 init() 方法初始化实例,Filter只会初始化一次。需要设置初始化参数的时候,可以写到init()方法中。
  2. doFilter(): 业务处理,拦截要执行的请求,对请求和响应进行处理,一般需要处理的业务操作都在这个方法中实现
  3. destroy() : 销毁实例,关闭容器时调用 destroy() 销毁 Filter 的实例。

过滤器是JavaEE标准,采用函数回调的方式进行。是在请求进入容器之后,还未进入Servlet之前进行预处理,并且在请求结束返回给前端这之间进行后期处理。

SpringBoot 实现过滤器

方式一:@WebFilter注解

通过 @WebFilter 注解,将类声明为 Bean 过滤器类,在启动类添加注解 @ServletComponentScan ,让 Spring 可以扫描到。

实现javax.servlet.Filter接口,重写三个关键方法

package com.ung.myflowable.filter;import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;/*** @author: wenyi* @create: 2022/10/19* @Description: @WebFilter 属性中没有配置顺序的,执行顺序和 Filter 类名称字符排序有关 所以这个需要注意*/
@WebFilter(filterName = "filter1",//自定义过滤器的名称urlPatterns = "/filter1/*"//自定义需要拦截的URL,可以使用正则匹配,若没指定该参数值,则默认拦截所有请求
)
public class MyFilter1 implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {String filter1 = filterConfig.getInitParameter("filter1");System.out.println("==========================filter1 init" + filter1);}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {//业务处理 获取ip地址HttpServletRequest request = (HttpServletRequest) servletRequest;String remoteAddr = request.getRemoteAddr();System.out.println("MyFilter1  访问的ip:" + remoteAddr);//放行filterChain.doFilter(servletRequest, servletResponse);}@Overridepublic void destroy() {}
}
package com.ung.myflowable;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;/*** @author: wenyi* @create: 2022/10/18* @Description:*/
@SpringBootApplication
@ServletComponentScan//启动类添加注解 @ServletComponentScan 
public class MyFlowableApplication {public static void main(String[] args) {SpringApplication.run(MyFlowableApplication.class, args);}
}
方式二:自定义配置类注入

FilterRegistrationBean对象配置Filter,注解声明Bean,交由 Spring 容器管理

FilterRegistrationBean.setOrder() 决定 Filter 执行顺序。 数字小的先执行

过滤器1 MyFilter1

package com.ung.myflowable.filter;import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;/*** @author: wenyi* @create: 2022/10/19* @Description: @WebFilter 属性中没有配置顺序的,执行顺序和 Filter 类名称字符排序有关 所以这个需要注意*/
//@WebFilter(
//        filterName = "filter1",//自定义过滤器的名称
//        urlPatterns = "/filter1/*"//自定义需要拦截的URL,可以使用正则匹配,若没指定该参数值,则默认拦截所有请求
//)
public class MyFilter1 implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {String filter1 = filterConfig.getInitParameter("filter1");System.out.println("==========================filter1 init" + filter1);}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {//业务处理 获取ip地址HttpServletRequest request = (HttpServletRequest) servletRequest;String remoteAddr = request.getRemoteAddr();System.out.println("MyFilter1  访问的ip:" + remoteAddr);//放行filterChain.doFilter(servletRequest, servletResponse);}@Overridepublic void destroy() {}
}

过滤器2 MyFilter2

package com.ung.myflowable.filter;import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;/*** @author: wenyi* @create: 2022/10/19* @Description:*/
public class MyFilter2 implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {String filter2 = filterConfig.getInitParameter("filter2");System.out.println("==========================filter2 init" + filter2);}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {//业务处理 获取ip地址HttpServletRequest request = (HttpServletRequest) servletRequest;String remoteAddr = request.getRemoteAddr();System.out.println("MyFilter2  访问的ip:" + remoteAddr);filterChain.doFilter(servletRequest, servletResponse);}@Overridepublic void destroy() {}
}

配置类

package com.ung.myflowable.config;import com.ung.myflowable.filter.MyFilter1;
import com.ung.myflowable.filter.MyFilter2;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;/*** @author: wenyi* @create: 2022/10/19* @Description:*/
@Configuration
public class MyFilterConfig {/*** 注册 过滤器 Filter*/@Beanpublic FilterRegistrationBean<Filter> myFilter1() {//匹配拦截 URLString urlPatterns = "/myFilter1/*,/system/*";FilterRegistrationBean<Filter> registration = new FilterRegistrationBean<Filter>();registration.setDispatcherTypes(DispatcherType.REQUEST);registration.setFilter(new MyFilter1());registration.addUrlPatterns(StringUtils.split(urlPatterns, ","));//设置名称registration.setName("filter1");//设置过滤器链执行顺序registration.setOrder(1);//启动标识registration.setEnabled(true);//添加初始化参数registration.addInitParameter("filter1", "filter1filter1filter1filter1");return registration;}/*** 注册 过滤器 Filter*/@Beanpublic FilterRegistrationBean<Filter> myFilter2() {//匹配拦截 URLString urlPatterns = "/myFilter2/*,/system/*";FilterRegistrationBean<Filter> registration = new FilterRegistrationBean<Filter>();registration.setDispatcherTypes(DispatcherType.REQUEST);registration.setFilter(new MyFilter2());registration.addUrlPatterns(StringUtils.split(urlPatterns, ","));//设置名称registration.setName("filter2");//设置过滤器链执行顺序registration.setOrder(3);//启动标识registration.setEnabled(true);//添加初始化参数registration.addInitParameter("filter2", "filter2filter2filter2filter2filter2");return registration;}
}

拦截器

Interceptor 拦截器是spring容器的,是spring支持的java里的拦截器是动态拦截Action调用的对象,是面向切面编程(AOP,Aspect Oriented Program)的。

就是在你的Service或者一个方法前调用一个方法,或者在方法后调用一个方法。比如动态代理就是拦截器的简单实现,在你调用方法前打印出字符串(或者做其它业务逻辑的操作),也可以在你调用方法后打印出字符串,甚至在你抛出异常的时候做业务逻辑的操作。
相当于:一个流程在进行的时候,干预它的进展,甚至可以终止结束,就是拦截器的工作。

(一堆字母中,进行干预,验证,做些其他事情)

SpringBoot 实现拦截器

1.实现接口HandlerInterceptor 实现拦截器

2.在WebMvc配置类中配置拦截器,并设置拦截规则

第一步很好做:

preHandle: 预先处理,在目标的controller方法执行之前,进行处理

postHandle: 在目标的controller方法执行之后,到达指定页面之前进行处理

afterCompletion: 在页面渲染之后进行处理

package com.ung.myflowable.interceptor;import com.ung.myflowable.annotation.AbolishInterceptor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;/*** @author: wenyi* @create: 2022/10/19* @Description:*/
@Slf4j
public class MyInterceptor implements HandlerInterceptor {/*** 当url已经匹配到controller层中某个方法时,在方法执行前执行* 它会决定是否放行,返回true,放行,返回false,不会执行*/@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {HandlerMethod handlerMethod = (HandlerMethod) handler;Method method = handlerMethod.getMethod();String methodName = method.getName();log.debug("方法名:{}", methodName);// 通过方法,可以获取该方法上的自定义注解,然后通过注解来判断该方法是否要被拦截// @AbolishInterceptor 是自定义的注解AbolishInterceptor annotation = method.getAnnotation(AbolishInterceptor.class);log.info("annotation===============,{}", annotation);Parameter[] parameters = method.getParameters();if (parameters != null) {System.out.println("传入的参数name:" + parameters[0]);}if (annotation != null) {return true;}
//        String token = request.getParameter("token");
//        if (token == null || "".equals(token)) {
//            log.info("未登录");
//            return false;
//        }// 返回true才会继续执行,返回false则取消当前请求return true;}/*** url 匹配到Controller 中的某个方法,且执行完了该方法,* 但是在 DispatcherServlet 视图渲染之前执行。在这个方法中有个 ModelAndView 参数,可以在此做一些修改动作。*/@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);}/*** 在整个请求处理完成后(包括视图渲染)执行,* 做一些资源的清理工作,这个方法只有在 preHandle(……) 被成功执行后并且返回true才会被执行*/@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {HandlerInterceptor.super.afterCompletion(request, response, handler, ex);}
}

参考:SpringBoot中WebMvcConfigurationSupport与WebMvcConfigurer_LoneWalker、的博客-CSDN博客_webmvcconfigurationsupport和webmvcconfigurer

springboot2.0后 推荐使用两种方式配置WebMvc

  • 实现WebMvcConfigurer 接口
  • 继承WebMvcConfigurationSupport 类

区别:

首先从SpringBoot自动装配来讲,SpringBoot对WebMvc做了自动配置

可以找到 自动配置类 WebMvcAutoConfiguration

在这里插入图片描述

里面蓝色框表示: WebMvcConfigurer 类存在bean容器,WebMvc自动配置生效

红色框表示:WebMvcConfigurationSupport 类存在bean容器, 自动配置就不生效

WebMvcConfigurer 配置类是spring内部的配置方式,采用JavaBean的方式代替 xml的方式,可以进行自定义Handler,Interceptor,ViewResolver,MessageConverter

常用方法

 /* 拦截器配置 */
void addInterceptors(InterceptorRegistry var1);
/* 视图跳转控制器 */
void addViewControllers(ViewControllerRegistry registry);
/***静态资源处理
**/
void addResourceHandlers(ResourceHandlerRegistry registry);
/* 默认静态资源处理器 */
void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer);
/*** 这里配置视图解析器**/
void configureViewResolvers(ViewResolverRegistry registry);
/* 配置内容裁决的一些选项*/
void configureContentNegotiation(ContentNegotiationConfigurer configurer);
/** 解决跨域问题 **/
public void addCorsMappings(CorsRegistry registry) ;

WebMvcConfigurationSupport 是mvc的基本实现并包含了WebMvcConfigurer接口中的方法

WebMvcAutoConfiguration 是mvc的自动装配类并部分包含了WebMvcConfigurer接口中的方法

如果项目没有使用 WebMvcConfigurationSupport 就会使用自动配置类,进行默认配置,比如对静态资源的访问

如果自动配置类不生效,会怎样?

WebMvcProperties 和 ResourceProperties 失效

两个配置类中的属性都在 WebMvcAutoConfiguration 中使用。当WebMvc自动配置失效(WebMvcAutoConfiguration自动化配置)时,会导致无法视图解析器无法解析并返回到对应的视图。

虽然 Bean容器里面有 WebMvcConfigurationSupport 但是 这个类没有 WebMvcProperties 和 ResourceProperties属性;

解决:可以实现WebMvcConfigurer并重写相关方法来达到类似的功能

@EnableWebMvc 注解

该注解会关闭默认配置

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Import({DelegatingWebMvcConfiguration.class})
public @interface EnableWebMvc {
}

DelegatingWebMvcConfiguration这个类是继承了WebMvcConfigurationSupport的,这就是它为什么可以关闭默认配置的原因了。

希望关闭默认配置,自己完全重新实现一个

@EnableWebMvc
@Configuration
public class WebConfig implements WebMvcConfigurer {

你希望重写部分配置

//@EnableWebMvc
@Configuration
public class WebConfig implements WebMvcConfigurer {

@EnableWebMvc
@Configuration
public class WebConfig extends WebMvcAutoConfiguration {

配置类

package com.ung.myflowable.config;import com.ung.myflowable.interceptor.MyInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/*** @author: wenyi* @create: 2022/10/19* @Description: 拦截器配置类*/
@Configuration
public class MyInterceptor2Config implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {System.out.println("添加到容器中啦+++++++++++++++++++++");registry.addInterceptor(new MyInterceptor())//添加拦截器.addPathPatterns("/**")//拦截路径.excludePathPatterns("/login", "/static/*");//忽略的拦截路径}
}

区别

①:拦截器是基于java的反射机制(动态代理)的,而过滤器是基于函数的回调
②:拦截器不依赖于servlet容器,而过滤器依赖于servlet容器。
③:拦截器只对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
④:拦截器可以访问action上下文、值、栈里面的对象,而过滤器不可以。
⑤:在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
⑥:拦截器可以获取IOC容器中的各个bean,而过滤器不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。

触发时机不同

过滤器是请求进入servlet之前进行处理,请求结束返回也是,在servlet处理后,返回给前端前执行,

过滤器包裹servlet,servlet包裹拦截器

在这里插入图片描述

使用场景

SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。

1、日志记录:记录请求信息的日志,以便进行信息监控、信息统计、计算PV(Page View)等。
2、权限检查:如登录检测,进入处理器检测检测是否登录,如果没有直接返回到登录页面;
3、性能监控:有时候系统在某段时间莫名其妙的慢,可以通过拦截器在进入处理器之前记录开始时间,在处理完后记录结束时间,从而得到该请求的处理时间(如果有反向代理,如apache可以自动记录);
4、通用行为:读取cookie得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取Locale、Theme信息等,只要是多个处理器都需要的即可使用拦截器实现。
5、OpenSessionInView:如hibernate,在进入处理器打开Session,在完成后关闭Session。

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何将各大网盘整合到一起顺便挂载本地使用(文末附软件获取方式)

目录 1、Alist.exe 2、RaiDrive 今天发现了一个网盘变硬盘神器&#xff0c;它不仅安全免费&#xff0c;更全面支持&#xff1a;百度网盘、阿里云盘、天翼云盘、蓝奏云、闪电盘、夸克网盘、迅雷网盘、等众多你们听过&#xff0c;以及没有听过的所有网盘&#xff01; 直接先看效…

Mac环境下反编译工具的使用

日常工作中避免不了反编译工具经常安装&#xff08;换电脑设备、手滑把文件夹删除了。。。等等原因&#xff09;&#xff0c;而且时间一久忘记命令的使用&#xff0c;因此做下记录。 一、反编译工具三件套 apktool&#xff1a;获取apk里的资源文件、配置文件、清单文件、lib文…

毕业论文中引用方法、原理、定义等 如何降重才更有效果?

论文重复率过高是一件很痛苦的事&#xff0c;我当年的本科论文&#xff0c;一共查了四遍才过。 我的查重方法其实比较简单&#xff0c;初稿出来以后我就开始查重了&#xff0c;然后按照标注把标红的部分全部修改掉&#xff0c;而后以此类推&#xff0c;每次改外&#xff0c;或…

BIM+物联网应用,可以解决生活中的诸多问题?

hi&#xff0c;还是我&#xff0c;建模助手。 本期的头条我们聊过有关于元宇宙、BIM和智慧城市之间的些许关联。顺着这条线&#xff0c;再和大家说说更深入的东西——物联网。 它与BIM的结合&#xff0c;可以解决生活中的哪些问题。 01 物联网与BIM关系 在建筑走向智能的时代&a…

ProGAN 论文精读

作者&#xff1a;Tero Karras, Timo Aila, Samuli Laine, Jaakko Lehtinen单位&#xff1a;NVIDIA发表期刊&#xff1a;ICLR 2018 一、前期知识储备&#xff1a; 1.1DCGAN&#xff1a; 1.1.1模型结构&#xff1a; 1.1.2项目地址&#xff1a; github git clone https://git…

【附源码】计算机毕业设计SSM数据分析教学网站

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

微信公众号搭建查题系统

微信公众号搭建查题系统 本平台优点&#xff1a; 多题库查题、独立后台、响应速度快、全网平台可查、功能最全&#xff01; 1.想要给自己的公众号获得查题接口&#xff0c;只需要两步&#xff01; 2.题库&#xff1a; 查题校园题库&#xff1a;查题校园题库后台&#xff08;…

Go Machine Learning

Go Machine Learning 前言 最近因为一直在弄部署整天c写的非常头疼,趁着昨天把分割部署写好后打算换换口味,想着试试Go语言来实现一些机器学习,深度学习会是什么样子.之前推荐过Go(goplus),不过这次打算用更基础的go语法来尝试. 1.准备工作 对于某个从未涉及的领域一开始肯…

硬盘分哪几种类型及主要参数详解

硬盘分哪几种类型 按接口分为:ide、sata、scsi 。 按大小分1.8英寸、 2.5英寸、 3.5英寸、 5.25英寸。 转速分为&#xff1a; 4500转,5400转&#xff0c;7200转和万转。 缓存分为&#xff1a;2m、8m、16m。 硬盘主要参数 硬盘主要参数详解&#xff1a; 转速&#xff1a;硬盘…

Web前端:所有新前端开发人员应该具备的顶级技能

作为前端开发人员&#xff0c;确保软件程序的用户界面正常运行是你的工作&#xff0c;这是一项艰巨的工作&#xff0c;因为你必须确保每个组件都按照预期的方式工作&#xff0c;这样用户才能有良好的体验。 前端开发现在需求量很大。前端开发者管理软件的用户界面/ UX。这很重要…

我不得不学的反射

什么是反射 反射是指对于任何一个Class类&#xff0c;在运行时都可以直接得到这个类的全部成分 这种运行时动态获取信息以及动态调用类中成分的能力称为java的反射机制 获取字节码文件 获取反射对象 方法一 public static void main(String[] args) throws Exception {Cla…

学生选课系统 前后端分离 vue springboot

学生选课系统 前后端分离 vue springboot系统描述一、系统功能二、系统截图1.网络爬虫 新闻获取代码2.pom源码系统描述 基于spring boot vue的学生选课系统 前端&#xff1a; Vue ElementUI axios 后端 springboot 持久层 mybatis Plus 会话 Spring Session redis 日志 AOP Mo…

程序设计与算法(三)C++面向对象程序设计笔记 第七周 输入输出和模板

笔记按照中国大学MOOC上北京大学郭炜老师主讲的程序设计与算法&#xff08;三&#xff09;C面向对象程序设计所作&#xff0c;B站上也有资源。原课程链接如下&#xff1a; 程序设计与算法&#xff08;三&#xff09;C面向对象程序设计 其他各章节链接如下&#xff1a; 程序设…

《CTF攻防世界web题》之我什么都不会(1)

前言 &#x1f340;作者简介&#xff1a;被吉师散养、喜欢前端、学过后端、练过CTF、玩过DOS、不喜欢java的不知名学生。 &#x1f341;个人主页&#xff1a;被吉师散养的职业混子 &#x1fad2;文章目的&#xff1a;记录唯几我能做上的题 &#x1f342;相应专栏&#xff1a;CT…

[附源码]Java计算机毕业设计SSM高校创新学分申报管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

从初级进阶为高级程序员,需要经历什么?

“怎样才能成为一名高级程序员&#xff1f;” 对每个新人来说&#xff0c;大概都梦想着尽快实现职场进阶&#xff0c;从萌新成长为技术大佬。但媳妇熬成婆&#xff0c;世界上最难熬的就是工作经验…… 程序员具有明确的职业等级制度&#xff0c;依据工作经验和水平划分&#x…

vite+vue3+ts项目搭建之集成qiankun让其成为子应用模板,并能实现主子应用之间跳转切换(新增在线预览地址)

前言 以下操作&#xff0c;是续接之前 第四步 ——即&#xff1a;vitevue3tspiniaelement-plus项目已完成搭建好&#xff0c;可以直接业务开发了 主应用技术栈&#xff1a;vue2webpackjs 集成qiankun(微前端) 1、安装vite-plugin-qiankun npm install vite-plugin-qiankun2、…

Gradle 入门说难也不难,说简单吧也不简单~

在学习过程中最痛苦的事&#xff0c;并不是认为自己坚持不下去学不会&#xff0c;而是对某块知识点的碎片信息学习了很多&#xff0c;仍然无法窥其门径&#xff0c;处于懵懂状态。 就拿Gradle来说&#xff0c;我之前就是这种状态&#xff0c;不管怎么去查阅文档和视频&#xf…

联邦学习(Federated Learning):技术角度的理解

联邦学习&#xff08;Federated Learning&#xff09;&#xff1a;技术角度的理解 学习笔记 B站学习链接&#xff1a;https://www.bilibili.com/video/BV1YK4y1G7jw/?p7&vd_source7def3d3fc89c6921c7aeadf5e4023d35 1.背景与动机 例子 Example >> 问题&#xff1a…

AES加密解密算法设计(C++)

目 录 1&#xff0e; 背景与意义 4 2. 系统设计 5 2.1系统主要目标 5 2.2主要软件需求&#xff08;运行环境&#xff09; 5 2.3功能模块与系统结构 6 3 系统功能程序设计 8 3.1基本要求部分 8 3.1.1 字节替换 8 3.1.2行移位 9 3.1.3列混合 11 3.1.4密钥加 13 3.1.5密钥扩展 14 …