1、Filter 接口主要有3个方法需要实现 ( init、doFilter、destroy )
/*初始化方法 接收一个FilterConfig类型的参数 该参数是对Filter的一些配置*/
public void init(FilterConfig config) throws ServletException { }
/*过滤方法 主要是对request和response进行一些处理,然后交给下一个过滤器或Servlet处理*/
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
chain.doFilter(req, resp);//交给下一个过滤器或servlet处理
}
/*销毁时调用*/
public void destroy() {}
配置过滤器,如图
我写的配置文件
参考程序
package com.ppmall.filter;
import com.ppmall.common.Const;
import com.ppmall.common.ResponseCode;
import com.ppmall.common.ServerResponse;
import com.ppmall.pojo.User;
import com.ppmall.service.IUserService;
import com.ppmall.service.impl.UserServiceImpl;
import com.ppmall.util.JsonUtil;
import com.ppmall.util.TokenUtil;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.InvalidClaimException;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
public class UserSecurityFilter implements Filter {
private IUserService iUserService;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
this.iUserService = new UserServiceImpl();
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//类型强制转换
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
/**
* 设置返回格式
*/
httpServletResponse.setCharacterEncoding("UTF-8");
httpServletResponse.setContentType("application/json; charset=utf-8");
// 从请求中得到httpSession
HttpSession httpSession = httpServletRequest.getSession();
//从请求中得到url
String requestUrl = httpServletRequest.getRequestURI();
String resultString = ServerResponse.createErrorStatus(ResponseCode.NOT_LOGIN).toString(); // resultString 此处为 {"status":10,"msg":"NOT_LOGIN"}
String token = httpServletRequest.getHeader("Authentication"); // 未登录为 null,登录后也为null
User currentUser = (User) httpSession.getAttribute(Const.CURRENT_USER); // 未登录为null,登录后不为空,Const.CURRENT_USER为字符串 ,IDEA显示灰色只是写法的问题
// 本程序此处token废了
if(token != null){
try {
Claims claims = TokenUtil.parseToken(token);
currentUser = JsonUtil.jsonStringToObject(JsonUtil.objectToJsonString(claims.get(Const.CURRENT_USER)), User.class);
httpSession.setAttribute(Const.CURRENT_USER, currentUser);
} catch (ExpiredJwtException e) {
httpSession.removeAttribute(Const.CURRENT_USER);
resultString = ServerResponse.createErrorStatus(ResponseCode.TOKEN_EXPIRED.getCode(), "token已过期").toString();
} catch (InvalidClaimException e) {
httpSession.removeAttribute(Const.CURRENT_USER);
resultString = ServerResponse.createErrorStatus(ResponseCode.TOKEN_INVALID.getCode(), "token不合法").toString();
} catch (Exception e) {
httpSession.removeAttribute(Const.CURRENT_USER);
e.printStackTrace();
resultString = ServerResponse.createErrorStatus(ResponseCode.TOKEN_ERROR.getCode(), "token错误").toString();
}
}
currentUser = (User) httpSession.getAttribute(Const.CURRENT_USER);
/**
* 包含login为登陆url不过滤,不包含login,register將进入以下
* 存在login.do,register.do...等任意一个,不进入第一个if
* 比如想访问 http://localhost:8080/dist/view/order-list.html地址,将requestUrl输出 按照顺序命令行打印出 /user/get_user_info.do 、/cart/get_cart_product_count.do 、/order/list.do
* 不是很理解,但是应该存在ajax异步请求的问题
*/
if (!requestUrl.contains("login.do")
&& !requestUrl.contains("register.do")
&& !requestUrl.contains("alipay_callback.do")
&& !requestUrl.contains("check_valid.do")
&& !requestUrl.contains("kill")
&& !requestUrl.contains("product/list.do")
&& !requestUrl.contains("product/detail.do")
&& !requestUrl.contains("category")
&& !requestUrl.contains("index")) {
// 不放行的请求,检验用户是否存在
if (currentUser == null) {
httpServletResponse.getWriter().print(resultString);
} else {
/**
* 已经登陆,转发请求
*/
filterChain.doFilter(httpServletRequest, httpServletResponse);
}
//被放行的继续判定是否是访问 manage,不是直接放行,是的话检验权限
} else if (requestUrl.contains("manage") && currentUser != null) {
/**
* 如果url包含manage即为后台管理,需要验证管理员权限
*/
ServerResponse responseUser = iUserService.checkAdmin(currentUser);
if (!responseUser.isSuccess()) {
resultString = ServerResponse.createErrorMessage("需要管理员权限").toString();
httpServletResponse.getWriter().print(resultString); //不放行,向前端输出权限不够的提示,doFilter结束
} else {
filterChain.doFilter(httpServletRequest, httpServletResponse);
}
} else {
filterChain.doFilter(httpServletRequest, httpServletResponse);
}
}
@Override
public void destroy() {
}
}
参考文档: