Jak wprowadzić obiekt do kontekstu żądania?
Mam taki scenariusz, w którym chcę napisać filtr i chcę, aby ten filtr wstawił jakiś obiekt do bieżącego żądania i przekazał go dalej, aby gdy Klasa zasobów otrzyma żądanie, mogła użyć tego obiektu.
Klasa filtra
@Override
public void filter(ContainerRequestContext request) throws IOException {
MyObject obj = new MyObject();
// Inject MyObject to request which I dont know how
}
Klasa Zasobów
@PUT @Consumes("application/json")
@Path("/")
public String create(
JSONParam sample,
@Context MyObject obj) {
System.out.println(obj.getName());
return "";
}
2 answers
Możesz po prostu użyć ContainterRequestContext.setProperty(String, Object)
. Następnie wystarczy wstrzyknąć 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();
}
Inną opcją bezpośredniego wtrysku MyObject
jest skorzystanie z funkcjonalności HK2.
Utworzyć fabrykę wstrzyknąć ContainerRequestContext
i zwrócić MyObject
. Na przykład
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) {}
}
Następnie musisz związać fabrykę:
public class InjectApplication extends ResourceConfig {
public InjectApplication() {
...
register(new AbstractBinder(){
@Override
protected void configure() {
bindFactory(MyObjectFactory.class)
.to(MyObject.class)
.in(RequestScoped.class);
}
});
}
}
Z tym samym ustawieniem właściwości jak w powyższym przykładzie filtra, możesz po prostu wprowadzić MyObject
z @Context
@GET
public Response getTest(@Context MyObject myObject) {
return Response.ok(myObject.getMessage()).build();
}
- Zobacz więcej na
Custom Injection
UPDATE
Proszę zobaczyć to pytanie dla problemu z tą implementacją.
Zobacz Też:
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-29 10:00:33
Mam na to rozwiązanie, które nie wymaga kontenera DI, ale nadal daje większość korzyści.
Są dwie części. Pierwszy to sposób na wprowadzenie instancji do mechanizmu wtrysku @ Context zamiast dostarczania klas w obiekcie ApplicationConfig.
Oto technika na to:
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);
}
}
I używasz go w ten sposób:
webAppContext.addEventListener(
new CustomContextResteasyBootstrap()
.addContextObject(MyCustom.class, myCustom)
.addContextObject(AnotherCustom.class, anotherCustom)
// additional objects you wish to inject into the REST context here
);
Teraz możesz używać tych klas z adnotacją @ Context:
@GET
public MyCustom echoService(@Context MyCustom custom) {
return custom;
}
Kolejna część układanki to jak podaj obiekty kontekstowe na żądanie. Aby to zrobić, dodaj następujący kod gdzieś u góry hierarchii wywołań jax-rs (zasadniczo wszystko, co zostanie wywołane poniżej tej linii, uzyska dostęp do obiektu context):
ResteasyProviderFactory.pushContext(MyContextSpecific.class, new MyContextSpecific());
Możesz następnie odwołać się do tego poprzez wstrzyknięcie w dowolnym miejscu poniżej tego poziomu:
@GET
public String contextSpecificEchoService(@Context MyContextSpecific contextSpecific) {
return custom.toString();
}
To jest DI biednego człowieka, ale działa naprawdę dobrze dla Wbudowanych serwerów rest.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-05 22:42:31