2014-05-03 48 views
2

我有一個@GET方法,用@Produces(MediaType.APPLICATION_JSON)進行註釋。當我禁用Jersey中的JSON處理時,我希望看到調用失敗,但無論我做什麼,當我在瀏覽器中訪問該URL方法時,都會繼續生成JSON輸出。如何禁用Jersey的JacksonJsonProvider自動註冊,所以我用我自己的?

當我在com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider的構造函數中放置一個斷點時,我發現它在MessageBodyFactory被實例化時正在註冊。尤其是,線下:

final Set<MessageBodyReader> mbrs = Providers.getProviders(locator, MessageBodyReader.class); 

JacksonJsonProvider即使我禁用所有自動發現發現。因此我不能註冊我自己提供的自定義ObjectMapper。默認的一個總是用來代替。

的方法是這樣的:

​​

在我的申請,我做什麼,我認爲是正確的(甚至是矯枉過正)配置:

public class CustomResourceConfig extends ResourceConfig { 

public CustomResourceConfig() { 

property(CommonProperties.METAINF_SERVICES_LOOKUP_DISABLE, true); 
property(CommonProperties.FEATURE_AUTO_DISCOVERY_DISABLE, true); 
property(CommonProperties.JSON_PROCESSING_FEATURE_DISABLE, true); 
property(CommonProperties.MOXY_JSON_FEATURE_DISABLE, true); 

property(ServerProperties.METAINF_SERVICES_LOOKUP_DISABLE, true); 
property(ServerProperties.FEATURE_AUTO_DISCOVERY_DISABLE, true); 
property(ServerProperties.MOXY_JSON_FEATURE_DISABLE, true); 
property(ServerProperties.JSON_PROCESSING_FEATURE_DISABLE, true); 

property(ClientProperties.FEATURE_AUTO_DISCOVERY_DISABLE, true); 
property(ClientProperties.METAINF_SERVICES_LOOKUP_DISABLE, true); 
property(ClientProperties.JSON_PROCESSING_FEATURE_DISABLE, true); 

packages("test.package.api"); 
} 
} 

我已經把下面CONFIGS在web.xml中:

<servlet> 
    <servlet-name>jersey-servlet</servlet-name> 
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> 

    <init-param> 
     <param-name>jersey.config.server.tracing</param-name> 
     <param-value>ALL</param-value> 
    </init-param> 
    <init-param> 
     <param-name>jersey.config.disableMetainfServicesLookup</param-name> 
     <param-value>1</param-value> 
    </init-param> 

    <init-param> 
     <param-name>jersey.config.disableJsonProcessing</param-name> 
     <param-value>1</param-value> 
    </init-param> 
    <init-param> 
     <param-name>jersey.config.disableMoxyJson</param-name> 
     <param-value>1</param-value> 
    </init-param> 

    <init-param> 
     <param-name>javax.ws.rs.Application</param-name> 
     <param-value>com.specktro.orchid.deployment.registry.CustomResourceConfig</param-value> 
    </init-param> 
    <load-on-startup>1</load-on-startup> 
</servlet> 

我的pom.xml包含以下依賴關係:

<dependency> 
     <groupId>org.glassfish.jersey.containers</groupId> 
     <artifactId>jersey-container-servlet</artifactId> 
    </dependency> 
    <dependency> 
     <groupId>org.glassfish.jersey.core</groupId> 
     <artifactId>jersey-server</artifactId> 
    </dependency> 
    <dependency> 
     <groupId>org.glassfish.jersey.core</groupId> 
     <artifactId>jersey-common</artifactId> 
    </dependency> 
    <dependency> 
     <groupId>log4j</groupId> 
     <artifactId>log4j</artifactId> 
    </dependency> 
    <dependency> 
     <groupId>com.fasterxml.jackson.jaxrs</groupId> 
     <artifactId>jackson-jaxrs-json-provider</artifactId> 
    </dependency> 

版本是由父POM管理,但我需要使用傑克遜2.3.2,和我使用的澤西2.7(也試圖與2.6,相同的結果)。

我也試着註冊JacksonJaxbJsonProvider它用我的對象映射:

register(new JacksonJaxbJsonProvider(objectMapper, null)); 

但將導致兩個JacksonJsonProviders註冊地:一個是我的JacksonJaxbJsonProvider和一個澤西初始化期間寄存器和一個被使用,因此我的是忽略。

我怎樣才能讓澤西使用我的JacksonJsonProvider而不是默認的,所以我可以提供我自己的ObjectMapper

UPDATE 當然我也嘗試創建一個自定義的ContextResolver,提供了一個自定義的ObjectMapper並將其註冊,但它會被忽略。

回答

0

發現問題! 我沒有像通常的人一樣返回一個對象。相反,我被扔WebApplicationException的一個子類,顯示在客戶端的JSON:

public class ApplicationException extends WebApplicationException { 
    private static final long serialVersionUID = 1L; 

    public ApplicationException(int errorCode, String message) { 
     super(Response.status(Response.Status.OK).entity(
        JsonNodeFactory.instance.objectNode() 
        .put("errorCode", errorCode) 
        .put("errorMessage", message).toString()) 
       .type(MediaType.APPLICATION_JSON).build()); 
    } 

} 

和在新澤西州的一個問題...當新澤西州處理這個例外,它不使用正確的JSON提供...相反,它註冊一個默認的沒有我的自定義設置,也不會查詢我註冊的ContextResolver導致一個未格式化的JSON(我在我的ObjectMapper打開漂亮的打印)。

我在JIRA開了一個錯誤與網隊: https://java.net/jira/browse/JERSEY-2503

我希望這有助於另一個可憐的人試圖處理這種情況。

0

它看起來像這樣會工作。我建立了一個在JerseyConfig中註冊的nop JacksonJsonProvider。以下是我用來製作nop JacksonJsonProvider的代碼:

import java.util.concurrent.atomic.AtomicReference; 
import com.fasterxml.jackson.databind.JavaType; 
import com.fasterxml.jackson.databind.ObjectMapper; 
import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider; 
import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider; 

public class NopJacksonProviderBuilder { 

    public static JacksonJaxbJsonProvider nopJacksonJaxbJsonProvider(){ 
     JacksonJaxbJsonProvider result = new JacksonJaxbJsonProvider(new NopObjectMapper(), null); 
     result.checkCanSerialize(true); 
     result.checkCanDeserialize(true); 
     return result; 
    } 

    public static JacksonJsonProvider nopJacksonJsonProvider(){ 
     JacksonJsonProvider result = new JacksonJsonProvider(new NopObjectMapper(), null); 
     result.checkCanSerialize(true); 
     result.checkCanDeserialize(true); 
     return result; 
    } 

    @SuppressWarnings("serial") 
    private static class NopObjectMapper extends ObjectMapper{ 

     @Override 
     public boolean canDeserialize(JavaType type) { 
      return false; 
     } 

     @Override 
     public boolean canDeserialize(JavaType type, AtomicReference<Throwable> cause){ 
      return false; 
     } 

     @Override 
     public boolean canSerialize(Class<?> type) { 
      return false; 
     } 

     @Override 
     public boolean canSerialize(Class<?> type, AtomicReference<Throwable> cause) { 
      return false; 
     } 

    } 
} 
相關問題