Jersey 2.*. Come sostituire InjectableProvider e AbstractHttpContextInjectable di Maglia 1.*

Vorrei creare una classe i cui oggetti possono essere inseriti utilizzando il @Context annotazione (o meglio ancora un’annotazione personalizzati per i casi in cui ho bisogno di passare un argomento per l’annotazione) in risorsa metodi. In Jersey 1.* Io avrei usato InjectableProvider (nel mio caso insieme con AbstractHttpContextInjectable). Quello che sto cercando di realizzare è qualcosa di simile a @Auth [Uno] da dropwizard (che usa Jersey 1.7).

L’iniezione capacità di Jersey sono stati sostituiti da HK2 per quanto ne so io e non ho trovato alcun esempio di quello che sto descrivendo.

Edit: Vedere questa domanda per ulteriori problemi che ho incontrato durante il tentativo di seguire Michal guida.

 

2 Replies
  1. 21

    È necessario implementare InjectionResolver<T> interfaccia HK2. Guarda le implementazioni esistenti che sono presenti in Jersey di lavoro:

    Una volta fatto questo, è necessario estendere AbstractBinder da HK2 e collegare il InjectionResolver via è #configure() metodo:

    public class MyResolverBinder extends AbstractBinder {
    
        @Override
        protected void configure() {
            bind(MyInjectionResolver.class)
                    .to(new TypeLiteral<InjectionResolver<MyAnnotation>>() {})
                    .in(Singleton.class);
        }
    }

    … e registrare un esempio di questo raccoglitore in classe di applicazione (o via funzione):

    Feature:

    public class MyFeature implements Feature {
    
        @Override
        public boolean configure(final FeatureContext context) {
            context.register(new MyResolverBinder());
            return true;
        }
    }

    registro MyFeature in Application:

    public class JaxRsApplication extends Application {
    
        @Override
        public Set<Class<?>> getClasses() {
            final HashSet<Class<?>> classes = new HashSet<Class<?>>();
            classes.add(MyFeature.class);
            //Register other providers or resources.
            return classes;
        }
    }

    registro MyResolverBinder o Feature in ResourceConfig

    new ResourceConfig()
            //Register either MyFeature
            .register(MyFeature.class)
            //or MyResolverBinder
            .register(new MyResolverBinder())
            //Register other providers or resources
            .packages("my.package");
    • Grazie! Che sembra essere esattamente ciò di cui ho bisogno.
    • Michal, ho provato a seguire la guida, ma ho incontrato uno strano avvertimento “… UN metodo HTTP GET … non dovrebbe consumare qualsiasi entità.”. Io non sono sicuro di cosa fare (modifica alla mia domanda per ulteriori dettagli). Avete qualche idea su cosa potrebbe essere la causa di esso? Grazie.
    • Grazie per la risposta. Tuttavia, non è chiaro a me come creare un oggetto dato, diciamo, il ContainerRequestContext e come smaltire correttamente iniettato di un oggetto, ad esempio, chiamando close(). Non riesco a trovare un esempio online, avete suggerimenti?
    • ContainerRequestContext è stato creato per voi da Jersey (si può accedere al provider). Se hai bisogno di smaltire l’oggetto di provare l’attuazione di un @PreDestroy metodo.
    • Io sono l’unico che ha la sensazione che questo è andato molto semplice e conciso, in Jersey 1.x estremamente eccessivamente ingegnere e ingombrante in 2.x?
  2. 4

    Fornire un’implementazione di InjectionResolver solo aiuta con iniezione, non quando la risoluzione di valori per i parametri di una risorsa metodo.

    Almeno con la Maglia 2.11, è necessario definire un ValueFactoryProvider annotato con @Provider.

    @Provider
    public class MyValueFactoryProvider implements ValueFactoryProvider {
    
        @Inject
        private MyFactory factory;
    
        @Override
        public Factory<?> getValueFactory(Parameter parameter) {
            if (parameter.getAnnotation(MyAnnotationParam.class) != null) {
                return factory;
            }
    
            return null;
        }
    
        @Override
        public PriorityType getPriority() {
            return Priority.NORMAL;
        }
    
    }

    Se si desidera ottenere il valore iniettato, ad esempio, i membri e i parametri del costruttore, quindi InjectionResolver funziona bene.

Lascia un commento