2016-12-19 2 views
0

У меня есть сервисное обслуживание на моем tomcat, и он работает правильно, но когда я развертываю его на другом сервере tomcat, он выдает исключение.Java jersey 2.6: ContainerRequestFilter: не внутри области запроса

Я пытаюсь реализовать ContainerRequestFilter. И это исключение вызвано @Context resourceInfo в моем authenticationFilter (класс, который реализует ContainerRequestFilter). Но я не понимаю, почему и как это исправить. (Я последовал this tutorial)

A MultiException has 3 exceptions. They are: 
1. java.lang.IllegalStateException: Not inside a request scope. 
2. java.lang.IllegalArgumentException: While attempting to resolve the dependencies of services.AuthentificationFilter errors were found 
3. java.lang.IllegalStateException: Unable to perform operation: resolve on services.AuthentificationFilter 

org.jvnet.hk2.internal.Collector.throwIfErrors(Collector.java:88) 
org.jvnet.hk2.internal.ClazzCreator.resolveAllDependencies(ClazzCreator.java:270) 
org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:414) 
org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:456) 
org.jvnet.hk2.internal.SingletonContext$1.compute(SingletonContext.java:114) 
org.jvnet.hk2.internal.SingletonContext$1.compute(SingletonContext.java:102) 
org.glassfish.hk2.utilities.cache.Cache$OriginThreadAwareFuture$1.call(Cache.java:97) 
java.util.concurrent.FutureTask.run(FutureTask.java:266) 
org.glassfish.hk2.utilities.cache.Cache$OriginThreadAwareFuture.run(Cache.java:154) 
org.glassfish.hk2.utilities.cache.Cache.compute(Cache.java:199) 
org.jvnet.hk2.internal.SingletonContext.findOrCreate(SingletonContext.java:153) 
org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2445) 
org.jvnet.hk2.internal.ServiceHandleImpl.getService(ServiceHandleImpl.java:98) 
org.jvnet.hk2.internal.ServiceHandleImpl.getService(ServiceHandleImpl.java:87) 
org.glassfish.jersey.internal.inject.Providers.getAllRankedProviders(Providers.java:234) 
org.glassfish.jersey.server.ApplicationHandler.getProcessingProviders(ApplicationHandler.java:616) 
org.glassfish.jersey.server.ApplicationHandler.initialize(ApplicationHandler.java:409) 
org.glassfish.jersey.server.ApplicationHandler.access$500(ApplicationHandler.java:161) 
org.glassfish.jersey.server.ApplicationHandler$3.run(ApplicationHandler.java:286) 
org.glassfish.jersey.internal.Errors$2.call(Errors.java:289) 
org.glassfish.jersey.internal.Errors$2.call(Errors.java:286) 
org.glassfish.jersey.internal.Errors.process(Errors.java:315) 
org.glassfish.jersey.internal.Errors.process(Errors.java:297) 
org.glassfish.jersey.internal.Errors.processWithException(Errors.java:286) 
org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:283) 
org.glassfish.jersey.servlet.WebComponent.<init>(WebComponent.java:298) 
org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:167) 
org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:349) 
javax.servlet.GenericServlet.init(GenericServlet.java:158) 
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) 
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) 
org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:620) 
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349) 
org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:784) 
org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) 
org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:802) 
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1410) 
org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) 
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 
java.lang.Thread.run(Thread.java:745) 

Код моего authenticationFilter

@Provider 
public class AuthentificationFilter implements javax.ws.rs.container.ContainerRequestFilter { 

@Context 
private ResourceInfo resourceInfo; 

private static final String AUTHORIZATION = "Authorization"; 
private static final String BASIC = "Basic"; 
private static final Response ACCESS_DENIED = Response.status(Response.Status.UNAUTHORIZED).entity("Essayez de mettre sudo devant votre requete").build(); 
private static final Response ACCESS_FORBIDDEN = Response.status(Response.Status.FORBIDDEN).entity("You shall not pass !").build(); 

@Override 
public void filter(final ContainerRequestContext context) throws IOException { 
    Method method = resourceInfo.getResourceMethod(); 
    if(!method.isAnnotationPresent(PermitAll.class)) { 
     MultivaluedMap<String, String> headers = context.getHeaders(); 
     List<String> authorization = headers.get(AUTHORIZATION); 

     if(method.isAnnotationPresent(DenyAll.class)) { 
      context.abortWith(ACCESS_FORBIDDEN); 
      return; 
     }else if(authorization == null || authorization.isEmpty()) { 
      context.abortWith(ACCESS_DENIED); 
      return; 
     } 

     String encodedUserPassword = authorization.get(0).replaceFirst(BASIC + " ", ""); 
     String auth = new String(Base64.getDecoder().decode(encodedUserPassword.getBytes()));; 

     String[] authTab = auth.split(":"); 
     String username = authTab[0]; 
     String password = authTab[1]; 

     if(method.isAnnotationPresent(RolesAllowed.class)) { 
      RolesAllowed rolesAnnotation = method.getAnnotation(RolesAllowed.class); 
      Set<String> rolesSet = new HashSet<String>(Arrays.asList(rolesAnnotation.value())); 
      if(!isAllowed(username, password, rolesSet)) { 
       context.abortWith(ACCESS_DENIED); 
       return; 
      } 
     } 
    } 
} 

private boolean isAllowed(final String username, final String password, final Set<String> rolesSet) 
{ 
    boolean isAllowed = false; 
    User user; 
    if((user = new UserMapper().get(username, password)) != null) { 
     String role = user.getStatus().toString(); 
     if(rolesSet.contains(role)) 
      isAllowed = true; 
    } 
    return isAllowed; 
} 

} 

Шифр ​​MyApplication.java, который регистрирует фильтр:

public class MyApplication extends ResourceConfig { 

public MyApplication() { 
    packages("services"); 
    register(AuthentificationFilter.class); 
} 
} 

И, наконец, web.xml

<?xml version="1.0" encoding="UTF-8"?> 
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" 
    version="3.1"> 

<servlet> 
    <servlet-name>Example API</servlet-name> 
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> 
    <init-param> 
     <param-name>javax.ws.rs.Application</param-name> 
     <param-value>services.MyApplication</param-value> 
    </init-param> 
    <init-param> 
     <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name> 
     <param-value>true</param-value> 
    </init-param> 
    <load-on-startup>1</load-on-startup> 
</servlet> 

<servlet-mapping> 
    <servlet-name>Example API</servlet-name> 
    <url-pattern>/*</url-pattern> 
</servlet-mapping> 
</web-app> 

Что я делаю неправильно?

+0

Да, это так. Он работает на моем tomcat, но это ошибки, когда я развертываю файл .war на другом сервере tomcat. (Я отредактирую сообщение, чтобы заметить его) –

ответ

1

Я наконец нашел решение. Мне пришлось создать класс, который реализует DynamicFeature и зарегистрировать мой AuthenticationFilter благодаря настраиваемому конструктору.

@Provider 
public class AuthenticationDynamicFeature implements DynamicFeature { 

    @Override 
    public void configure(ResourceInfo resourceInfo, FeatureContext featureContext) { 
     featureContext.register(new AuthenticationFilter(resourceInfo)); 
    } 
} 

А вот пользовательский конструктор:

public AuthenticationFilter(ResourceInfo resourceInfo) { 
    super(); 
    this.resourceInfo = resourceInfo; 
} 

Я пробовал много других способов, и это один, это единственный, который работал для меня.

Смежные вопросы