gpt4 book ai didi

java - 如何将 UriInfo 对象注入(inject)非资源类

转载 作者:行者123 更新时间:2023-11-30 08:43:33 25 4
gpt4 key购买 nike

在修改我的项目代码的过程中,我发现我没有机会将 UriInfo 对象插入到资源类中(使用 @Context 注释)不幸的是,我无法更改方法或构造函数签名以检索资源中的 uriinfo 并将其传递给服务类。

是否有任何选项可以将 UriInfo 插入普通类(不是 jax-rs)?也许有一些选项可以说 Jersey 不仅扫描资源类,还扫描自定义类?编辑:

这里是一些代码示例

@Path("path")
public class JerseyResource {
@Get
public Responce executeMethod(@QueryParam Criteria criteria, @QueryParam ObjType type) {
return RestUtils.chooseServiceByType(type).process(criteria);
}
}

RestUtils.chooseServiceByType(type) 可以返回大约 15 个不同的实例。并且只有 1 个实例(即 Type2LogicProcessorServiceImpl)我需要访问 process(criteria) 方法中的 uriInfo 对象

谢谢,迪马

最佳答案

您需要将该类绑定(bind)为 Jersey 的 DI 框架中的服务,HK2 . Jersey 使用 HK2 进行大部分注入(inject),包括 @Context 注入(inject)。由于 @Context 绑定(bind)到 DI,如果您的服务绑定(bind)到 DI,您可以在您的服务中接受 @Context 注入(inject)。

例如,如果你有这个Service

public class Service {

@Context
UriInfo uriInfo;

public String getUri() {
return uriInfo.getRequestUri().toASCIIString();
}
}

然后你需要像这样绑定(bind)它

public class Binder extends AbstractBinder {
@Override
protected void configure() {
bind(Service.class).to(Service.class);
}
}

然后向 Jersey 注册 Binder 。在 ResourceConfig 中你可以做

public class AppConfig extends ResourceConfig {
public AppConfig() {
register(new Binder());
}
}

如果你使用的是web.xml,那么就没有办法直接注册binder了。您将需要使用 Feature并让该功能被发现。您可以在那里注册 Binder 。

@Provider
public class BinderFeature implements Feature {
@Override
public boolean configure(FeatureContext ctx) {
ctx.register(new Binder());
return true;
}
}

然后您可以将Service注入(inject)到您的资源类中

@Path("uri")
public class UriResource {

@Inject
Service service;

@GET
public String get() {
return service.getUri();
}
}

更多信息:


更新

看看下面的测试。它都可以通过单个测试依赖项运行

<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-grizzly2</artifactId>
<version>${jersey2.version}</version>
<scope>test</scope>
</dependency>

我所做的是使用 HK2 Factory 注入(inject)查询参数 ObjType,并获取 Service(现在只是一个接口(interface) super 类型)。如果它是需要 UriInfo 的类型,我会用 ServiceLocator 明确地注入(inject)它。工厂和定位器对您来说可能是新概念,所以如果您想了解更多信息,我会浏览上面提供的两个文档链接。

import java.util.logging.Logger;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;

import org.glassfish.hk2.api.Factory;
import org.glassfish.hk2.api.ServiceLocator;
import org.glassfish.hk2.utilities.binding.AbstractBinder;
import org.glassfish.jersey.filter.LoggingFilter;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;

import org.junit.Test;
import static junit.framework.Assert.assertEquals;

public class UriInfoTest extends JerseyTest {

public static interface Service {
String getUri();
}

public static class ServiceOne implements Service {

@Context
UriInfo uriInfo;

@Override
public String getUri() {
return uriInfo.getRequestUri().toASCIIString();
}
}

public static class ServiceTwo implements Service {
@Override
public String getUri() {
return "Blah";
}
}

public static class ObjType {
String param;
public ObjType(String param) {
this.param = param;
}
}

static class RestUtils {
static Service getServiceByType(ObjType type) {
switch (type.param) {
case "one": return new ServiceOne();
case "two": return new ServiceTwo();
default: return new ServiceOne();
}
}
}

public static class ServiceFactory implements Factory<Service> {

@QueryParam("type")
ObjType type;

@Inject
ServiceLocator locator;

@Override
public Service provide() {
Service service = RestUtils.getServiceByType(type);
if (service instanceof ServiceOne) {
locator.inject(service);
}
return service;
}

@Override
public void dispose(Service t) {}
}

public static class Binder extends AbstractBinder {
@Override
protected void configure() {
bindFactory(ServiceFactory.class).to(Service.class);
}
}

@Path("uri")
public static class UriResource {

@Inject
Service service;

@GET
public String get() {
return service.getUri();
}
}

@Override
public ResourceConfig configure() {
return new ResourceConfig(UriResource.class)
.register(new Binder())
.register(new LoggingFilter(Logger.getAnonymousLogger(), true));
}

@Test
public void doit() {
Response response = target("uri").queryParam("type", "one").request().get();
assertEquals(200, response.getStatus());
String message = response.readEntity(String.class);
assertEquals("http://localhost:9998/uri?type=one", message);
response.close();
}
}

关于java - 如何将 UriInfo 对象注入(inject)非资源类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34201468/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com