在Jersey Rest应用程序中使用DI时出现错误:
org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=PricingService,parent=PricingResource,qualifiers={},position=0,optional=false,self=false,unqualified=null,1633188703)
我对这个概念很陌生,它似乎很复杂,因为有一些例子似乎被弃用了。据我所知,有几种方法可以使DI工作:原生HK2,Spring/ HK2桥。什么更容易配置,更直接?如何以编程方式(不是XML的粉丝)为泽西岛2.x设置?
资源配置
import org.glassfish.jersey.server.ResourceConfig;
public class ApplicationConfig extends ResourceConfig {
public ApplicationConfig() {
register(new ApplicationBinder());
packages(true, "api");
}
}
摘要确认器
public class ApplicationBinder extends AbstractBinder {
@Override
protected void configure() {
bind(PricingService.class).to(PricingService.class).in(Singleton.class);
}
}
定价资源
@Path("/prices")
public class PricingResource {
private final PricingService pricingService;
@Inject
public PricingResource(PricingService pricingService) {
this.pricingService = pricingService;
}
@GET
@Produces(MediaType.APPLICATION_JSON)
public Collection<Price> findPrices() {
return pricingService.findPrices();
}
}
定价服务
@Singleton
public class PricingService {
// no constructors...
// findPrices() ...
}
更新
public class Main {
public static final String BASE_URI = "http://localhost:8080/api/";
public static HttpServer startServer() {
return createHttpServerWith(new ResourceConfig().packages("api").register(JacksonFeature.class));
}
private static HttpServer createHttpServerWith(ResourceConfig rc) {
HttpServer httpServer = GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI), rc);
StaticHttpHandler staticHttpHandler = new StaticHttpHandler("src/main/webapp");
staticHttpHandler.setFileCacheEnabled(false);
staticHttpHandler.start();
httpServer.getServerConfiguration().addHttpHandler(staticHttpHandler);
return httpServer;
}
public static void main(String[] args) throws IOException {
System.setProperty("java.util.logging.config.file", "src/main/resources/logging.properties");
final HttpServer server = startServer();
System.out.println(String.format("Jersey app started with WADL available at "
+ "%sapplication.wadl\nHit enter to stop it...", BASE_URI));
server.start();
System.in.read();
server.stop();
}
}
更新3:
public class PricingResourceTest extends JerseyTest {
@Mock
private PricingService pricingServiceMock;
@Override
protected Application configure() {
MockitoAnnotations.initMocks(this);
enable(TestProperties.LOG_TRAFFIC);
enable(TestProperties.DUMP_ENTITY);
ResourceConfig config = new ResourceConfig(PricingResource.class);
config.register(new AbstractBinder() {
@Override
protected void configure() {
bind(pricingServiceMock).to(PricingService.class);
}
});
return config;
}
@Test
public void testFindPrices(){
when(pricingServiceMock.findPrices()).thenReturn(getMockedPrices());
Response response = target("/prices")
.request()
.get();
verify(pricingServiceMock).findPrices();
List<Price> prices = response.readEntity(new GenericType<List<Price>>(){});
// assertEquals("Should return status 200", 200, response.getStatus());
assertTrue(prices.get(0).getId() == getMockedPrices().get(0).getId());
}
private List<Price> getMockedPrices(){
List<Price> mockedPrices = Arrays.asList(new Price(1L, 12.0, 50.12, 12L));
return mockedPrices;
}
}
JUnit输出:
INFO: 1 * Client response received on thread main
1 < 200
1 < Content-Length: 4
1 < Content-Type: application/json
[{}]
java.lang.AssertionError
调试时:
价格.get(0)
是价格
对象, 已将空分配给
所有字段。
更新4:
添加到confiure()
:
config.register(JacksonFeature.class);
config.register(JacksonJsonProvider.class);
现在Junit输出稍微好了一点:
INFO: 1 * Client response received on thread main
1 < 200
1 < Content-Length: 149
1 < Content-Type: application/json
[{"id":2,"recurringPrice":122.0,"oneTimePrice":6550.12,"recurringCount":2},{"id":2,"recurringPrice":122.0,"oneTimePrice":6550.12,"recurringCount":2}]
实际上,标价
具有正确的价格数量,
但所有价格字段均为空。这导致假设问题可能是读取实体:
List<Price> prices = response.readEntity(new GenericType<List<Price>>(){});
将Moxy依赖项更改为:
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
</dependency>
并在“价格”对象上添加注释。
@XmlRootElement
@JsonIgnoreProperties(ignoreUnknown = true)
如果bean,也会出现相同的错误。xml丢失或放错位置。这帮助了我:豆子应该放在哪里。放置xml?
我通过向我的应用程序添加以下依赖项来解决这个问题。编译组:“org . glassfish . jersey . containers . glassfish”,名称:“jersey-gf-cdi”,版本:“2.14”
那么就不需要有任何“AbstractBinder”相关的代码。
忘记< code>InjectableProvider。你不需要它。问题是模拟服务不是被注入的服务。它是由DI框架创建的。因此,您正在检查模拟服务上的更改,它从未被触及过。
所以您需要做的是将mock与DI框架绑定在一起。您可以简单地创建另一个< code>AbstractBinder来进行测试。它可以是一个简单的匿名函数,您可以在其中绑定mock
ResourceConfig config = new ResourceConfig(PricingResource.class);
config.register(new AbstractBinder() {
@Override
protected void configure() {
bind(pricingServiceMock).to(PricingService.class);
}
});
在这里,您只是绑定了被模仿的服务。所以框架会将模拟注入资源。现在,当您在请求中修改它时,将在断言中看到更改
哦,您仍然需要执行when(..).then(..)
来初始化模拟服务中的数据。这也是你所缺少的
@Test
public void testFindPrices(){
Mockito.when(pricingServiceMock.findSomething()).thenReturn(list);
我有一个使用Jersey 2.x的简单REST API项目。我尝试使用GoogleGuice注入我的依赖项,但似乎不起作用。我得到这个错误: 组织.glassfish.hk2.api.不满意的依赖性例外:在系统导入过程中没有可用于注入的对象(必填类型=帐户服务,父=帐户资源,限定符={},位置=0,可选=假,自=假,非限定=空,1658198405) 我有这个简单的资源类 我想将此服务注入我的资源
我已经尝试了很多方法来解决这个问题,但都做不到。我发现,如果我们使用“abstractBinder”,那么这个问题可能会得到解决,但一旦我的Binder就位,就会出现404错误。 请帮帮忙 我的资源: 我的资源配置文件: 我的活页夹[如果到位] 服务: 用户服务及其实施 其他 断续器 现在,我可以使用访问我的资源http://localhost:8080/javaeeLearning/rest/s
我试图在flyway迁移java代码中注入配置属性的组件,但它总是空的。 我用的是带飞道的Spring靴。 然后在Flyway迁移代码中,尝试按照如下方式自动更新该组件:
考虑以下方法: 当我从Postman调用WS时,我得到以下异常: 08-Feb-2019 14:23:44.138 GRAVE [http-nio-8080-exec-7] com.sun.jersey.spi.container.ContainerResponse.mapMappableContainerException MappableContainerException MappableC
我正在尝试用Struts填充select。但是,我得到了一条错误消息:name在其所查找的类中也没有名为“label”的变量,因此我不知道它是如何查找 表单类是一个非常典型的实体类 关于为什么会出现这个错误,有什么建议吗?
问题内容: 我是JAX-RS的新手,我试图了解注释的工作方式。 在javadoc中有六个等级的列表()。但是,我在网络上找到将this注释与其他类型一起使用的代码,例如: 是否有可以与此注释一起使用的受支持类型的列表?在执行标准之间,此列表是否会更改? 我目前正在试验Jersey,我担心自己写的代码无法移植到其他JAX-RS实现中。 问题答案: 铆接的JAX-RS 规范定义了你可以通过注入的所有标