25 回复
这是要弄session持久化?
酱紫 定义了 然后 启动 报错
package io.nutz.nutzsite.common.starter;
import io.nutz.nutzsite.common.bean.OnlineSession;
import io.nutz.nutzsite.common.constant.ShiroConstants;
import io.nutz.nutzsite.common.shiro.session.OnlineSessionDAO;
import org.apache.shiro.web.filter.PathMatchingFilter;
import org.nutz.boot.starter.WebFilterFace;
import org.nutz.ioc.Ioc;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.util.EnumSet;
import java.util.Map;
/**
* 同步Session数据到Db
*
* @author haimming
*/
@IocBean
public class SyncOnlineSessionFilter extends PathMatchingFilter implements WebFilterFace {
@Inject("refer:$ioc")
protected Ioc ioc;
@Inject
private OnlineSessionDAO onlineSessionDAO;
@Override
public String getName() {
return "syncOnlineSession";
}
@Override
public String getPathSpec() {
return "/*";
}
/**
* 需要支持哪些请求方式
*
* @return 请求方式列表
*/
@Override
public EnumSet getDispatches() {
return EnumSet.of( DispatcherType.FORWARD,
DispatcherType.INCLUDE,
DispatcherType.REQUEST,
DispatcherType.ASYNC,
DispatcherType.ERROR);
}
@Override
public Filter getFilter() {
return ioc.get(SyncOnlineSessionFilter.class, "syncOnlineSessionFilter");
}
@Override
public Map getInitParameters() {
return null;
}
@Override
public int getOrder() {
return 0;
}
/**
* 同步会话数据到DB 一次请求最多同步一次 防止过多处理 需要放到Shiro过滤器之前
*/
@Override
protected boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
OnlineSession session = (OnlineSession) request.getAttribute(ShiroConstants.ONLINE_SESSION);
// 如果session stop了 也不同步
// session停止时间,如果stopTimestamp不为null,则代表已停止
if (session != null && session.getUserId() != null && session.getStopTimestamp() == null) {
onlineSessionDAO.syncToDb(session);
}
return true;
}
}
[DEBUG] 15:36:38.895 org.nutz.ioc.impl.ScopeContext.remove(ScopeContext.java:85) - Remove object 'syncOnlineSessionFilter' from [app]
[WARN ] 15:36:38.895 org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:554) - Failed startup of context o.e.j.w.WebAppContext@2489e84a{/,[file:///Users/apple/IdeaProjects/ns/src/main/resources/static/, file:///Users/apple/IdeaProjects/ns/target/classes/static/, jar:file:/Users/apple/.m2/repository/org/nutz/nutzboot-starter-swagger/2.3.4.v20190410/nutzboot-starter-swagger-2.3.4.v20190410.jar!/static/],UNAVAILABLE}
org.nutz.ioc.IocException: IocBean[syncOnlineSessionFilter] throw Exception when creating
at org.nutz.ioc.impl.ObjectMakerImpl.make(ObjectMakerImpl.java:153)
at org.nutz.ioc.impl.NutIoc.get(NutIoc.java:241)
at org.nutz.ioc.impl.NutIoc.get(NutIoc.java:271)
at org.nutz.boot.AppContext.getBeans(AppContext.java:334)
at org.nutz.boot.starter.servlet3.NbServletContextListener.contextInitialized(NbServletContextListener.java:116)
at org.eclipse.jetty.server.handler.ContextHandler.callContextInitialized(ContextHandler.java:957)
at org.eclipse.jetty.servlet.ServletContextHandler.callContextInitialized(ServletContextHandler.java:553)
at org.eclipse.jetty.server.handler.ContextHandler.startContext(ContextHandler.java:922)
at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:365)
at org.eclipse.jetty.webapp.WebAppContext.startWebapp(WebAppContext.java:1497)
at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1459)
at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:852)
at org.eclipse.jetty.servlet.ServletContextHandler.doStart(ServletContextHandler.java:278)
at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:545)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:138)
at org.eclipse.jetty.server.Server.start(Server.java:415)
at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:108)
at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:113)
at org.eclipse.jetty.server.Server.doStart(Server.java:382)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.nutz.boot.starter.jetty.JettyStarter.start(JettyStarter.java:137)
at org.nutz.boot.AppContext.startServers(AppContext.java:310)
at org.nutz.boot.NbApp.execute(NbApp.java:210)
at org.nutz.boot.NbApp.run(NbApp.java:182)
at io.nutz.nutzsite.MainLauncher.main(MainLauncher.java:66)
Caused by: java.lang.RuntimeException: IocBean[syncOnlineSessionFilter] fail at field=[onlineSessionDAO]
at org.nutz.ioc.weaver.FieldInjector.inject(FieldInjector.java:40)
at org.nutz.ioc.weaver.DefaultWeaver.fill(DefaultWeaver.java:67)
at org.nutz.ioc.impl.ObjectMakerImpl.make(ObjectMakerImpl.java:138)
... 25 more
Caused by: org.nutz.ioc.IocException: IocBean[onlineSessionDAO] throw Exception when creating
at org.nutz.ioc.impl.ObjectMakerImpl.make(ObjectMakerImpl.java:153)
at org.nutz.ioc.impl.NutIoc.get(NutIoc.java:241)
at org.nutz.ioc.val.ReferTypeValue.get(ReferTypeValue.java:60)
at org.nutz.ioc.weaver.FieldInjector.inject(FieldInjector.java:32)
... 27 more
Caused by: java.lang.RuntimeException: IocBean[onlineSessionDAO] fail at field=[onlineSessionFactory]
at org.nutz.ioc.weaver.FieldInjector.inject(FieldInjector.java:40)
at org.nutz.ioc.weaver.DefaultWeaver.fill(DefaultWeaver.java:67)
at org.nutz.ioc.impl.ObjectMakerImpl.make(ObjectMakerImpl.java:138)
... 30 more
Caused by: org.nutz.ioc.IocException: IocBean[class:io.nutz.nutzsite.common.shiro.session.OnlineSessionFactory] none ioc bean match class=io.nutz.nutzsite.common.shiro.session.OnlineSessionFactory
at org.nutz.ioc.impl.NutIoc.getByType(NutIoc.java:461)
at org.nutz.ioc.val.ReferTypeValue.get(ReferTypeValue.java:66)
at org.nutz.ioc.weaver.FieldInjector.inject(FieldInjector.java:32)
... 32 more
[INFO ] 15:36:38.932 org.eclipse.jetty.server.AbstractConnector.doStart(AbstractConnector.java:292) - Started ServerConnector@7de15553{HTTP/1.1,[http/1.1]}{127.0.0.1:8090}
[INFO ] 15:36:38.932 org.eclipse.jetty.server.Server.doStart(Server.java:407) - Started @3700ms
不是 是参考 这个项目https://gitee.com/y_project/RuoYi
前端 做一个 nutz版本
none ioc bean match class=io.nutz.nutzsite.common.shiro.session.OnlineSessionFactory
MainLauncher在哪个package?
OnlineSessionFactory 没加iocbean吧
恩 果然是
现在错误变成这样
启动成功 没有执行方法onPreHandle
package io.nutz.nutzsite.common.starter;
import io.nutz.nutzsite.common.bean.OnlineSession;
import io.nutz.nutzsite.common.constant.ShiroConstants;
import io.nutz.nutzsite.common.shiro.session.OnlineSessionDAO;
import org.apache.shiro.web.filter.PathMatchingFilter;
import org.nutz.boot.starter.WebFilterFace;
import org.nutz.ioc.Ioc;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
/**
* 同步Session数据到Db
*
* @author haimming
*/
@IocBean(name = "syncOnlineSession")
public class SyncOnlineSessionFilter extends PathMatchingFilter implements WebFilterFace {
@Inject("refer:$ioc")
protected Ioc ioc;
@Inject
private OnlineSessionDAO onlineSessionDAO;
@Override
public String getName() {
return "syncOnlineSession";
}
@Override
public String getPathSpec() {
return "/*";
}
/**
* 需要支持哪些请求方式
*
* @return 请求方式列表
*/
@Override
public EnumSet getDispatches() {
return EnumSet.of( DispatcherType.FORWARD,
DispatcherType.INCLUDE,
DispatcherType.REQUEST,
DispatcherType.ASYNC,
DispatcherType.ERROR);
}
@Override
public Filter getFilter() {
return ioc.get(SyncOnlineSessionFilter.class, "syncOnlineSession");
}
@Override
public Map getInitParameters() {
return new HashMap();
}
@Override
public int getOrder() {
return 0;
}
/**
* 同步会话数据到DB 一次请求最多同步一次 防止过多处理 需要放到Shiro过滤器之前
*/
@Override
protected boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
OnlineSession session = (OnlineSession) request.getAttribute(ShiroConstants.ONLINE_SESSION);
// 如果session stop了 也不同步
// session停止时间,如果stopTimestamp不为null,则代表已停止
if (session != null && session.getUserId() != null && session.getStopTimestamp() == null) {
onlineSessionDAO.syncToDb(session);
}
return true;
}
}
为啥没有执行方法呢莫非是WebFilterFace不对
getFilter应该return this
至于为啥没有执行
要么order不对,没放在shiro之前
要么超类的逻辑问题,因为Filter接口就一个方法,你覆盖的是超类的方法,并非Filter的方法, web容器并不会直接调用到
定义 filter
package io.nutz.nutzsite.common.starter;
import io.nutz.nutzsite.common.filter.OnlineSessionFilter;
import org.nutz.boot.starter.WebFilterFace;
import org.nutz.ioc.loader.annotation.IocBean;
import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
/**
* 同步Session数据到Db
*
* @author haimming
*/
@IocBean
public class SyncOnlineSessionFilter implements WebFilterFace {
@Override
public String getName() {
return "syncOnlineSession";
}
@Override
public String getPathSpec() {
return "/*";
}
/**
* 需要支持哪些请求方式
*
* @return 请求方式列表
*/
@Override
public EnumSet getDispatches() {
return EnumSet.of( DispatcherType.FORWARD,
DispatcherType.INCLUDE,
DispatcherType.REQUEST,
DispatcherType.ASYNC,
DispatcherType.ERROR);
}
@Override
public Filter getFilter() {
return new OnlineSessionFilter();
}
@Override
public Map getInitParameters() {
return new HashMap();
}
@Override
public int getOrder() {
return 0;
}
}
调用
package io.nutz.nutzsite.common.filter;
import io.nutz.nutzsite.common.bean.OnlineSession;
import io.nutz.nutzsite.common.constant.ShiroConstants;
import io.nutz.nutzsite.common.shiro.session.OnlineSessionDAO;
import org.apache.shiro.web.filter.PathMatchingFilter;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.mvc.ActionContext;
import org.nutz.mvc.ActionFilter;
import org.nutz.mvc.View;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
/**
* @Author: Haimming
* @Date: 2019-04-19 09:38
* @Version 1.0
*/
public class OnlineSessionFilter extends PathMatchingFilter implements ActionFilter {
@Inject
private OnlineSessionDAO onlineSessionDAO;
@Override
public View match(ActionContext actionContext) {
try {
this.onPreHandle(actionContext.getRequest(),actionContext.getResponse(),actionContext.getMethodArgs());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 同步会话数据到DB 一次请求最多同步一次 防止过多处理 需要放到Shiro过滤器之前
*/
@Override
protected boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
OnlineSession session = (OnlineSession) request.getAttribute(ShiroConstants.ONLINE_SESSION);
// 如果session stop了 也不同步
// session停止时间,如果stopTimestamp不为null,则代表已停止
if (session != null && session.getUserId() != null && session.getStopTimestamp() == null) {
onlineSessionDAO.syncToDb(session);
}
return true;
}
}
还是没有执行
WebFilterFace只能保证调用到Filter的doFilter方法, 其他方法是Filter实现类的事.
WebFilterFace的作用等同于web.xml里面声明个和
PS: 跟ActionFilter一点关系没有,实现ActionFilter没一点意义.
打断点 也没有执行 doFilter方法
package io.nutz.nutzsite.common.starter;
import io.nutz.nutzsite.common.bean.OnlineSession;
import io.nutz.nutzsite.common.constant.ShiroConstants;
import io.nutz.nutzsite.common.shiro.session.OnlineSessionDAO;
import org.apache.shiro.web.filter.PathMatchingFilter;
import org.nutz.boot.starter.WebFilterFace;
import org.nutz.ioc.Ioc;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
/**
* 同步Session数据到Db
*
* @author haimming
*/
@IocBean
public class SyncOnlineSessionFilter extends PathMatchingFilter implements WebFilterFace {
@Inject("refer:$ioc")
protected Ioc ioc;
@Inject
private OnlineSessionDAO onlineSessionDAO;
@Override
public String getName() {
return "syncOnlineSession";
}
@Override
public String getPathSpec() {
return "/*";
}
/**
* 需要支持哪些请求方式
*
* @return 请求方式列表
*/
@Override
public EnumSet getDispatches() {
return EnumSet.of( DispatcherType.FORWARD,
DispatcherType.INCLUDE,
DispatcherType.REQUEST,
DispatcherType.ASYNC,
DispatcherType.ERROR);
}
@Override
public Filter getFilter() {
return this;
}
@Override
public Map getInitParameters() {
return new HashMap();
}
@Override
public int getOrder() {
return 0;
}
/**
* 同步会话数据到DB 一次请求最多同步一次 防止过多处理 需要放到Shiro过滤器之前
*/
@Override
protected boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
OnlineSession session = (OnlineSession) request.getAttribute(ShiroConstants.ONLINE_SESSION);
// 如果session stop了 也不同步
// session停止时间,如果stopTimestamp不为null,则代表已停止
if (session != null && session.getUserId() != null && session.getStopTimestamp() == null) {
onlineSessionDAO.syncToDb(session);
}
return true;
}
public void doFilter(){
System.out.println(1);
}
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)
throws IOException, ServletException;
Error:(84, 23) java: io.nutz.nutzsite.common.starter.SyncOnlineSessionFilter中的doFilter(javax.servlet.ServletRequest,javax.servlet.ServletResponse,javax.servlet.FilterChain)无法覆盖org.apache.shiro.web.servlet.OncePerRequestFilter中的doFilter(javax.servlet.ServletRequest,javax.servlet.ServletResponse,javax.servlet.FilterChain)
被覆盖的方法为final
你写个无参数的doFilter,又怎么可能被调用
PS: getOrder返回的值会影响filter的先后顺序
应该会比shiro 先执行
@Override
public int getOrder() {
return 0;
}
spring 这样配置 nutzboot如何在启动 时设置ShiroFilterFactoryBean.setFilter呢
/**
* Shiro过滤器配置
*/
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager)
{
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
// Shiro的核心安全接口,这个属性是必须的
shiroFilterFactoryBean.setSecurityManager(securityManager);
// 身份认证失败,则跳转到登录页面的配置
shiroFilterFactoryBean.setLoginUrl(loginUrl);
// 权限认证失败,则跳转到指定页面
shiroFilterFactoryBean.setUnauthorizedUrl(unauthorizedUrl);
// Shiro连接约束配置,即过滤链的定义
LinkedHashMap filterChainDefinitionMap = new LinkedHashMap<>();
// 对静态资源设置匿名访问
filterChainDefinitionMap.put("/favicon.ico**", "anon");
filterChainDefinitionMap.put("/ruoyi.png**", "anon");
filterChainDefinitionMap.put("/css/**", "anon");
filterChainDefinitionMap.put("/docs/**", "anon");
filterChainDefinitionMap.put("/fonts/**", "anon");
filterChainDefinitionMap.put("/img/**", "anon");
filterChainDefinitionMap.put("/ajax/**", "anon");
filterChainDefinitionMap.put("/js/**", "anon");
filterChainDefinitionMap.put("/ruoyi/**", "anon");
filterChainDefinitionMap.put("/druid/**", "anon");
filterChainDefinitionMap.put("/captcha/captchaImage**", "anon");
// 退出 logout地址,shiro去清除session
filterChainDefinitionMap.put("/logout", "logout");
// 不需要拦截的访问
filterChainDefinitionMap.put("/login", "anon,captchaValidate");
// 系统权限列表
// filterChainDefinitionMap.putAll(SpringUtils.getBean(IMenuService.class).selectPermsAll());
Map filters = new LinkedHashMap<>();
filters.put("onlineSession", onlineSessionFilter());
filters.put("syncOnlineSession", syncOnlineSessionFilter());
filters.put("captchaValidate", captchaValidateFilter());
// 注销成功,则跳转到指定页面
filters.put("logout", logoutFilter());
shiroFilterFactoryBean.setFilters(filters);
// 所有请求需要认证
filterChainDefinitionMap.put("/**", "user,onlineSession,syncOnlineSession");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
/**
* 自定义在线用户处理过滤器
*/
@Bean
public OnlineSessionFilter onlineSessionFilter()
{
OnlineSessionFilter onlineSessionFilter = new OnlineSessionFilter();
onlineSessionFilter.setLoginUrl(loginUrl);
return onlineSessionFilter;
}
/**
* 自定义在线用户同步过滤器
*/
@Bean
public SyncOnlineSessionFilter syncOnlineSessionFilter()
{
SyncOnlineSessionFilter syncOnlineSessionFilter = new SyncOnlineSessionFilter();
return syncOnlineSessionFilter;
}
研究出来了
可以酱紫玩
所有请求都会执行syncOnlineSessionFilter过滤器
##shiro
shiro.objects = syncOnlineSessionFilter
shiro.url.login=/login
shiro.url.unauth=/login/unauth
shiro.ini.urls:
/static/** = anon
/login = anon
/sys/** = authc
/index = authc
/druid/** =authc
/swagger/** =authc
/** =syncOnlineSessionFilter