在球衣2.17

时间:2015-05-20 20:46:00

标签: java jax-rs cdi jersey-2.0

我有资源类

@Path("/rest")
public class DemoResourceController {
    @Inject
    DemoService demoService;

    @Path("/get/demo")
    @GET
    @Produces(APPLICATION_JSON)
    public Response getDemoLists() {
        List<String> demoList=demoService.getDemoList();
        return  Response.ok(demoList).build();
    }

我在帖子中尝试了答案   Dependency injection with Jersey 2.0

如果我使用

compile group: "org.glassfish.jersey.ext.cdi" , name: "jersey-cdi1x" , version: "2.17"
compile group: "org.glassfish.jersey.ext.cdi" ,name: "jersey-weld2-se" , version: "2.17"

在启动服务器时我得到了

org.jboss.weld.exceptions.IllegalArgumentException: WELD-001408: 
Unsatisfied dependencies for type demoService with qualifiers @Default
[BackedAnnotatedField] @Inject  DemoResourceController.demoService at injection point

如果我删除上面的依赖项,那么我得到

javax.servlet.ServletException: A MultiException has 3 exceptions.  They are:
1. org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no
   object available for injection at SystemInjecteeImpl(requiredType=DemoService,parent=DemoResourceController,qualifiers={},position=- 1,optional=false,self=false,unqualified=null,1952079126)**
2. java.lang.IllegalArgumentException: While attempting to resolve the dependencies of DemoResourceController errors were found
3. java.lang.IllegalStateException: Unable to perform operation: resolve on package.DemoResourceController

org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:421)

resourceconfig类是

public class ApplicationConfig extends ResourceConfig {

  public ApplicationConfig() {
    register(new ApplicationBinder());
    packages(..name of packages..);
  }

活页夹类是

public class ApplicationBinder extends AbstractBinder{
  @Override
  protected void configure() {
      bind(DemoService.class).to(DemoServiceImpl.class);
  }
 }

我在嵌入模式下使用tomcat并添加init参数

Context ctx = tomcat.addContext("/", new File("web-app").getAbsolutePath());
Wrapper wrapper = ctx.createWrapper();
wrapper.addInitParameter("javax.ws.rs.Application","xx.xx.ApplicationConfig");

如何在控制器中注入服务? 注入是单元测试的首选方式(当服务实现时,比如说demoServiceImpl正在调用另一个服务,比如XService),单元测试不应该依赖于Xservice,因此demoServiceImpl 我如何从测试中将服务的模拟注入控制器?

1 个答案:

答案 0 :(得分:2)

在您的第二次尝试中(没有cdi依赖项;使用HK2)您的绑定不正确。它应该是

bind(Implementation).to(Contract)
// - i.e.
bind(DemoServiceImpl.class).to(DemoService.class);

你反过来了。

就测试而言,如果您在相同的包中进行测试(在项目的测试区域中),您应该能够分配服务,因为它是私有的包。虽然个人而言,我已经养成了构造函数注入的习惯。您可以做的另一件事是使用Jersey Test Framework。您可以看到一个完整的示例here,其中注入了模拟服务