当前位置: 首页 > 知识库问答 >
问题:

包含数据库信息的自定义筛选器删除向导

卢出野
2023-03-14

我正在使用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.最终]

共有3个答案

蒲昊苍
2023-03-14

也许你可以试试:

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,可能会满足您的需求。

洪安顺
2023-03-14

我自己也遇到了这个问题,我想我的问题是在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();

这是否是最好的解决方案是有争议的,但对我来说,这已经足够了。

麹承
2023-03-14

要在代码的非托管部分启用 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。在尝试实现此功能的几天后,不会加载,因此不会筛选任何请求。请帮帮忙。

  • 我有一个扩展类的类,它看起来像: 问题是,我可以向添加自定义吗?我浏览了和中可用的所有方法,但没有找到任何方法。但是在模式下,我发现在中有的列表。如何在此添加自定义?