2015-04-30 12 views
9

erhalten, um den vollständigen Code für dieses Problem zu sehen, finden Sie in diesem GithubJersey: ContainerRequestFilter nicht Context ServletRequest

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

ich dieses Jersey Jira auch

erstellt

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

Ich bin Arbeiten an einem ContainerRequestFilter mit Jersey 2.15. Dies ist eine eingebettete Jetty-App, die in einem einzigen Jar schattiert ist.

in der Mole Starter (Hauptklasse):

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(); 
    } 
} 

Ich habe einen Filter, der über einen Provider enthalten ist

@Provider 
public class ExampleProvider implements DynamicFeature { 

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

dann im Filter:

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()); 
     // ... 
    } 

} 

Jedoch dies erzeugt ein 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) 

Was mache ich falsch und wie behebe ich das?

UPDATE: Einschließlich pom entried für Jetty und 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

Ich bin mir ziemlich sicher, dass das funktioniert, da dieses Problem unter diesen Umständen nicht gemeldet wird. Hast du dir den GitHub angeschaut? Seine extrem Barebones. Es ist klar, entweder Jetty oder Jersey oder die Kombination der beiden hat einen Fehler in diesem Fall. Diese Prämie soll eine Lösung finden, die nicht darauf wartet, auf eine der beiden Gruppen zu reagieren. Sicher, eine Lösung besteht darin, Jetty komplett zu entfernen, aber ich würde es lieber nicht tun. –

Antwort

12

Der Fehler war, dass man manuell eine Instanz von ExampleRequestLoggingFilter innerhalb des ExampleRequestFilterProvider erstellt . Die Abhängigkeitseinfügung funktioniert nur für Instanzen, die vom Container selbst erstellt und verwaltet werden, z. B. ExampleRequestFilterProvider. Dies erklärt, warum @Context Injektion in Ihrer manuell erstellten Instanz nicht zu funktionieren scheint.

Eine Lösung wäre, den Injektionspunkt auf ExampleRequestFilterProvider zu verschieben und dann an den Konstruktor ExampleRequestLoggingFilter zu übergeben.

@Provider 
public class ExampleRequestFilterProvider implements DynamicFeature { 

    @Context 
    private HttpServletRequest request; 

    @Override 
    public void configure(ResourceInfo resourceInfo, FeatureContext featureContext) { 
     ExampleRequestLoggingFilter exampleRequestLoggingFilter = new ExampleRequestLoggingFilter(request); 
     featureContext.register(exampleRequestLoggingFilter); 
    } 

} 

Getestet habe ich es hier (ein dickes Lob an das Git-Projekt!) Und es für mich gearbeitet.

Beachten Sie, dass Sie hier nicht die tatsächliche HttpServletRequest Instanz übergeben, sondern einen containerverwalteten Proxy, der bei jedem Methodenaufruf weiter an die tatsächliche Instanz delegiert, sodass Sie sich hier keine Gedanken über Integrität und Threadsicherheit machen müssen.

+0

Bam, so ... Danke Mann, das hat wirklich geholfen. Klar muss ich die Bücher darüber schlagen, wie dieses Zeug besser funktioniert. Ich kann nur in 22 Stunden Kopfgeld geben, aber ich werde es tun. Vielen Dank. –

+1

Gern geschehen. Keine Eile mit dem Kopfgeld. Sie können es sogar offen lassen, bis es abläuft (und automatisch vergeben wird). Dies erhöht die Chance, Ups von Leuten zu bekommen, die die Bounty-Fragen durchstöbern (damit Sie die Rep zurück verdienen können), insbesondere während des Tages bevor sie ablaufen. – BalusC

+0

Klingt gut, wird es tun. Prost. –