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

arm*_*min 24 java dependency-injection jersey jersey-2.0

我有这个场景,我想编写一个过滤器,我希望这个过滤器将一些对象插入当前请求并传递给它,以便当资源类获取请求时它可以使用该对象.

过滤类

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

资源类

@PUT @Consumes("application/json")
@Path("/")
public String create(
        JSONParam sample,
        @Context MyObject obj) {

    System.out.println(obj.getName());

    return "";
}
Run Code Online (Sandbox Code Playgroud)

Pau*_*tha 41

你可以使用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();
}
Run Code Online (Sandbox Code Playgroud)

MyObject直接注入的另一个选择是使用Jersey 2提供的HK2功能.

创建工厂注入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) {}  
}
Run Code Online (Sandbox Code Playgroud)

然后你需要绑定工厂:

public class InjectApplication extends ResourceConfig {

    public InjectApplication() {
        ...
        register(new AbstractBinder(){
            @Override
            protected void configure() {
                bindFactory(MyObjectFactory.class)
                        .to(MyObject.class)
                        .in(RequestScoped.class);
            } 
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

随着财产如上面的例子过滤器相同的设置,则可以只注射MyObject@Context

@GET
public Response getTest(@Context MyObject myObject) {
    return Response.ok(myObject.getMessage()).build();
}
Run Code Online (Sandbox Code Playgroud)

UPDATE

有关实现的问题,请参阅此问题.

也可以看看: