2015-04-30 41 views
9

Aby zobaczyć pełny kod dla tej kwestii, proszę zobaczyć ten GitHubJersey: ContainerRequestFilter nie dostać Context ServletRequest

https://github.com/mobiusinversion/web-application

ja również utworzony ten Jersey Jira

https://java.net/jira/browse/JERSEY-2851

jestem działa na komputerze ContainerRequestFilter przy użyciu oprogramowania Jersey 2.15. Jest to osadzona aplikacja Jetty, która jest zacieniona do jednego słoika.

wprowadzający Jetty (grupa główna):

public static void main(String[] args) throws Exception { 
    ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); 
    context.setContextPath("/"); 
    Server jettyServer = new Server(10005); 
    jettyServer.setHandler(context); 
    ServletHolder jerseyServlet = context.addServlet(ServletContainer.class, "/*"); 
    jerseyServlet.setInitOrder(0); 
    jerseyServlet.setInitParameter(ServerProperties.PROVIDER_PACKAGES, ServletConstants.COMPONENT_SCAN_ROOT); 

    try { 
     System.out.println("Starting Jetty"); 
     jettyServer.start(); 
     System.out.println("Jetty Started"); 
     jettyServer.join(); 
    } catch (Exception e) { 
     System.out.println("Could not start server"); 
     e.printStackTrace(); 
    } finally { 
     jettyServer.destroy(); 
    } 
} 

że posiada filtr, który jest dołączony przez operatora

@Provider 
public class ExampleProvider implements DynamicFeature { 

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

Następnie na filtr:

public class ExampleFilter implements ContainerRequestFilter { 

    private static final Logger logger = LoggerFactory.getLogger(ExampleFilter.class); 

    @Context 
    private HttpServletRequest servletRequest; 

    @Override 
    public void filter(ContainerRequestContext containerRequestContext) throws IOException { 
     logger.info("IP ADDRESS " + servletRequest.getRemoteAddr()); 
     // ... 
    } 

} 

Jednak w ten sposób powstaje NullPointerException:

Caused by: java.lang.NullPointerException: null 
at com.example.filters.ExampleFilter.filter(ExampleFilter.java:29) 
at org.glassfish.jersey.server.ContainerFilteringStage.apply(ContainerFilteringStage.java:131) 
at org.glassfish.jersey.server.ContainerFilteringStage.apply(ContainerFilteringStage.java:67) 

Co robię źle i jak mogę to naprawić?

UPDATE: W tym pom entried dla Jetty i Jersey

<properties> 
     <jersey.version>2.15</jersey.version> 
     <jetty.version>9.2.6.v20141205</jetty.version> 
    </properties> 

    <!-- Jersey --> 
    <dependency> 
     <groupId>org.glassfish.jersey.containers</groupId> 
     <artifactId>jersey-container-servlet</artifactId> 
     <version>${jersey.version}</version> 
    </dependency> 
    <dependency> 
     <groupId>org.glassfish.jersey.media</groupId> 
     <artifactId>jersey-media-json-jackson</artifactId> 
     <version>${jersey.version}</version> 
    </dependency> 
    <dependency> 
     <groupId>org.glassfish.jersey</groupId> 
     <artifactId>jersey-bom</artifactId> 
     <version>${jersey.version}</version> 
     <type>pom</type> 
     <scope>compile</scope> 
    </dependency> 

    <!-- Jetty --> 
    <dependency> 
     <groupId>org.eclipse.jetty</groupId> 
     <artifactId>jetty-server</artifactId> 
     <version>${jetty.version}</version> 
    </dependency> 
    <dependency> 
     <groupId>org.eclipse.jetty</groupId> 
     <artifactId>jetty-servlet</artifactId> 
     <version>${jetty.version}</version> 
    </dependency> 
    <dependency> 
     <groupId>org.eclipse.jetty</groupId> 
     <artifactId>jetty-servlets</artifactId> 
     <version>${jetty.version}</version> 
    </dependency> 
+0

Jestem prawie pewien, że zadziała, ponieważ ten problem nie jest zgłaszany w takich okolicznościach. Czy spojrzałeś na githuba? Jego wyjątkowo boskie kości. Jasne, czy to Jetty, czy Jersey, albo kombinacja tych dwóch ma błąd w tym przypadku. Ta nagroda polega na znalezieniu rozwiązania, które nie wymaga czekania na reakcję żadnej z grup. Pewnie, jednym rozwiązaniem jest całkowite opuszczenie Jetty, ale wolałbym tego nie robić. –

Odpowiedz

12

Błędem było to, że ręcznie tworzone instancję ExampleRequestLoggingFilter wewnątrz ExampleRequestFilterProvider. Wstrzyknięcie zależności działa tylko w instancjach utworzonych i zarządzanych przez sam kontener, takich jak ExampleRequestFilterProvider. To wyjaśnia, dlaczego wstrzyknięcie @Context nie działa w ręcznie utworzonej instancji.

Rozwiązaniem byłoby przesunięcie punktu wtrysku do ExampleRequestFilterProvider, a następnie przekazanie go do konstruktora z ExampleRequestLoggingFilter.

Przetestowałem to tutaj (uznanie dla projektu Git!) I zadziałało dla mnie.

Zauważ, że tutaj nie przekazujesz rzeczywistej instancji HttpServletRequest, ale serwer zarządzany przez kontener, który deleguje dalej do rzeczywistej instancji przy każdym wywołaniu metody, więc nie ma się czym martwić integralnością i wątkami tutaj.

+0

Bam, w ten sposób ... Dzięki człowieku, to naprawdę pomogło. Najwyraźniej muszę opublikować książki o tym, jak te rzeczy działają lepiej. Mogę nagrodzić nagrodę dopiero za 22 godziny, ale zrobię to. Dzięki wielkie. –

+1

Nie ma za co. Nie spiesz się z nagrodą. Możesz nawet pozostawić to otwarte, dopóki nie wygaśnie (i zostanie automatycznie nagrodzone). Zwiększa to szansę na uzyskanie upvotes od osób przeglądających pytania o nagrodę (dzięki czemu można uzyskać rep), szczególnie w przeddzień wygaśnięcia. – BalusC

+0

Brzmi świetnie, zrobi. Twoje zdrowie. –