2013-09-05 96 views
7

Tôi đang xây dựng một dịch vụ Jersey Moxy bằng cách sử dụng kiểu mẫu nhanh ở cuối. Mã của tôi hoạt động tốt và tôi có thể nhận được một số JSON trả về. Tuy nhiên khi tôi đang phát triển, nếu tôi mắc lỗi, nói rằng trình xử lý yêu cầu có loại không được hỗ trợ, tôi sẽ nhận được một phản hồi 500 trống, điều này làm cho việc gỡ lỗi trở nên khó khăn. Ví dụ, nếu tôi trang trí một thuộc tính không đúng với @XmlElementRef, tôi sẽ nhận được một câu trả lời như:Grizzly Jersey nuốt ngoại lệ

$ 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 

Các máy chủ sẽ hoạt động như nếu không có gì là sai:

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... 

Tôi đã cố gắng sử dụng một cấu hình đăng nhập tệp với:

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

Điều này tạo ra nhiều đầu ra, nhưng vẫn không hiển thị bất kỳ loại ngoại lệ nào.

Tôi đã thử tìm kiếm trong cấu hình Grizzly nhưng tôi không thể tìm thấy cách tắt xử lý lỗi duyên dáng. Lý tưởng nhất là tôi muốn máy chủ ném một ngoại lệ. Bất kỳ đề xuất về những gì tôi đang mất tích?

Dưới đây là code chính của tôi:

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

Mã này là gần như giống hệt với ví dụ ở đây:

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

Full thế hệ nguyên mẫu tôi đã sử dụng:

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 

Gợi ý biết ơn nhận.

+0

"... nếu tôi trang trí một thuộc tính không đúng với @XmlElementRef ..." Tôi đã có cùng một vấn đề. Ngay cả khi đăng nhập được bật lên, tôi không nhận được bất kỳ thông tin nào về chính xác những gì đã xảy ra với chú thích JAXB của tôi. Tôi đã mở [vấn đề Jersey này] (https://java.net/jira/browse/JERSEY-2321). –

Trả lời

12

Ngoại lệ không được truyền sang lớp Grizzly, vì vậy nó phải được ghi bởi Jersey. Tôi đã không tìm thấy những loại Logger bạn phải kích hoạt, nhưng trông giống như tùy chỉnh ExceptionMapper có thể giúp đỡ.

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

Tôi đã sử dụng cách tiếp cận này và tôi thấy rằng nó hoạt động khá tốt. Điều này cũng được thảo luận trong http://stackoverflow.com/questions/19621653/how-should-i-log-uncaught-exceptions-in-my-restful-jax-rs-web-service – emas

+2

Tôi đã thêm một 'ExceptionMapper' bổ sung cho 'Ngoại lệ' như là một trò chơi bắt kịp. Trong kịch bản của tôi 'RuntimeException' nơi bị mất, và bây giờ tôi có thể đăng nhập và kiểm soát đầu ra. – Hank

1

Như bạn đã thấy, Grizzly sử dụng java.util.logging. Nếu bạn muốn xem stacktrace, bạn cần đảm bảo các cấp được đặt chính xác trong tệp log.conf của bạn.

Dưới đây là các thiết lập đã làm việc cho tôi trong quá khứ:

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

Tôi cần thay đổi 'org.glassfish.level = CONFIG' thành' org.glassfish.level = ALL' để nhận tất cả ngoại lệ. – zpon