网上搜到的都是Filter,在此记录一下
Bug原因:web应用启动的顺序是:listener->filter->servlet
解决方法:使用context中的ApplicationContextAware解决
工具类
package cn.xxxx.common.utils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
* Spring Context 工具类
*/
@Component
public class SpringContextUtils implements ApplicationContextAware {
public static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
SpringContextUtils.applicationContext = applicationContext;
}
public static Object getBean(String name) {
return applicationContext.getBean(name);
}
public static <T> T getBean(Class<T> clazz){
return applicationContext.getBean(clazz);
}
public static <T> T getBean(String name, Class<T> requiredType) {
return applicationContext.getBean(name, requiredType);
}
public static boolean containsBean(String name) {
return applicationContext.containsBean(name);
}
public static boolean isSingleton(String name) {
return applicationContext.isSingleton(name);
}
public static Class<? extends Object> getType(String name) {
return applicationContext.getType(name);
}
}
实现:SpringContextUtils.getBean(XXXX.class);
import org.apache.shiro.util.CollectionUtils;
import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.RequestMethod;
import zztTrans.redissocket.RedisUtil;
import zztTrans.system.service.TransUserService;
import zztTrans.system.web.vo.TransUserQueryVo;
import zztTrans.util.shrio.TokenSubjectUtil;
import zztTrans.util.startuputil.SpringContextUtil;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Set;
public class RoleFilter extends BasicHttpAuthenticationFilter {
@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
System.out.println("isAccessAllowed");
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
System.out.println(httpServletRequest.getServletPath());
String token = httpServletRequest.getHeader("token");
String subject = TokenSubjectUtil.getSubject(token);
if (subject == null || "".equals(subject)) {
try {
response.setContentType("application/json;charset=utf-8");
response.getWriter().write("{\"code\":50005,\"message\":\"未登录\"}");
} catch (IOException e) {
e.printStackTrace();
}
}
boolean flat = false;
if (token != null) {
String[] rolesArray = (String[]) mappedValue;
//使用context手动注入
TransUserService transUserService = SpringContextUtil.getBean(TransUserService.class);
String userId= transUserService.getUserid(token);
if (rolesArray != null && rolesArray.length != 0) {
Set<String> roles = CollectionUtils.asSet(rolesArray);
for (String item : roles) {
TransUserQueryVo bean = transUserService.getTransUserQueryVo(userId, item);
if (bean!=null) {
flat = true;
//每次操作延长token的有效时间
RedisUtil.persist(token);
RedisUtil.expire(token, 604800);
}
}
}
}
return flat;
}
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
response.setContentType("application/json;charset=utf-8");
response.getWriter().write("{\"code\":50008,\"message\":\"未授权\"}");
return false;
}
/**
* 对跨域提供支持
*/
@Override
protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
httpServletResponse.setHeader("Access-control-Allow-Origin", httpServletRequest.getHeader("Origin"));
httpServletResponse.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,PUT,DELETE");
httpServletResponse.setHeader("Access-Control-Allow-Headers", httpServletRequest.getHeader("Access-Control-Request-Headers"));
// 跨域时会首先发送一个option请求,这里我们给option请求直接返回正常状态
if (httpServletRequest.getMethod().equals(RequestMethod.OPTIONS.name())) {
httpServletResponse.setStatus(HttpStatus.OK.value());
return false;
}
return super.preHandle(request, response);
}
}