Working with configuration properties in Jersey

我的未来我决定 提交于 2019-12-08 11:12:44

问题


I use java/jetty self-hosted server and jersey-2 for java RESTful api. Application has application.properties file with properties.

ConfigurationProperties class reads and loads properties file into java.util.Properties class.

Jetty server instantiation is done in the following way.

     // Create and register resources
    final ResourceConfig resourceConfig = new ApiServiceConfig()
            .register(new DependencyInjectionBinder());

    ServletContextHandler contextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);

    contextHandler.setContextPath("/mydomain/api");
    Server jettyServer = new Server(8585);
    jettyServer.setHandler(contextHandler);

    ServletHolder jerseyServlet = new ServletHolder(new ServletContainer(resourceConfig));
    contextHandler.addServlet(jerseyServlet, "/*");

    // Create web context. Can't use.
    //WebApplicationContext webContext = getWebApplicationContext();
    // Add web context to servlet event listener.
    //contextHandler.addEventListener(new ContextLoaderListener(webContext));

    try {
        jettyServer.start();
        jettyServer.join();
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } finally {
        jettyServer.destroy();
    }

I can't use Spring AnnotationConfigWebApplicationContext as it requires commons-logging dependency which doesn't work in java-8.

How can I register Properties with jetty/jersey context and how can I retrieve values later(eg.: context.getProperty("prop.name"))?


回答1:


You could...

Just configure the Properties object as an injectable, and inject it into wherever you need it

final Properties props ...
resourceConfig.register(new AbstractBinder() {
    @Override
    protected void configure() {
        bind(props).to(Properties.class);
    }
});

@Path("config")
public class ConfigResource {

    @Inject
    private Properties properties;

}

You could...

Make the individual properties injectable, using an InjectionResolver and a custom annotation

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public static @interface Config {
    String value();
}

public class ConfigInjectionResolver implements InjectionResolver<Config> {

    private final Properties properties;
    public ConfigurationInjectionResolver(Properties properties) {
        this.properties = properties;
    }

    @Override
    public Object resolve(Injectee injectee, ServiceHandle<?> handle) {
        if (String.class == injectee.getRequiredType()) {
            Config annotation = injectee.getParent().getAnnotation(Config.class);
            if (annotation != null) {
                String prop = annotation.value();
                return properties.getProperty(prop);
            }
        }
        return null;
    }
    ...
}

final Properties props...
resourceConfig.register(new AbstractBinder(){
    @Override
    protected void configure() {
        bind(new ConfigInjectResolver(props))
                .to(new TypeLiteral<InjectionResolver<Config>>(){});
    }
});

Then just use it with the custom annotation

@Path("config")
public class ConfigResource {

    @Config(PROP_KEY)
    private String propValue;

    @GET
    public String getConfigProp() {
        return propValue;
    }
}

You could...

Use a small library that I made

<dependency>
    <groupId>com.github.psamsotha</groupId>
    <artifactId>jersey-properties</artifactId>
    <version>0.1.1</version>
<dependency>

resourceConfig.register(JerseyPropertiesFeature.class);
resourceConfig.property(JerseyPropertiesFeature.RESOURCE_PATH, "appication.properties");

@Path("test")
public class SomeResource {

    @Prop("some.prop")
    private String someFieldProp;

    private String someConstructorProp;

    public SomeResource(@Prop("some.prop") String someConstructorProp) {
        this.someConstructorProp = someConstructorProp;
    }

    @GET
    public String get(@Prop("some.prop") String someParamProp) {
        return someParamProp;
    }
}

You could...

Use Spring. I think the problem you are facing with using Java 8, is that you are using Spring 3.x. I don't think Java 8 is supported. I have had no problems using Jersey/Spring4 with java 8. If you are using the jersey-spring3 dependency, you need to exclude the spring3 dependencies, and add the spring 4. See the UPDATE in this post

See Also:

  • Configuration Properties with Jersey


来源:https://stackoverflow.com/questions/36318651/working-with-configuration-properties-in-jersey

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!