I have a simple Dropstar 0.8.1 REST service that pulls on Jersey 2.17. Before the REST / Jetty service, I have an authentication service that adds some authorization information to the HTTP header that is passed to my Dropwizard application.
I would really like to create a custom annotation in my resource that hides all the messy garbage of the POJO parsing header. Something like that:
@Path("/v1/task")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class TaskResource {
@UserContext
private UserContextData userContextData;
@GET
public Collection<Task> fetch() {
}
I spent the last day looking back at stackoverflow and finding several other people who had the same problem and appeared (?) To get some satisfaction, but I can’t avoid getting “Not inside the request area” when I try to do this .
, 22.1 22.2 : https://jersey.java.net/documentation/2.17/ioc.html
( Dropwizard ), "@SessionInject" , " " . ?
:
@Path("/v1/task")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class TaskResource {
private final TaskDAO taskDAO;
@Context
private HttpServletRequest httpRequest;
@SessionInject
private HttpSession httpSession;
public TaskResource(TaskDAO taskDAO) {
this.taskDAO = taskDAO;
}
@GET
public Collection<Task> fetch(@SessionInject HttpSession httpSession) {
if (httpSession != null) {
logger.info("TOM TOM TOM httpSession isn't null: {}", httpSession);
}
else {
logger.error("TOM TOM TOM httpSession is null");
}
return taskDAO.findAllTasks();
}
SessionInjectResolver:
package com.foo.admiral.integration.jersey;
import com.foo.admiral.integration.core.SessionInject;
import javax.inject.Inject;
import javax.inject.Named;
import javax.servlet.http.HttpSession;
import org.glassfish.hk2.api.Injectee;
import org.glassfish.hk2.api.InjectionResolver;
import org.glassfish.hk2.api.ServiceHandle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SessionInjectResolver implements InjectionResolver<SessionInject> {
private static final Logger logger = LoggerFactory.getLogger(HttpSessionFactory.class);
@Inject
@Named(InjectionResolver.SYSTEM_RESOLVER_NAME)
InjectionResolver<Inject> systemInjectionResolver;
@Override
public Object resolve(Injectee injectee, ServiceHandle<?> handle) {
if (HttpSession.class == injectee.getRequiredType()) {
return systemInjectionResolver.resolve(injectee, handle);
}
return null;
}
@Override
public boolean isConstructorParameterIndicator() {
return false;
}
@Override
public boolean isMethodParameterIndicator() {
return false;
}
}
HttpSessionFactory:
package com.foo.admiral.integration.jersey;
import javax.inject.Inject;
import javax.inject.Singleton;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.glassfish.hk2.api.Factory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Singleton
public class HttpSessionFactory implements Factory<HttpSession> {
private static final Logger logger = LoggerFactory.getLogger(HttpSessionFactory.class);
private final HttpServletRequest request;
@Inject
public HttpSessionFactory(HttpServletRequest request) {
logger.info("Creating new HttpSessionFactory with request");
this.request = request;
}
@Override
public HttpSession provide() {
logger.info("Providing a new session if one does not exist");
return request.getSession(true);
}
@Override
public void dispose(HttpSession t) {
}
}
:
package com.foo.admiral.integration.core;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface SessionInject {
}
, , Application Dropwizard:
@Override
public void run(TodoConfiguration configuration, Environment environment) throws Exception {
...
environment.jersey().register(new AbstractBinder() {
@Override
protected void configure() {
bindFactory(HttpSessionFactory.class).to(HttpSession.class);
bind(SessionInjectResolver.class)
.to(new TypeLiteral<InjectionResolver<SessionInject>>() { })
.in(Singleton.class);
}
});
:
Caused by: java.lang.IllegalStateException: Not inside a request scope.
at jersey.repackaged.com.google.common.base.Preconditions.checkState(Preconditions.java:149)
at org.glassfish.jersey.process.internal.RequestScope.current(RequestScope.java:233)
at org.glassfish.jersey.process.internal.RequestScope.findOrCreate(RequestScope.java:158)
at org.jvnet.hk2.internal.MethodInterceptorImpl.invoke(MethodInterceptorImpl.java:74)
at org.jvnet.hk2.internal.MethodInterceptorInvocationHandler.invoke(MethodInterceptorInvocationHandler.java:62)
at com.sun.proxy.$Proxy72.getSession(Unknown Source)
at com.foo.admiral.integration.jersey.HttpSessionFactory.provide(HttpSessionFactory.java:29)
at com.foo.admiral.integration.jersey.HttpSessionFactory.provide(HttpSessionFactory.java:14)
, :
1) , HttpSessionFactory , , Factory DropWizard.
2) () , , ( HTTPSession - , , Factory ...)
public Collection<Task> fetch(@SessionInject HttpSession httpSession) {
3) , , "" environment.jersey(). () environment.jersey(). GetResourceConfig(). ()... , .
- ? !