问题
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