我正在从DropWizard 0.7.1迁移到0.8.1的过程中。这包括从Jersey 1.x迁移到2.x。在使用Jersey
1.18.1的实现中,我实现了MyProvider
(为简单起见,更改了所有类名)InjectableProvider
。此类将创建MyInjectable
包含自定义注入批注的对象MyToken
。MyToken
包含传递并由读取的各种属性MyInjectable
。最后,在Application
该类中,我注册的新实例MyProvider
,如下所示。
我已经进行了一些研究,似乎无法完全围绕如何在Jersey 2.x中创建(或替换)这样的secenario进行研究。
这是当前的1.18.1实现:
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.PARAMETER, ElementType.FIELD })
public @interface MyToken {
// Custom annotation containing various attributes
boolean someAttribute() default true;
// ...
}
public class MyProvider implements InjectableProvider<MyToken, Parameter> {
// io.dropwizard.auth.Authenticator
private final Authenticator<String, MyObject> authenticator;
public MyProvider(Authenticator<String, MyObject> authenticator) {
this.authenticator = authenticator;
}
@Override
public ComponentScope getScope() {
return ComponentScope.PerRequest;
}
@Override
public Injectable<?> getInjectable(ComponentContext ic, MyToken t, Parameter p) {
return new MyInjectable(authenticator, t.someAttribute());
}
}
class MyInjectable extends AbstractHttpContextInjectable<MyObject> {
private final Authenticator<String, Session> authenticator;
private final boolean someAttribute;
public MyInjectable(Authenticator<String, MyObject> authenticator, boolean someAttribute) {
this.authenticator = authenticator;
this.someAttribute = someAttribute;
// ... Removed a few paramters for simplicity's sake
}
@Override
public MyObject getValue(HttpContext c) {
final HttpRequestContext request = c.getRequest();
// ... Removed code not pertaining to the question
return myObject;
}
}
// Lastly, the register call in the io.dropwizard.Application class
environment.jersey().register(new MyProvider(new MyProviderValidator(someValidator)));
是的Jersey在2.x中使自定义注入的创建更加复杂。对于Jersey 2.x,您需要了解一些自定义注入的主要组件。
org.glassfish.hk2.api.Factory
-创建可注射对象/服务org.glassfish.hk2.api.InjectionResolver
-用于为自己的注释创建注入点。org.glassfish.jersey.server.spi.internal.ValueFactoryProvider
-提供参数值注入。您可以在“
定制注入和生命周期管理”中阅读有关定制注入的更多信息。该文档的一个缺点是缺乏对如何注入参数值的解释。您可以通过简单地实现来摆脱困境InjectResolver
,并且可以使用自定义注释将其注入字段,但是为了注入方法参数,我们需要ValueFactoryProvider
。
幸运的是,我们可以扩展一些抽象类(文档中也没有提到),这些抽象类会使生活变得更轻松。我必须搜索软件包的源代码,org.glassfish.jersey.server.internal.inject
以尝试找出所有问题。
这是一个完整的示例,可帮助您入门。
Token
(注射物)
public class Token {
private final String token;
public Token(String token) { this.token = token; }
public String getToken() { return token; }
}
@TokenParam
(我们的注解注解)
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER, ElementType.FIELD})
public @interface TokenParam {
boolean someAttribute() default true;
}
TokenFactory
(Factory
每个第一个项目点的实现,但我们只需要扩展AbstractContainerRequestValueFactory
。即可ContainerRequestContext
。。请注意,所有这些HK2组件,我们都可以向其中注入其他依赖项,例如TokenAuthenticator
,稍后我们将其绑定到HK2
。
import javax.inject.Inject;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
import org.glassfish.jersey.server.internal.inject.AbstractContainerRequestValueFactory;
public class TokenFactory extends AbstractContainerRequestValueFactory<Token> {
private final TokenAuthenticator tokenAuthenticator;
@Inject
public TokenFactory(TokenAuthenticator tokenAuthenticator) {
this.tokenAuthenticator = tokenAuthenticator;
}
@Override
public Token provide() {
String auth = getContainerRequest().getHeaderString(HttpHeaders.AUTHORIZATION);
try {
if (tokenAuthenticator.authenticate(auth).get() == null) {
throw new WebApplicationException(Response.Status.FORBIDDEN);
}
} catch (AuthenticationException ex) {
Logger.getLogger(TokenFactory.class.getName()).log(Level.SEVERE, null, ex);
}
return new Token("New Token");
}
}
TokenParamInjectionResolver
(实现InjectResolver
每个要点两个。我简单地扩展ParamInjectionResolver
一下。如果您对引擎盖下发生的事情感兴趣,则可以在我链接到的源代码中找到该类)
import org.glassfish.jersey.server.internal.inject.ParamInjectionResolver;
public class TokenParamInjectionResolver extends ParamInjectionResolver {
public TokenParamInjectionResolver() {
super(TokenFactoryProvider.class);
}
}
TokenFactoryProvider
(实现ValueFactoryProvider
第三个要点。我只是扩展AbstractValueFactoryProvider
一下。再次,您可以查看引擎盖下信息的来源)
import javax.inject.Inject;
import org.glassfish.hk2.api.Factory;
import org.glassfish.hk2.api.ServiceLocator;
import org.glassfish.jersey.server.internal.inject.AbstractValueFactoryProvider;
import org.glassfish.jersey.server.internal.inject.MultivaluedParameterExtractorProvider;
import org.glassfish.jersey.server.model.Parameter;
public class TokenFactoryProvider extends AbstractValueFactoryProvider {
private final TokenFactory tokenFactory;
@Inject
public TokenFactoryProvider(
final MultivaluedParameterExtractorProvider extractorProvider,
ServiceLocator locator,
TokenFactory tokenFactory) {
super(extractorProvider, locator, Parameter.Source.UNKNOWN);
this.tokenFactory = tokenFactory;
}
@Override
protected Factory<?> createValueFactory(Parameter parameter) {
Class<?> paramType = parameter.getRawType();
TokenParam annotation = parameter.getAnnotation(TokenParam.class);
if (annotation != null && paramType.isAssignableFrom(Token.class)) {
return tokenFactory;
}
return null;
}
}
TokenFeature
(在这里,我们绑定了上面看到的所有组件,甚至包括了TokenAuthentictor
我遗漏的组件,但是如果您通常使用Dropwizard的话Authenticator
。我还使用了Feature
。我倾向于这样做来包装自定义功能的组件。在这里,您也可以使用可以决定所有范围(只需注意某些组件必须在Singleton
范围内)
import javax.inject.Singleton;
import javax.ws.rs.core.Feature;
import javax.ws.rs.core.FeatureContext;
import org.glassfish.hk2.api.InjectionResolver;
import org.glassfish.hk2.api.TypeLiteral;
import org.glassfish.hk2.utilities.binding.AbstractBinder;
import org.glassfish.jersey.server.spi.internal.ValueFactoryProvider;
public class TokenFeature implements Feature {
@Override
public boolean configure(FeatureContext context) {
context.register(new AbstractBinder(){
@Override
public void configure() {
bind(TokenAuthenticator.class)
.to(TokenAuthenticator.class)
.in(Singleton.class);
bind(TokenFactory.class).to(TokenFactory.class)
.in(Singleton.class);
bind(TokenFactoryProvider.class)
.to(ValueFactoryProvider.class)
.in(Singleton.class);
bind(TokenParamInjectionResolver.class)
.to(new TypeLiteral<InjectionResolver<TokenParam>>(){})
.in(Singleton.class);
}
});
return true;
}
}
最后,只需注册功能
register(TokenFeature.class);
现在,您应该能够注入Token
with
@TokenParam
以及您通常的实体主体(如果我们未实现的话,这是不可能的)ValueFactoryProvider
@POST
@Consumes(MediaType.APPLICATION_JSON)
public String postToken(@TokenParam Token token, User user) {
}
对于您的特定用例来说,这是一个一半@
$$$的示例。更好的方法可能是在Factory
类中使用clone方法并TokenFactory
使用一些参数创建一个新方法(也许是从注释. For example, in the
TokenFactory中获得的,
public class TokenFactory extends AbstractContainerRequestValueFactory<Token> {
public TokenFactory clone(boolean someAttribute) {
return new TokenFactory(authenticator, someAttribute);
}
然后在TokenFactoryProvider
ine createValueFactory
方法中,调用clone方法
TokenParam annotation = parameter.getAnnotation(TokenParam.class);
if (annotation != null && paramType.isAssignableFrom(Token.class)) {
return tokenFactory.clone(annotation.someAttribute());
}
或者,您实际上 可以 在方法内部 创建 工厂。你有选择。
我创建了一个自定义验证属性,我想将其用于 API 控制器 DTO。此属性需要来自已配置选项的值,这就是我在构造函数中注入这些值的原因,以便我以后可以在 和 方法中使用选项服务。 不幸的是,当我想在DTO中将其用作属性时 我收到错误信息 没有给出对应于'MyValidationAttribute.MyValidationAttribute(IOptionsMonitor)'所需形式参数'myOpti
我已经用自定义注释注释了Spring bean,但似乎Spring在创建bean后删除了我的自定义注释。 第二步不行,我的自定义注释丢失了。(可能是到期的代理文件) 我的豆子 我的一个自定义注释的示例 findAndDoStuffWithAnnotatedThings Bean中出错的内容被传递到一个类,在该类中,我的自定义注释得到验证,但我的验证程序找不到任何注释。(Util使用isAnnota
我目前正在开发一个尽可能尊重六边形架构原则的应用程序。 因此,我的“域”模块(组Id: ; 工件Id:)不依赖于任何技术框架。 我的所有服务都使用自定义注释(本身是我域的一部分)进行注释: 然而,在我的“Quarkus应用”模块(groupId:< code > acme ;artifact id:< code > app-quar kus ,我需要注入我的“域”模块中定义的服务(< code>a
我们一直在使用Spring@Value注释来注入属性值。我们有一个约定来命名属性名称,以匹配它们注入的java字段。这带来了不必要的工作,即每个ConfigBean的java字段都需要用@Value注释。 我正在寻找一种方法,用新的注释注释java类(比如说ConfigBean),让一些后处理器读取这些bean的属性名称,并自动注入属性值。 我正在寻找一些关于如何在没有@Value注释的情况下实现
我在整个代码中有一堆常量,用于系统的各种可调整属性。我正在将它们全部移动到一个中央文件中。我目前的解决方案是有一个静态加载文件并公开各种getter方法,如下所示: 唯一的问题是,对于我从这个文件中获得的每个常量,我都有一些样板: 我不认为我想使用Spring或类似的东西,因为那看起来更像是boilerplae。我希望使用自定义注释来解决这个问题。我找到了这个教程,但是我真的不能弄清楚如何从注释处
我正在创建一个后spring web服务endpoint,并使用一个Object,其中包含大约7-8个String变量和其他变量。在验证请求时,我需要对每个条件进行相同的测试,例如- < li >条件1如果为真,则继续,否则抛出异常。 < li >条件2如果为真,则继续,否则抛出异常。 < li >条件3如果为真,则继续,否则抛出异常 3-4更多业务逻辑验证就像上面一样,有很多if-else,一种