@Slf4j
@WebFilter("/*")
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;
//2.获取请求url
String url = request.getRequestURI();
log.info("url的值是: {}",url);
//3.判断请求url是否登录,如果是就放行
if ("/login".equals(url)){
filterChain.doFilter(request,response);
return;
}
//4.走到这行一定不是登录,获取请求头的token(令牌)
String token = request.getHeader("token");
//5.token不存在,返回前端未登录
if (token == null || token.equals("")){
String json = new ObjectMapper().writeValueAsString(Result.error("NOT_LOGIN"));
response.setContentType("application/json;charset=utf-8");
response.getWriter().write(json);
return;
}
//6.解析token,如果解析失败,返回前端未登录
try {
JwtUtils.parseJWT(token);
} catch (Exception e) {
//出现异常:token校验不通过,返回
String json = new ObjectMapper().writeValueAsString(Result.error("NOT_LOGIN"));
response.setContentType("application/json;charset=utf-8");
response.getWriter().write(json);
return;
}
//7.放行
filterChain.doFilter(request,response);
}
}
这段代码是一个基于Java Servlet的登录检查过滤器,用于在用户发起请求时检查用户是否已经登录。现在我将为你详细解释每一部分代码的含义:
@Slf4j
@WebFilter("/*")
public class LoginCheckFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//...
}
}
这段代码定义了一个名为LoginCheckFilter
的过滤器,用于在每次请求到达时进行登录检查。下面是每段代码的含义:
-
@Slf4j
:这是一个Lombok注解,会自动为LoginCheckFilter
类生成一个名为log
的日志记录器。 -
@WebFilter("/*")
:这个注解指定过滤器将会拦截所有URL路径的请求。 -
public class LoginCheckFilter implements Filter
:定义了一个实现了Filter
接口的LoginCheckFilter
过滤器类。 -
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,FilterChain filterChain) throwsIOException, ServletException
:实现了Filter
接口中的doFilter
方法,用于实际的过滤逻辑。
接下来,我会解释这个方法中的具体内容:
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
String url = request.getRequestURI();
log.info("url的值是: {}", url);
-
将ServletRequest类型的
servletRequest
对象强制转换为HttpServletRequest类型的request
对象,ServletResponse类型的servletResponse
对象强制转换为HttpServletResponse类型的response
对象。这样可以使用HttpServletRequest和HttpServletResponse提供的方法。 -
使用
request.getRequestURI()
方法获取当前请求的URL路径。 -
使用日志记录器
log
打印日志,记录请求的URL路径。
if ("/login".equals(url)){
filterChain.doFilter(request, response);
return;
}
-
检查当前请求的URL是否为"/login",如果是,则直接放行(通过调用
filterChain.doFilter(request, response)
方法)。 -
return;
语句表示在这个条件满足时直接结束方法执行,不会继续执行后面的过滤逻辑。
String token = request.getHeader("token");
if (token == null || token.equals("")){
String json = new ObjectMapper().writeValueAsString(Result.error("NOT_LOGIN"));
response.setContentType("application/json;charset=utf-8");
response.getWriter().write(json);
return;
}
-
获取请求头中名为"token"的值,存储在
token
变量中。这个"token"在此处表示用户的令牌。 -
检查
token
是否为空或为空字符串,如果是,则表示用户未登录。 -
构造一个错误信息的JSON字符串,并设置响应的Content-Type为"application/json;charset=utf-8"。
-
通过响应对象的
getWriter()
方法获取一个PrintWriter对象,并使用write()
方法将JSON字符串作为响应体写入输出流中。 -
return;
语句表示在这个条件满足时直接结束方法执行,不会继续执行后面的过滤逻辑。
try {
JwtUtils.parseJWT(token);
} catch (Exception e) {
String json = new ObjectMapper().writeValueAsString(Result.error("NOT_LOGIN"));
response.setContentType("application/json;charset=utf-8");
response.getWriter().write(json);
return;
}
-
使用
JwtUtils.parseJWT(token)
方法对令牌进行解析和验证。如果解析失败,会抛出一个异常。 -
在
catch
块中,捕获解析异常,并构造一个错误信息的JSON字符串。 -
设置响应的Content-Type为"application/json;charset=utf-8"。
-
通过响应对象的
getWriter()
方法获取一个PrintWriter对象,并使用write()
方法将JSON字符串作为响应体写入输出流中。
最后一部分代码是以下内容:
filterChain.doFilter(request, response);
如果前面的条件均不满足,则表示用户已经登录且令牌验证通过。此时可以将请求和响应对象传递给过滤器链中的下一个过滤器或Servlet,通过调用filterChain.doFilter(request, response)
方法来实现。
这段代码作为过滤器的一部分,在用户每次发起请求时进行登录检查。当用户请求"/login"时,直接放行;当用户请求其他URL时,检查请求头中的"token"是否存在,并进行相应的处理。通过这个过滤器,可以进行登录验证、安全控制以及其他业务逻辑的处理。