2013-09-05 13 views
7

Buduję usługę Jersey Moxy za pomocą archetypu szybkiego startu na końcu. Mój kod działa poprawnie i mogę uzyskać zwrot JSON. Jednak w miarę jak się rozwijam, jeśli popełnię błąd, powiedz, że moduł obsługi żądań ma nieobsługiwany typ, otrzymam pustą odpowiedź 500, co utrudnia debugowanie. Na przykład, jeśli ozdobić atrybut nieprawidłowo z @XmlElementRef, dostanę odpowiedź w stylu:Grizzly Jersey przełknięcie wyjątków

$ curl -i http://localhost:8080/myapp/test 
HTTP/1.1 500 Internal Server Error 
Date: Thu, 05 Sep 2013 10:27:55 GMT 
Connection: close 
Content-Length: 0 

Serwer będzie działać tak, jakby nic nie jest źle:

Sep 5, 2013 11:27:46 AM org.glassfish.grizzly.http.server.HttpServer start 
INFO: [HttpServer] Started. 
Jersey app started with WADL available at http://localhost:8080/application.wadl 
Hit enter to stop it... 

Próbowałem przy użyciu config dziennika file with:

-Djava.util.logging.config.file=log.conf 

Daje to dużą wydajność, ale nadal nie wykazuje żadnego wyjątku.

Próbowałem zaglądać do konfiguracji Grizzly, ale nie mogę znaleźć sposobu na wyłączenie płynnej obsługi błędów. Idealnie chciałbym, aby serwer rzucił wyjątek. Jakieś sugestie co do tego, czego mi brakuje?

Tu jest mój główny kod:

import org.glassfish.grizzly.http.server.HttpServer; 
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory; 
import org.glassfish.jersey.moxy.json.MoxyJsonConfig; 
import org.glassfish.jersey.server.ResourceConfig; 

import javax.ws.rs.ext.ContextResolver; 
import javax.ws.rs.ext.Provider; 

import java.io.IOException; 
import java.net.URI; 
import java.util.*; 

public class Main { 
    // Base URI the Grizzly HTTP server will listen on 
    public static final String BASE_URI = "http://localhost:8080/"; 

    /** 
    * Starts Grizzly HTTP server exposing JAX-RS resources defined in this application. 
    * @return Grizzly HTTP server. 
    */ 
    public static HttpServer startServer() { 
     // create a resource config that scans for JAX-RS resources and providers 
     // in com.myapp package 
     final ResourceConfig rc = new ResourceConfig().packages("com.myapp").registerInstances(new JsonMoxyConfigurationContextResolver()); 

     // create and start a new instance of grizzly http server 
     // exposing the Jersey application at BASE_URI 
     return GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI), rc); 
    } 

    /** 
    * Main method. 
    * @param args 
    * @throws IOException 
    */ 
    public static void main(String[] args) throws IOException { 
     final HttpServer server = startServer(); 
     System.out.println(String.format("Jersey app started with WADL available at " 
       + "%sapplication.wadl\nHit enter to stop it...", BASE_URI)); 
     System.in.read(); 
     server.stop(); 
    } 

    @Provider 
    final static class JsonMoxyConfigurationContextResolver implements ContextResolver<MoxyJsonConfig> { 

     @Override 
     public MoxyJsonConfig getContext(Class<?> objectType) { 
      final MoxyJsonConfig configuration = new MoxyJsonConfig(); 

      Map<String, String> namespacePrefixMapper = new HashMap<String, String>(1); 
      namespacePrefixMapper.put("http://www.w3.org/2001/XMLSchema-instance", "xsi"); 

      configuration.setNamespacePrefixMapper(namespacePrefixMapper); 
      configuration.setNamespaceSeparator(':'); 

      return configuration; 
     } 
    } 
} 

Kod jest niemal identyczny jak przykład tutaj:

https://github.com/jersey/jersey/tree/2.2/examples/json-moxy/src/main/java/org/glassfish/jersey/examples/jsonmoxy

Pełna generacji archetyp użyłem:

mvn archetype:generate -DarchetypeArtifactId=jersey-quickstart-grizzly2 \ 
-DarchetypeGroupId=org.glassfish.jersey.archetypes -DinteractiveMode=false \ 
-DgroupId=com.myapp -DartifactId=yarese-service -Dpackage=com.myapp \ 
-DarchetypeVersion=2.2 

Sugestie podziękowaniem Odebrane.

+0

„... gdybym ozdobić atrybut nieprawidłowo z @XmlElementRef ...” Miałem ten sam problem. Nawet jeśli rejestracja została zakończona, nie otrzymałem żadnych informacji o tym, co było nie tak z adnotacjami JAXB. Otworzyłem [ten wydawanie Jersey] (https://java.net/jira/browse/JERSEY-2321). –

Odpowiedz

12

Wyjątek nie jest przenoszony do warstwy Grizzly, więc powinien być zalogowany przez Jersey. Nie znalazłem rodzaju Logger, który musisz włączyć, ale wygląda na to, że niestandardowy ExceptionMapper może pomóc.

import javax.ws.rs.WebApplicationException; 
import javax.ws.rs.core.Response; 
import javax.ws.rs.ext.ExceptionMapper; 
import javax.ws.rs.ext.Provider; 
import org.glassfish.grizzly.utils.Exceptions; 

@Provider 
public class MyExceptionMapper implements 
     ExceptionMapper<WebApplicationException> { 
    @Override 
    public Response toResponse(WebApplicationException ex) { 
     return Response.status(500).entity(Exceptions.getStackTraceAsString(ex)).type("text/plain") 
       .build(); 
    } 
} 
+1

Użyłem tego podejścia i odkryłem, że działa całkiem dobrze. Jest to omówione również w http://stackoverflow.com/questions/19621653/how-should-i-loglog-uncaught-exceptions-in-my-restful-jax-rs-web-service – emas

+2

Dodałem dodatkową 'ExceptionMapper' dla 'Wyjątku' jako catch-all. W moim scenariuszu 'RuntimeException's gdzie utracone, a teraz mogę je zalogować i kontrolować dane wyjściowe. – Hank

1

Jak widzieliście, Grizzly używa java.util.logging. Jeśli chcesz zobaczyć stacktrace, musisz upewnić się, że poziomy są poprawnie ustawione w twoim pliku log.conf.

Oto ustawienia, które pracowały dla mnie w przeszłości:

handlers=java.util.logging.ConsoleHandler 
java.util.logging.ConsoleHandler.level=ALL 
.level=ALL 
org.glassfish.level=CONFIG 
+0

Potrzebowałem zmienić 'org.glassfish.level = CONFIG' na' org.glassfish.level = ALL', aby uzyskać wszystkie wyjątki. – zpon