- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想按字段为单个请求注入(inject)数据存储,例如
@Context
protected HttpServletRequest request;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER, ElementType.FIELD})
public @interface TenantDatastore {}
public class TenantDatastoreFactory extends AbstractContainerRequestValueFactory<Datastore> {
public TenantDatastoreFactory() {}
@Override
public Datastore provide() {
ContainerRequest request = getContainerRequest();
return DatastoreManager.getDs(request.getHeaders().get("Host")));
}
@Override
public void dispose(Datastore d) {}
}
public class TenantDatastoreFactoryProvider extends AbstractValueFactoryProvider {
private final TenantDatastoreFactory tenantDatastoreFactory;
@Inject
public TenantDatastoreFactoryProvider(
final MultivaluedParameterExtractorProvider extractorProvider,
ServiceLocator locator,
TenantDatastoreFactory tenantDatastoreFactory) {
super(extractorProvider, locator, Parameter.Source.UNKNOWN);
this.tenantDatastoreFactory = tenantDatastoreFactory;
}
@Override
protected Factory<?> createValueFactory(Parameter parameter) {
Class<?> paramType = parameter.getRawType();
TenantDatastore annotation = parameter.getAnnotation(TenantDatastore.class);
if (annotation != null && paramType.isAssignableFrom(Datastore.class)) {
return tenantDatastoreFactory;
}
return null;
}
}
public class TenantDatastoreInjectionResolver extends ParamInjectionResolver {
public TenantDatastoreInjectionResolver() {
super(TenantDatastoreFactoryProvider.class);
}
}
@Path("/users")
public class User {
@TenantDatastore
private Datastore ds;
private ObjectMapper objectMapper;
public User(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
@GET
public Response getUsers(){
return Response.ok(ds.find(User.class).asList()).build();
}
}
environment.jersey().register(new UserResource(objectMapper));
environment.jersey().getResourceConfig().register(new AbstractBinder(){
@Override
public void configure() {
bind(TenantDatastoreFactory.class)
.to(TenantDatastoreFactory.class)
.in(Singleton.class);
bind(TenantDatastoreFactoryProvider.class)
.to(ValueFactoryProvider.class)
.in(Singleton.class);
bind(TenantDatastoreInjectionResolver.class)
.to(new TypeLiteral<InjectionResolver<TenantDatastore>>(){})
.in(Singleton.class);
}
});
environment.jersey().register(UserResource.class);
javax.servlet.http.HttpServletRequest
连同
javax.ws.rs.core.Context
在注册为实例的资源中工作得很好,那么我怎样才能使我的用例的这种行为成为可能呢?
最佳答案
因此,当您实例化资源以使其成为单例时,Jersey 会尝试在启动时进行所有注入(inject)。这意味着尝试访问本质上是请求范围的任何对象都将失败......除非......该对象是可代理的。
一些对象是由 Jersey 制作的,这是设计和规范的。例如 HttpHeaders
, UriInfo
, SecurityContext
,以及其他一些列表 here .虽然 HttpServletRequest
未列出,它也是可代理的对象之一。
可代理的意思是注入(inject)代理而不是注入(inject)实际对象(在有请求之前不存在)。在代理上进行调用时,它们会被转发到当前请求中可用的实际对象。您可以尝试打印/记录 HttpServletRequest
的类你会看到这个类实际上是com.sun.proxy.ProxyX
而不是 HttpServletRequestSomeImpl
.这就是 Java 的 dynamic proxies 的魔力在上类。
您当前面临的问题是注入(inject) Datastore
.它本质上是请求范围的,因为它的创建依赖于请求上下文信息,即 header 。因此,在注入(inject)期间,此调用无法获取 ContainerRequest
在您的工厂内
ContainerRequest request = getContainerRequest();
Datastore
可代理的。
bindFactory(...).proxy(true).proxyForSameScope(false).to(...);
proxy(true)
方法使其可代理,
proxyForSameScope(false)
说如果我们试图注入(inject)同一个作用域,它不应该是代理,而是实际的实例。
bind(TenantDatastoreFactory.class)
.to(TenantDatastoreFactory.class)
.in(Singleton.class);
TenantDatastoreFactoryProvider
.但是我们实际上需要使代理工作,将工厂绑定(bind)到实际的
Datastore
。 :
bindFactory(TenantDatastoreFactory.class)
.proxy(true)
.proxyForSameScope(false)
.to(Datastore.class)
.in(RequestScoped.class);
Factory
的问题。来自
createValueFactory
方法。我们不想只返回
TenantDatastoreFactory
例如,因为我们仍然会面临与
provide
相同的问题。调用方法来获取
Datastore
.为了解决这个问题,我们可以执行以下操作
@Override
protected Factory<?> createValueFactory(Parameter parameter) {
Class<?> paramType = parameter.getRawType();
TenantDatastore annotation = parameter.getAnnotation(TenantDatastore.class);
if (annotation != null && paramType.isAssignableFrom(Datastore.class)) {
return getFactory();
}
return null;
}
private Factory<Object> getFactory() {
return new Factory<Object>() {
@Context
Datastore datastore;
@Override
public Object provide() {
return datastore;
}
@Override
public void dispose(Object t) {}
};
}
Factory
动态地,我们在其中注入(inject)代理
Datastore
.现在当 Jersey 尝试注入(inject)资源类时,它会注入(inject)代理,而
provide
方法永远不会在启动时调用。只有在我们尝试实际使用
Datastore
时才会调用它。在请求期间。
TenantDatastoreFactory
和匿名
Factory
创建为运行时。但这是制作
Datastore
所必需的。可代理并确保
provide()
启动时永远不会调用方法。
TenantDatastoreFactoryProvider
来简化实现。 .这仅对参数注入(inject)是必需的。我们只需要
InjectionResolver
处理自定义注释,工厂创建
Datastore
.
InjectionResolver
实现将需要更改如下
public class TenantDatastoreInjectionResolver
implements InjectionResolver<TenantDatastore> {
@Inject
@Named(InjectionResolver.SYSTEM_RESOLVER_NAME)
InjectionResolver<Inject> systemInjectionResolver;
@Override
public Object resolve(Injectee injectee, ServiceHandle<?> handle) {
if (Datastore.class == injectee.getRequiredType()) {
return systemInjectionResolver.resolve(injectee, handle);
}
return null;
}
@Override
public boolean isConstructorParameterIndicator() { return false; }
@Override
public boolean isMethodParameterIndicator() { return false; }
}
TenantDatastoreFactoryProvider
@Override
public void configure() {
bindFactory(TenantDatastoreFactory.class)
.proxy(true)
.proxyForSameScope(false)
.to(Datastore.class)
.in(RequestScoped.class);
bind(TenantDatastoreInjectionResolver.class)
.to(new TypeLiteral<InjectionResolver<TenantDatastore>>() {
})
.in(Singleton.class);
}
关于java - jersey 2 上下文注入(inject)基于没有单例的 HttpRequest,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34747574/
假设我的客户端(浏览器)请求我的 java 服务(服务 A)。 http://localhost:8080/getDataFromB 根据服务 A 的请求,我需要向服务 B 或服务 C 发出另一个 H
我正在尝试调用 API 来检索数据列表,此数据将帮助我获取图像源。因此,对于每个数据条目,我尝试调用图像 url 并使用 Parse Image 进行一些图像处理。问题是,内部的 httpReques
当前代码 if (!(context.Exception is exception)) HttpContent requestContent = context.Request.Content
我有这个代码: You are browsing this site with: Or with Request.UserAgent: 第一个在浏览器
我正在使用 Django 和 TornadIO2/Tornado 编写一个 socket.io 应用程序。在 TonradIO2 session 中,我可以访问 Tornado 的 HTTPReque
用于确定用户代理的这两个属性之间有什么区别(如果有)和优点/缺点? Dim strUserAgt as String userAgent = Request.userAgent 对比 Dim strU
详情如下:https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.http.httprequest?view=aspnetco
我一直在关注我网站的性能,在所有执行缓慢的代码 (>1s) 中,超过 90% 是因为 System.Web.HttpRequest.GetEntireRawContent()(由 System.Web
我有一个后端服务,它接受授权 header 来验证访问。我使用 Spring cloud zuul 创建了一个网关服务,并将请求路由到后端服务。 网关服务本身受 OAuth2 保护,并接受授权 hea
是否可以在中间件函数中获取请求方法(GET、POST、PUT...)? $myMiddleware = function (Request $request) { // This is wha
代码如下: //Get请求方式 private string RequestGet(string Url) &n
在 .net Framework yield ok. // if is not valid var request = HttpContext.Current.Req
在用于 http get 和 post 的 angular 5.2.x 中,我有以下代码: post(url: string, model: any): Observable { return thi
我试图了解如何从Dart进行Ajax调用。我对Web编程的了解非常有限。 我的简单服务器ajax.py:- #!/usr/bin/env python from datetime import tim
我正在为Http GET请求创建包装器类,但是当我使用HttpRequest.request时,没有任何响应。如果我使用原始的HttpRequests使用等效的代码,则可以使用。 我想念什么吗?我正在
我正在尝试生成一个 jmeter 脚本,其中每次运行脚本时都会创建一个唯一的文件夹 - 将某种变量添加到文件夹名称中,例如用户名+时间戳,应该足以保证唯一性。然而,jmeter 并没有将变量解析为其值
我有一个网络应用程序,它有一个计时器,每 3 秒触发一次轮询以获取数据。它工作正常大约 2.5 分钟,然后 Chromium 崩溃。 我的请求 Dart 看起来像这样 HttpRequest.getS
我目前有一个函数,可以生成 httpRequest 并将接收到的 json 解析为 URL array 。我想在第一个请求完成并且数据解析后触发第二个 httpRequest ,在我尝试过的两种解决方
我试图像这样延迟我的 $http 调用: githubService.getUserEvents = function getUserEvents() { return $timeout
我正在运行 340 个并发用户以使用 jmeter 在服务器上进行负载测试。 但是在大多数情况下,jmeter 挂断并且不会返回,即使我尝试关闭连接它也只是挂断了。最终我不得不关闭应用程序。 任何想法
我是一名优秀的程序员,十分优秀!