Bug原因:web应用启动的顺序是:listener->filter->servlet
解决方法:使用context中的ApplicationContextAware解决
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class SpringContextUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext = null;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if(SpringContextUtil.applicationContext == null){
SpringContextUtil.applicationContext = applicationContext;
}
}
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
public static Object getBean(String name){
return getApplicationContext().getBean(name);
}
public static <T> T getBean(Class<T> clazz){
return getApplicationContext().getBean(clazz);
}
public static <T> T getBean(String name,Class<T> clazz){
return getApplicationContext().getBean(name, clazz);
}
}
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);
}
}