【问题标题】:Working with configuration properties in Jersey在 Jersey 中使用配置属性
【发布时间】:2016-03-30 20:04:09
【问题描述】:

我使用 java/jetty 自托管服务器和 jersey-2 用于 java RESTful api。 应用程序具有带有属性的 application.properties 文件。

ConfigurationProperties 类读取属性文件并将其加载到java.util.Properties 类中。

Jetty 服务器实例化是通过以下方式完成的。

     // 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();
    }

我不能使用 Spring AnnotationConfigWebApplicationContext,因为它需要在 java-8 中不起作用的 commons-logging 依赖项。

如何使用码头/球衣上下文注册属性以及如何在以后检索值(例如:context.getProperty("prop.name"))?

【问题讨论】:

    标签: java java-8 jersey-2.0 jetty-9


    【解决方案1】:

    你可以...

    只需将Properties 对象配置为可注入对象,然后将其注入到您需要的任何地方

    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;
    
    }
    

    你可以...

    使用InjectionResolver 和自定义注释使各个属性可注入

    @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>>(){});
        }
    });
    

    然后只需将其与自定义注释一起使用

    @Path("config")
    public class ConfigResource {
    
        @Config(PROP_KEY)
        private String propValue;
    
        @GET
        public String getConfigProp() {
            return propValue;
        }
    }
    

    你可以...

    使用我制作的small library

    <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;
        }
    }
    

    你可以...

    使用弹簧。我认为您在使用 Java 8 时面临的问题是您使用的是 Spring 3.x。我认为不支持 Java 8。我在 java 8 中使用 Jersey/Spring4 没有问题。如果您使用 jersey-spring3 依赖项,则需要排除 spring3 依赖项,并添加 spring 4。请参阅the UPDATE in this post

    另请参阅:

    【讨论】:

    • public static @interface Config { ... } 应该放在哪里?在它同一个类,单独的接口类?
    • 它不需要是静态的。我只是在测试它,并在测试时将它作为一个内部类。如果您希望它在它自己的文件中,它不应该(也不能)是静态的。还有你需要重写的 InjectionResolver 中的另外两个方法,你可以只为它们返回 false
    • 在它自己的文件中这些注释是不允许的。
    • 如果是在单个文件中,是不是意味着 ConfigInjectionResolver 类要成为一个内部类?
    • 没有。它应该在它自己的文件中。我展示的所有类都应该在它们自己的文件中
    猜你喜欢
    • 1970-01-01
    • 2021-06-22
    • 2018-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-20
    • 2018-04-28
    • 2014-07-21
    相关资源
    最近更新 更多