栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

带有属性的Jersey 2.x自定义注入注释

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

带有属性的Jersey 2.x自定义注入注释

是的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
使用一些参数创建一个新方法(也许是从注释
. Forexample, 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());}

或者,您实际上 可以 在方法内部 创建 工厂。你有选择。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/483291.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号