我正在使用dropwizard 0.7.0,我想创建一个自定义过滤器。
自定义筛选器应检查数据库中是否存在令牌。创建筛选器并在应用程序类中注册此筛选器的正确方法是什么?
我用这个问题来实现过滤器,这是有效的,但当我将代码更改为:
final AuthenticationDAO authenticationDAO = new AuthenticationDAO(hibernateBundle.getSessionFactory());
environment.servlets().addFilter("authenticationFilter", new AuthenticationFilter(authenticationDAO)).addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), false, "/transaction/*");
这是我的过滤器:
public class AuthenticationFilter implements Filter {
private final AuthenticationDAO authenticationDAO;
public AuthenticationFilter(AuthenticationDAO authenticationDAO) {
this.authenticationDAO = authenticationDAO;
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
String authenticationToken = ((Request) servletRequest).getHeader(Constants.HEADER_TOKEN_PARAM_NAME);
HttpServletResponse response = (HttpServletResponse)servletResponse;
if(Strings.isNullOrEmpty(authenticationToken)){
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
} else if(!authenticationDAO.findByAuthenticationToken(authenticationToken).isPresent()){
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
} else {
filterChain.doFilter(servletRequest, servletResponse);
}
}
@Override
public void destroy() {
}
}
当访问过滤器时,我得到以下错误,因为没有活动会话:
警告 [2014-04-22 14:37:42,733] 组织日食.码头.servlet.伺服员处理程序: /测试/显示 !Hibernate异常:当前没有会话绑定到执行上下文!在 org.Hibernate.上下文.内部.托管会话.当前会话(托管会话上下文.java:75) ~[Hibernate-核心-4.3.1.最终.jar:4.3.1.最终] !在组织.Hibernate.内部.会话工厂简化.getCurrentSession(会话工厂简化.java:1013) ~[Hibernate核心-4.3.1.最终.jar:4.3.1.最终]
也许你可以试试:
import com.google.common.base.Strings;
import com.sun.jersey.spi.container.ContainerRequest;
import com.sun.jersey.spi.container.ContainerRequestFilter;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
public class AuthenticationFilter implements ContainerRequestFilter {
private final AuthenticationDAO authenticationDAO;
public AuthenticationFilter(AuthenticationDAO authenticationDAO) {
this.authenticationDAO = authenticationDAO;
}
@Override
public ContainerRequest filter(final ContainerRequest containerRequest) {
String authenticationToken = containerRequest.getHeaderValue(Constants.HEADER_TOKEN_PARAM_NAME);
if (Strings.isNullOrEmpty(authenticationToken)) {
throw new WebApplicationException(Response.status(Response.Status.UNAUTHORIZED).build());
} else if (!authenticationDAO.findByAuthenticationToken(authenticationToken).isPresent()) {
throw new WebApplicationException(Response.status(Response.Status.FORBIDDEN).build());
}
return containerRequest;
}
}
在run-method中,您可以添加:
environment.jersey().getResourceConfig().getContainerRequestFilters().add(new AuthenticationFilter(...));
此拉取请求 https://github.com/dropwizard/dropwizard/pull/541,可能会满足您的需求。
我自己也遇到了这个问题,我想我的问题是在Dropwizard线程中讨论的:https://groups.google.com/forum/#!msg/dropwizard-user/LE6FYIpSDQ0/X5smCEZWltcJ
简而言之,您可能需要打开并绑定自己的会话——我的由Dropwizard管理的类可以很好地使用会话,但是不由dropwizard管理的类会遇到这个错误。
我正在尝试在打开和绑定我自己的会话之间做出决定,并将类移动到由Dropwizard管理的类,以便我可以使用@UnitOfWork注释。
此外,如果您不在@UnitOfWork中(这似乎只对rest调用有效),那么您可以使用会话,但不能使用DAO层。如果使用DAO,则会出现错误。可能还有更多,但出于我的目的,我只使用了一个SQLQuery:
SQLQuery deleteQuery = session.createSQLQuery("DELETE FROM MYTABLE WHERE REPORTTIME < ?");
deleteQuery.setTimestamp(0, cutoffDate.toDate());
deleteQuery.executeUpdate();
这是否是最好的解决方案是有争议的,但对我来说,这已经足够了。
要在代码的非托管部分启用 DropWizard“魔术”(Hibernate),您必须注入会话工厂。您可以看到如何在“拖放向导”配置中创建一个:
https://dropwizard.github.io/dropwizard/manual/hibernate.html
然后,您可以将该sessionFacotry注入到构造函数中的AuthenticationFilter中。
在过滤器中,您必须手动绑定hibernate会话,如下所示:
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
String authenticationToken = ((Request) servletRequest).getHeader(Constants.HEADER_TOKEN_PARAM_NAME);
Session session = sessionFactory.openSession();
session.setDefaultReadOnly(true);
session.setCacheMode(CacheMode.NORMAL);
session.setFlushMode(FlushMode.MANUAL);
ManagedSessionContext.bind(session);
// DropWizard magic enabled from this point.
HttpServletResponse response = (HttpServletResponse)servletResponse;
if(Strings.isNullOrEmpty(authenticationToken)){
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
} else if(!authenticationDAO.findByAuthenticationToken(authenticationToken).isPresent()){
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
} else {
filterChain.doFilter(servletRequest, servletResponse);
}
session.close();
// DropWizard magic disabled from this point.
}
这是本质。bind()和close()之间发生的任何事情都会启用DropWizard魔法——在托管Dao中也是如此。您可以通过错误处理等使其更加健壮来改进它。
即使您遇到了示例中的托管资源,这也会起作用。发生的情况是DropWizards RequestDispatcher激活并执行与您相同的操作:它打开一个会话并将其绑定到线程。其结果是,托管资源使用的会话与手动打开的会话不同,并且原始绑定的会话将在不进行清理的情况下删除。在您的示例中,这样做的效果是,在调用doFilter(…)之后,魔术结束了。如果希望以后访问数据库,则必须重新绑定之前创建的会话。只需致电:
ManagedSessionContext.bind(session);
我没有遇到过任何关于这项技术的问题,但我可以想象的一个问题是,如果你需要访问在另一个会话中进行的一个会话中的数据。这可能需要对隔离级别进行一些调整。
我正在使用数据表和服务器端处理(Django)。 我有一个单独的textfield,在表已经呈现之后,我使用它自定义筛选DataTable中的数据。 以下操作很好(我想自定义筛选列): 所以在页面加载(DataTable的初始加载)时,它很好地过滤了'Robert'。但现在我想以编程方式更改数据以筛选 我已经尝试了以下操作,有一个正确的筛选对象,但是表本身并没有用新的筛选器重新绘制。 我也试过这个
存储在Django模型中的元素如下 示例数据如下: . 结果:找到对象- 结果:找到对象- 结果:找到对象- 结果:未找到对象 如何使用过滤器和正则表达式进行这些查询?
问题内容: 我正在寻找一种选择SQL服务器上所有数据库的方法,这些数据库仅包含表“ dbo.mytable” 我怎样才能做到这一点 ? 我已经有了这两个sql查询: 和 第一个查询列出我的sql服务器上的所有数据库,第二个查询检查dbo.mytable是否存在。我想将它们合并。 谢谢 问题答案: 一种将它们全部归还到一个结果集中的简洁方法是
我创建了一个自定义筛选器,用于获取令牌,然后用与令牌相关的角色填充身份验证对象 然后,我将该过滤器添加到springsecuritycontext中,如下所示: 应用程序已经存在,我只是尝试添加Spring Security层。Spring Security版本为4.2.3。在尝试实现此功能的几天后,不会加载,因此不会筛选任何请求。请帮帮忙。
我有一个扩展类的类,它看起来像: 问题是,我可以向添加自定义吗?我浏览了和中可用的所有方法,但没有找到任何方法。但是在模式下,我发现在中有的列表。如何在此添加自定义?