2013-04-02 18 views
7

Sto cercando di ottenere alcuni contesti iniettati (ad esempio Session o HttpServletRequest) in un servlet che ho scritto, in esecuzione su Grizzly, ma niente di ciò che faccio sembra funzionare. L'intero processo sembra stallo piuttosto prematuramente con il seguente errore:Grizzly e ServletContainerContext

SEVERE: Missing dependency for field: javax.servlet.http.HttpServletRequest com.test.server.LolCat.hsr 

il server è morto semplice, si compone di due file, il punto di ingresso statico (Main.java):

package com.test.server; 

import java.io.IOException; 
import java.net.URI; 
import javax.ws.rs.core.UriBuilder; 

import org.glassfish.grizzly.http.server.HttpServer; 
import com.sun.jersey.api.container.grizzly2.GrizzlyServerFactory; 
import com.sun.jersey.api.core.ClassNamesResourceConfig; 
import com.sun.jersey.api.core.ResourceConfig; 

public class Main { 

    private static URI getBaseURI() { 
     return UriBuilder.fromUri("http://localhost/").port(8080).build(); 
    } 

    public static final URI BASE_URI = getBaseURI(); 

    public static void main(String[] args) throws IOException { 
     ResourceConfig rc = new ClassNamesResourceConfig(LolCat.class); 
     HttpServer httpServer = GrizzlyServerFactory.createHttpServer(BASE_URI, rc); 
     System.in.read(); 
     httpServer.stop(); 
    } 
} 

e il serlvet (LolCat.java):

package com.test.server; 

import javax.servlet.http.HttpServletRequest; 
import javax.ws.rs.GET; 
import javax.ws.rs.Path; 
import javax.ws.rs.core.Context; 

@Path(value = "/lol") 
public class LolCat { 

    @Context HttpServletRequest hsr; 

    @GET 
    @Path(value="/cat") 
    public String list() { 
     return "meow"; 
    } 

} 

in particolare, è il contesto della riga @ nel file di origine sopra che è la fonte e la soluzione a tutti i miei problemi. Ne ho bisogno, e secondo tutto quello che ho letto su Jersey e Servlets dovrebbe funzionare, ma purtroppo no. Ho anche provato a utilizzare GrizzlyWebContainerFactory invece di GrizzlyServerFactory, ma senza risultato.

Per riferimento, il progetto viene compilato con le seguenti dipendenze:

  • org.glassfish.grizzly: grigio-quadro: jar: 2.2.21
  • org.glassfish.grizzly: grigio-http: jar: 2.2.21
  • org.glassfish.grizzly: grizzly-http-servlet: jar: 2.2.21
  • org.glassfish.grizzly: grizzly-http-server: jar: 2.2.21
  • com. sun.jersey: jersey-server: jar: 1.17
  • com.sun.jersey: jersey-servlet: jar: 1.17
  • com.sun.jersey: jersey-core: jar: 1.17
  • javax.servlet: javax.servlet-api: jar: 2.5.0
  • com.sun.jersey: jersey-grizzly2: jar: 1.17
  • com.sun.jersey: jersey-grizzly2-servlet: jar: 1.17
  • asm: asm: vaso: 3.3.1

risposta

3

Questa classe principale funziona bene per me:

package com.test.server; 

import com.sun.jersey.api.container.grizzly2.GrizzlyServerFactory; 
import java.io.IOException; 
import java.net.URI; 
import javax.ws.rs.core.UriBuilder; 

import com.sun.jersey.api.core.ClassNamesResourceConfig; 
import com.sun.jersey.spi.container.servlet.ServletContainer; 
import org.glassfish.grizzly.http.server.HttpHandler; 
import org.glassfish.grizzly.http.server.HttpServer; 
import org.glassfish.grizzly.http.server.Request; 
import org.glassfish.grizzly.http.server.Response; 
import org.glassfish.grizzly.servlet.ServletRegistration; 
import org.glassfish.grizzly.servlet.WebappContext; 

public class Main { 
    private static final String JERSEY_SERVLET_CONTEXT_PATH = ""; 

    private static URI getBaseURI() { 
     return UriBuilder.fromUri("http://localhost").port(8080).path("/").build(); 
    } 

    public static final URI BASE_URI = getBaseURI(); 

    public static void main(String[] args) throws IOException { 
     // Create HttpServer and register dummy "not found" HttpHandler 
     HttpServer httpServer = GrizzlyServerFactory.createHttpServer(BASE_URI, new HttpHandler() { 

      @Override 
      public void service(Request rqst, Response rspns) throws Exception { 
       rspns.setStatus(404, "Not found"); 
       rspns.getWriter().write("404: not found"); 
      } 
     }); 

     // Initialize and register Jersey Servlet 
     WebappContext context = new WebappContext("WebappContext", JERSEY_SERVLET_CONTEXT_PATH); 
     ServletRegistration registration = context.addServlet("ServletContainer", ServletContainer.class); 
     registration.setInitParameter(ServletContainer.RESOURCE_CONFIG_CLASS, 
       ClassNamesResourceConfig.class.getName()); 
     registration.setInitParameter(ClassNamesResourceConfig.PROPERTY_CLASSNAMES, LolCat.class.getName()); 
     registration.addMapping("/*"); 
     context.deploy(httpServer); 

     System.in.read(); 
     httpServer.stop(); 
    } 
} 

Prova http://localhost:8080/lol/cat nel tuo browser. È possibile modificare JERSEY_SERVLET_CONTEXT_PATH per aggiornare il percorso di contesto di Servlet.

+0

Ha funzionato, con il tipo sicurezza di testo in chiaro :). È possibile registrare una classe senza utilizzare setInitParameter String/String? – Mic

+0

Penso che la GrizzlyWebContainerFactory di Jersey potrebbe essere estesa/migliorata, quindi non avresti bisogno di gestire i parametri di init, ma in ogni caso sarà un wrapper sullo stesso codice di registrazione di WebappContext. – alexey

+0

Help! .. Il mio codice arriva fino a 'WebappContext context = new WebappContext (...' poi si blocca improvvisamente con 'Exception in thread" main "java.lang.NoSuchMethodError: org.glassfish.grizzly.utils.DataStructures. getConcurrentMap (IFI) Ljava/util/concurrent/ConcurrentMap; '. Provato con Java 7 e 8, utilizzando jersey-container-grizzly-http: 2.5 e jersey-container-grizzly2-servlet: 2.5 –

4

Secondo le spiegazioni degli sviluppatori - Grizzly non è completamente compatibile con JAX-RS 2.0 quindi non ci saranno iniezioni/involucri di contesti ufficiali. Vedi Jersey Bug-1960 Applicabile per Jersey + Grizzly versione 2.7+

Fortunatamente esiste un modo per iniettare oggetti di richiesta/risposta di Grizzly. Un po 'complicato ma funziona Esempio di codice fornito in uno dei test unitari di Jersey.Vedere Jersey container test

Così frammento di codice sarà:

import javax.inject.Inject; 
import javax.inject.Provider; 

public someclass { 
    @Inject 
    private Provider<Request> grizzlyRequestProvider; 

    public void method() { 
     if (grizzlyRequestProvider != null) { 
      Request httpRequest = grizzlyRequestProvider.get(); 

      // Extract what you need 
     } 
    } 
} 

funziona bene sia per i filtri e metodi di servizio

1

È possibile anche registrare manualmente un ResourceContext

HttpServer httpServer = GrizzlyHttpServerFactory.createHttpServer(getBaseURI()); 

    WebappContext context = new WebappContext("WebappContext", "/api"); 
    ServletRegistration registration = context.addServlet("ServletContainer", 
    new ServletContainer(config)); 
    registration.addMapping("/*"); 
    context.deploy(httpServer); 

Dove config è la risorsa contesto.

Problemi correlati