1

我有一个简单的Dropwizard休息服务应用程序,它只有两层:控制器层(又名资源)和持久层(又名 dao)。Dropwizard 应用程序小巧简洁,运行顺畅。

但是,在一些需求发生变化之后,我需要添加一些业务逻辑来处理传入的 json 对象,然后将其持久化到数据库中。因此,我正在寻找在控制器和持久层之间添加此服务层的最佳方法。

您能否建议在应用程序中添加服务层的最佳方法。谢谢。

控制器(又名资源):

@Path("/person")
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public class PersonResource {

   private PersonService personService;

   public PersonResource(PersonService personService) {
        this.personService = personService;
    }


   @GET
    public List<Person> getAll(){
        return personService.getAll();
    }

   @GET
    @Path("/{id}")
    public Person findById(@PathParam("id") Integer id){
        return personService.findPersonById(id);
    }
}

服务层:

public class PersonService {

   private PersonDAO personDAO;

   public PersonService(PersonDAO personDAO) {
        this.personDAO = personDAO;
    }

   @UnitOfWork
    public List<Person> getAll(){
        return personDAO.getAll();
    }

   @UnitOfWork
    public Person findPersonById(Integer id){
        return personDAO.findById(id);
    }
}

应用类:

public class DemoApplication extends Application<DemoConfiguration> {

   public static void main(final String[] args) throws Exception {
        new DemoApplication().run(args);
    }

   private final HibernateBundle<DemoConfiguration> hibernateBundle = new HibernateBundle<DemoConfiguration>(Person.class) {
        @Override
        public DataSourceFactory getDataSourceFactory(DemoConfiguration configuration) {
            return configuration.getDatabaseAppDataSourceFactory();
        }
    };

   @Override
    public void initialize(final Bootstrap<DemoConfiguration> bootstrap) {
        bootstrap.addBundle(hibernateBundle);
    }

   @Override
    public void run(final DemoConfiguration configuration, final Environment environment) {
        final PersonDAO personDAO = new PersonDAO(hibernateBundle.getSessionFactory());
        final PersonService personResource = new PersonService(personDAO);
        environment.jersey().register(personResource);
    }
}

我可以成功启动应用程序,但是在处理请求时它会失败 404 错误代码。并在日志中看到此消息:

org.glassfish.jersey.internal.inject.Providers:在 SERVER 运行时注册的提供程序 com.laboratory.dropwizard.service.PersonService 不实现任何适用于 SERVER 运行时的提供程序接口。由于约束配置问题,提供者 com.laboratory.dropwizard.service.PersonService 将被忽略。

Dropwizard 有什么问题,如何引入工作服务层?谢谢。

4

2 回答 2

1

您收到错误(警告),因为您正在register尝试PersonService. 该register方法仅用于注册资源和已知的提供者类型。您可能想要做的是使用依赖注入。您要做的是将 DAO 和服务绑定到注入框架。然后你可以@Inject在需要的地方注入它们。

@Override
public void run(DemoConfiguration conf, Environment env) {
    env.jersey().register(new AbstractBinder() {
        @Override
        public void configure() {
            bindAsContract(PersonDAO.class).in(Singleton.class);
            bindAsContract(PersonService.class).in(Singleton.class);
        }
    });
}

现在您可以将 DAO 注入到服务中,将服务注入到资源中

public class PersonService {
    private PersonDAO dao;

    @Inject
    public PersonService(PersonDAO dao){
        this.dao = dao;
    }
}

@Path("people")
public class PersonResource {
    private PersonService service;

    @Inject
    public PersonResource(PersonService service) {
        this.service = service;
    }
}
于 2018-04-10T16:42:45.783 回答
0

从文档中

@UnitOfWork目前,使用注释创建事务仅适用于 Jersey 管理的资源。如果您想在 Jersey 资源之外使用它,例如在身份验证器中,您应该使用UnitOfWorkAwareProxyFactory.

说明这一点的代码示例是:

SessionDao dao = new SessionDao(hibernateBundle.getSessionFactory());
ExampleAuthenticator exampleAuthenticator = new UnitOfWorkAwareProxyFactory(hibernateBundle)
               .create(ExampleAuthenticator.class, SessionDao.class, dao);

沿着这条线尝试一些东西。

于 2018-04-10T13:52:47.687 回答