Mic*_*eds 4 rest hibernate dropwizard
我想我对这里的问题有一个很好的了解,但我绝对不知道如何解决它...
以下是我在dropwizard中启动应用程序的方法:
@Override
public void run(ServerConfiguration configuration, Environment environment)
{
// Setting up the database.
final DBIFactory factory = new DBIFactory();
final DBI jdbi = factory.build(environment, configuration.getDataSourceFactory(), "mysql");
//Hibernate
final UserDAO dao = new UserDAO(hibernate.getSessionFactory());
environment.jersey().register(new UserResource(dao));
final TemplateHealthCheck healthCheck = new TemplateHealthCheck(configuration.getTemplate());
environment.healthChecks().register("template", healthCheck);
// security
//****** Dropwizard security - custom classes ***********/
environment.jersey().register(new AuthDynamicFeature(new BasicCredentialAuthFilter.Builder<User>()
.setAuthenticator(new BasicAuth(dao))
.setAuthorizer(new BasicAuthorizer())
.setRealm("BASIC-AUTH-REALM")
.buildAuthFilter()));
environment.jersey().register(RolesAllowedDynamicFeature.class);
environment.jersey().register(new AuthValueFactoryProvider.Binder<>(User.class));
}
Run Code Online (Sandbox Code Playgroud)
现在,正如你在这里看到的那样,我将我的用户dao传递给我的身份验证器......我在网上看到的没有教程就是这样,这是因为每个在线教程都使用硬编码值而不是显示如何查询数据库.
也就是说,这就是我试图验证的方式......
public class BasicAuth implements Authenticator<BasicCredentials, User> {
UserDAO _userDAO;
final Encryption enc = new Encryption();
public BasicAuth(UserDAO dao)
{
this._userDAO = dao;
}
@Override
public Optional<User> authenticate(BasicCredentials credentials)
throws AuthenticationException {
// Get the user record.
User requestedUser = _userDAO.findOneByUsername(credentials.getUsername());
if (requestedUser != null)
{
// check pw.
if(enc.compare(credentials.getPassword(), requestedUser.getPassword())) {
return Optional.of(requestedUser);
}
else {
return Optional.empty();
}
}
return Optional.empty();
}
}
Run Code Online (Sandbox Code Playgroud)
请原谅上面那个可怕的缩进,我把我的代码从intelliJ粘贴到这里并且表现不佳 - 无论如何,当我尝试运行这个应用程序时,验证者告诉我:
No session currently bound to execution context
Run Code Online (Sandbox Code Playgroud)
这是踢球者,我知道这只是为了安全方面我得到了这个错误,因为如果我从Application类中删除安全线并运行它,我仍然可以点击我的创建用户端点(也使用这个DAO),效果很好.
所以我的问题真的是 - 我是不是想在验证器中使用那个dao?如果没有,我该怎么想查询数据库?
如果我,那我在哪里错了?
提前致谢.
首先,你的问题:
从DW文档:
目前,使用@UnitOfWork注释创建事务仅对Jersey管理的资源开箱即用.如果您想在Jersey资源之外使用它,例如在身份验证器中,您应该使用UnitOfWorkAwareProxyFactory实例化您的类.
使用您的代码,您可以创建一个Authenticator但是您永远不会将其挂钩回Hibernate会话.如何Authenticator知道何时开启新会话以DAO进行操作?这是由UnitOfWork机制完成的.但是,这仅适用于Jersey资源,需要为任何其他想要参与此类的人启用.
所以,幸运的是Docs Authenticator在这里给出了一个确切的例子:http:
//www.dropwizard.io/1.0.6/docs/manual/hibernate.html
我不打算复制他们的代码,因为我有一个独立的例子供你玩:
public class HibernateTest extends io.dropwizard.Application<DBConfiguration> {
private final HibernateBundle<DBConfiguration> hibernate = new HibernateBundle<DBConfiguration>(Object.class) {
@Override
public DataSourceFactory getDataSourceFactory(DBConfiguration configuration) {
return configuration.getDataSourceFactory();
}
};
@Override
public void initialize(Bootstrap<DBConfiguration> bootstrap) {
super.initialize(bootstrap);
bootstrap.addBundle(hibernate);
}
@Override
public void run(DBConfiguration configuration, Environment environment) throws Exception {
MyDao dao = new MyDao(hibernate.getSessionFactory());
environment.jersey().register(new MyHelloResource(dao));
// THIS IS ABSOLUTELY CRITICAL
MyAuthenticator proxyAuth = new UnitOfWorkAwareProxyFactory(hibernate).create(MyAuthenticator.class, MyDao.class, dao);
AuthDynamicFeature authDynamicFeature = new AuthDynamicFeature(
new BasicCredentialAuthFilter.Builder<Principal>()
.setAuthenticator(proxyAuth)
.setRealm("SUPER SECRET STUFF")
.buildAuthFilter());
environment.jersey().register(authDynamicFeature);
}
public static void main(String[] args) throws Exception {
new HibernateTest().run("server", "/home/artur/dev/repo/sandbox/src/main/resources/config/db.yaml");
}
@Path("test")
@Produces(MediaType.APPLICATION_JSON)
public static class MyHelloResource {
private MyDao dao;
public MyHelloResource(MyDao dao) {
this.dao = dao;
}
@GET
@Path("/test")
@UnitOfWork
@PermitAll
public Response downloadFile() throws Exception {
dao.get();
return Response.ok().build();
}
}
public static class MyAuthenticator implements Authenticator<BasicCredentials, Principal> {
private MyDao dao;
MyAuthenticator(MyDao dao) {
this.dao = dao;
}
@Override
@UnitOfWork
public Optional<Principal> authenticate(BasicCredentials credentials) throws AuthenticationException {
dao.get();
return Optional.empty();
}
}
public static class MyDao extends AbstractDAO<Object> {
public MyDao(SessionFactory sessionFactory) {
super(sessionFactory);
}
public Object get() {
// if not bridged to Jersey this will throw an exception due to session
currentSession().createSQLQuery("SELECT 1;").uniqueResult();
return new Object();
}
}
}
Run Code Online (Sandbox Code Playgroud)
上面的代码运行一个最小的DW应用程序,在内存中设置了h2 db.您必须应用配置更改才能启动(并更改服务器配置文件)
这样做是:
DataSourceFactoryDAOAuthenticator代理重要的是:
MyAuthenticator proxyAuth = new UnitOfWorkAwareProxyFactory(hibernate).create(MyAuthenticator.class, MyDao.class, dao);
Run Code Online (Sandbox Code Playgroud)
这为您创建了一个知道UnitOfWork注释的代理.它允许Authenticator挂钩(我相信)事件系统,它将根据请求打开和关闭会话.
然后在您的代理中使用该代理 AuthDynamicFeature
最后,在您Authenticator执行身份验证时必须告诉它打开一个新的Session,例如:
@Override
@UnitOfWork
public Optional<Principal> authenticate(BasicCredentials credentials) throws AuthenticationException {
dao.get();
return Optional.empty();
}
Run Code Online (Sandbox Code Playgroud)
现在所有这些都可以正常运行:
curl user:pass@localhost:9085/api/test/test
Credentials are required to access this resource.
Run Code Online (Sandbox Code Playgroud)
至于你的上一个问题:
我实际上对春天更流利你认为转换而不是经常处理它是个好主意吗?
我认为这主要是基于意见的,但是:Spring DI!= Jersey DI.你基本上是做春天同样的事情,你弥合Jersey DI与Spring DI这样jersey可以访问这些豆子Spring.但是,所有session逻辑仍然以相同的方式处理.Spring简单地将显式抽象带走了 - 它在创建bean时已经为你创建了代理.所以我认为你不会有很多优势,而且从个人经验来看,连接Spring和Jersey并不是那么容易.dependency(spring-jersey-bridge)jersey广告不适用于嵌入式Jetties(例如DW设置),而是通过在启动时挂钩到Servlet(您没有).这仍然可以工作,但需要一些黑客才能获得该设置.根据我的经验,guice(例如https://github.com/xvik/dropwizard-guicey)在DW中更容易和更好地集成,并将为您提供相同的优势.Guice显然没有完成Spring所做的所有事情(也没有Spring完成所有的事情Guice)所以你可能需要做自己的研究.
我希望这可以解决问题并让你开始:)
问候,
阿图尔
| 归档时间: |
|
| 查看次数: |
2959 次 |
| 最近记录: |