需求:登陆拦截,设置未登录不可直接通过url地址访问网站内部。
1.给项目启动类加上注解 @ServletComponentScan //开启扫描配置的过滤器,监听器
@Slf4j
@SpringBootApplication
@ServletComponentScan //开启扫描配置的过滤器,监听器
public class ReggieApplication {
public static void main(String[] args) {
SpringApplication.run(ReggieApplication.class);
log.info("项目启动成功...");
}
}
2.新建filter包,登陆检查过滤器类 LoginCheckFilter类
3.编写过滤器代码
package cn.pjh.reggie.filter;
import cn.pjh.reggie.common.R;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.AntPathMatcher;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 检查用户是否完成登陆过滤器
*/
@Slf4j
@WebFilter(filterName = "LoginCheckFilter",urlPatterns = "/*")
public class LoginCheckFilter implements Filter {
//路由地址匹配器,用于检查是否包含我们设置的不需要过滤的路由
public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
//1.获取本次请求的uri
String requestURI = request.getRequestURI();
//定义不需要处理的url
String[] urls = new String[]{
"/employee/login",
"/employee/logout",
"/backend/**",
"/front/**"
};
//2.判断本次请求是否需要处理
boolean check = check(urls, requestURI);
//3.如果不需要处理,直接放行
if (check) {
filterChain.doFilter(request, response);
return;
}
//4.判断登陆状态,如果已经登陆,则直接放行
if (request.getSession().getAttribute("employee") != null) {
filterChain.doFilter(request, response);
return;
}
//5.如果未登陆,通过输出流方式向客户端页面响应数据,路由跳转是前端设置拦截器通过后端返回固
//定的值前端拿到之后,在进行判断,最后进行页面跳转到
response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));
}
//路由地址匹配器检查是否包含我们设置的不需要过滤的路由
/**
*
* @param urls 不需要过滤的路由
* @param requestUrl 本次请求的路由地址
* @return
*/
public boolean check(String[] urls, String requestUrl) {
for (String url : urls) {
if (PATH_MATCHER.match(url, requestUrl)) {
return true;
}
}
return false;
}
}
返回值R是自定义的前后端交互的数据格式
package cn.pjh.reggie.common;
import lombok.Data;
import java.util.HashMap;
import java.util.Map;
@Data
public class R<T> {
private Integer code; //编码:1成功,0和其它数字为失败
private String msg; //错误信息
private T data; //数据
private Map map = new HashMap(); //动态数据
public static <T> R<T> success(T object) {
R<T> r = new R<T>();
r.data = object;
r.code = 1;
return r;
}
public static <T> R<T> error(String msg) {
R r = new R();
r.msg = msg;
r.code = 0;
return r;
}
public R<T> add(String key, Object value) {
this.map.put(key, value);
return this;
}
}