如何将对象注入jersey请求上下文?

我有这种情况下,我想写一个filter,我希望这个filter插入一些对象到当前的请求,并传递它,以便当资源类获取请求时,它可以使用该对象。

过滤类

@Override public void filter(ContainerRequestContext request) throws IOException { MyObject obj = new MyObject(); // Inject MyObject to request which I dont know how } 

资源类

 @PUT @Consumes("application/json") @Path("/") public String create( JSONParam sample, @Context MyObject obj) { System.out.println(obj.getName()); return ""; } 

你可以使用ContainterRequestContext.setProperty(String, Object) 。 然后只需注入ContainerRequestContext

 @Override public void filter(ContainerRequestContext crc) throws IOException { MyObject obj = new MyObject(); crc.setProperty("myObject", myObject); } @POST public Response getResponse(@Context ContainerRequestContext crc) { return Response.ok(crc.getProperty("myObject")).build(); } 

直接注入MyObject另一种select是使用Jersey 2提供的HK2function。

创build一个工厂注入ContainerRequestContext并返回MyObject 。 例如

 import javax.inject.Inject; import javax.ws.rs.container.ContainerRequestContext; import jetty.plugin.test.domain.MyObject; import org.glassfish.hk2.api.Factory; public class MyObjectFactory implements Factory<MyObject> { private final ContainerRequestContext context; @Inject public MyObjectFactory(ContainerRequestContext context) { this.context = context; } @Override public MyObject provide() { return (MyObject)context.getProperty("myObject"); } @Override public void dispose(MyObject t) {} } 

然后你需要绑定工厂:

 public class InjectApplication extends ResourceConfig { public InjectApplication() { ... register(new AbstractBinder(){ @Override protected void configure() { bindFactory(MyObjectFactory.class) .to(MyObject.class) .in(RequestScoped.class); } }); } } 

使用与上面的filter示例中相同的属性设置,您可以使用@Context注入MyObject

 @GET public Response getTest(@Context MyObject myObject) { return Response.ok(myObject.getMessage()).build(); } 

  • Custom Injection查看更多信息

UPDATE

请看这个问题,这个实现的问题。

也可以看看:

  • 如果您使用的是web.xml而不是ResourceConfig

我有一个解决scheme,这不需要一个DI容器,但仍然给大部分好处。

有两个部分。 首先是如何将实例放入@Context注入机制,而不是在ApplicationConfig对象中提供类。

这里有一个技巧:

 private static class CustomContextResteasyBootstrap extends org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap{ private final Map<Class<?>, Object> additionalContextObjects = new HashMap<Class<?>, Object>(); public <E> CustomContextResteasyBootstrap addContextObject(Class<? super E> clazz, E obj){ additionalContextObjects.put(clazz, obj); return this; } @Override public void contextInitialized(ServletContextEvent event) { super.contextInitialized(event); deployment.getDispatcher().getDefaultContextObjects().putAll(additionalContextObjects); } } 

你可以这样使用它:

  webAppContext.addEventListener( new CustomContextResteasyBootstrap() .addContextObject(MyCustom.class, myCustom) .addContextObject(AnotherCustom.class, anotherCustom) // additional objects you wish to inject into the REST context here ); 

现在你可以用@Context注解来使用这些类:

 @GET public MyCustom echoService(@Context MyCustom custom) { return custom; } 

难题的下一部分是如何提供每个请求的上下文对象。 为此,请在jax-rs调用层次结构顶部附近添加以下代码(基本上,在该行下面调用的任何东西都可以访问上下文对象):

  ResteasyProviderFactory.pushContext(MyContextSpecific.class, new MyContextSpecific()); 

然后,您可以通过任何低于该级别的注射来引用这个:

 @GET public String contextSpecificEchoService(@Context MyContextSpecific contextSpecific) { return custom.toString(); } 

这是穷人的DI,但对于embedded式rest服务器来说,它确实很好。