1.什么是Filter
Filter表示过滤器,可以把对资源的请求拦截下来,从而实现一些特殊的功能。
比如:要想访问web服务器上的资源,必须先经过滤器,过滤器处理完毕之后,才可以访问对应的资源。
2.使用步骤
- 定义:定义一个类,实现 Filter 接口,并实现其所有方法。
- 配置:在定义的类上添加 @WebFilter 注解,配置拦截资源的路径。
- 开启:在启动类上添加 @ServletComponentScan 注解开启。
代码实现:
package com.vcom.filter;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.utils.StringUtils;
import com.vcom.pojo.Result;
import com.vcom.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Slf4j
@WebFilter(urlPatterns = "/*")
public class LoginCheckFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
// 1.获取请求的url
String url = request.getRequestURL().toString();
// 2.判断请求url中是否包含login,如果是说明是登录操作,直接放行
if (url.contains("/login")) {
// 放行请求
filterChain.doFilter(request, response);
return;
}
// 3.获取令牌
String token = request.getHeader("token");
log.info("获取的token为:{}", token);
// 4.如果令牌为空,则显示没有登录
if (StringUtils.isEmpty(token)) {
Result responseResult = Result.error("没有登录!");
response.setContentType("application/json;charset=utf-8");
response.getWriter().write(JSONObject.toJSONString(responseResult));
return;
}
// 5.解析token,如果解析失败,则显示登录信息异常
try {
JwtUtils.parseJWT(token);
} catch (Exception e) {
Result responseResult = Result.error("登录信息异常");
response.setContentType("application/json;charset=utf-8");
response.getWriter().write(JSONObject.toJSONString(responseResult));
return;
}
// 6.解析成功,执行放行
filterChain.doFilter(request, response);
}
}
附上工具类:
package com.vcom.utils;
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 final String SIGNATURE_KEY = "signKey";
private static final Long EXPIRATION = System.currentTimeMillis() + 43200000L;
/**
* 生成 jwt 令牌
*
* @param claims 参数集合
* @return 令牌
*/
public static String generateJwt(Map<String, Object> claims) {
return Jwts.builder()
.addClaims(claims)
.signWith(SignatureAlgorithm.HS256, SIGNATURE_KEY)
.setExpiration(new Date(EXPIRATION))
.compact();
}
/**
* 解析JWT令牌
*
* @param jwt 令牌
* @return 令牌中存储的内容
*/
public static Claims parseJWT(String jwt) {
return Jwts.parser()
.setSigningKey(SIGNATURE_KEY)
.parseClaimsJws(jwt)
.getBody();
}
}
注意:需要在启动类上加上 @ServletComponentScan 注解
package com.vcom;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
@ServletComponentScan
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}