Filter 过滤器
对所有请求都可以过滤。
实现Filter接口,重写几个方法,加上@WebFilter注解,表示拦截哪些路由,如上是所有请求都会拦截。
然后还需要在入口处加上@SvlterComponentScan注解,因为Filter是javaweb三大组件之一,并不是springboot的内容。
chain.doFilter是放行该请求的意思,如果没有将会卡在当前过滤器上。
过滤器链
一个服务可以配置多个过滤器,多个过滤器形成过滤器链。有点像koa的洋葱模型。
过滤器1执行 -> 过滤器2执行 -> 执行主要逻辑 -> 过滤器2放行后的逻辑执行 -> 过滤器1放行后的逻辑执行
那么怎么区分那个过滤器先执行呢?通过过滤器首字母排序来决定。
Interceptor拦截器
拦截器是Spring框架提供的,跟filter不一样。
使用:
实现HandlerInterceptor
接口,重写方法,其中preHanldel是在controller执行前执行,返回值作为放行的条件。
postHandle是在controller执行后执行。
实现拦截器之后,还需要配置才能生效。
实现WebMvcConfigurer接口,然后使用@Configuration,这样springboot启动的时候会自动扫描该注解,生效该配置。
如上就是将拦截器注册,并指定其拦截的接口。
拦截器-拦截路径
可以通过addPathPatterns指定哪些路径需要拦截,通过excludePathPatterns指定哪些路径不需要拦截。
执行时机
上面说过,拦截器是spring框架提供的,而过滤器是tomcat框架提供的,如图。
如果都存在的话,会先执行过滤器,再执行拦截器的逻辑。
过滤器会拦截所有的请求资源,而拦截器只会拦截Spring环境中的资源。
案例 实现jwt登陆验证
安装对应依赖
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
实现jwtUtils类
package com.example.demo.util;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;
import java.util.Map;
public class JwtUtils {
private static String singKey = "test1234"; // 密钥
private static long expire = 432000L; //过期时间
public static String generatorToken(Map<String, Object> data) {
String jwt = Jwts.builder()
.addClaims(data)
.signWith(SignatureAlgorithm.HS256, JwtUtils.singKey)
.setExpiration(new Date(System.currentTimeMillis() + JwtUtils.expire))
.compact();
return jwt;
}
public static Claims parseToken(String token) {
Claims calims = Jwts.parser()
.setSigningKey(singKey)
.parseClaimsJws(token)
.getBody();
return calims;
}
}
使用jwt生成token
@Slf4j
@RestController
public class LoginController {
@PostMapping("/login")
public Result login(@RequestBody LoginUser body){
Map<String, Object> data = new HashMap<>();
log.info("{},{}", body.getName(),body.getPassword());
data.put("name", body.getName());
data.put("password", body.getPassword());
String token =