2016-11-07 53 views
7

工作,我有以下的資源,消耗了JSON映射到一個POJO。定製ExceptionMapper澤西島不是無效的JSON輸入

@Path("example") 
public class ExampleResource { 

    @POST 
    @Consumes(MediaType.APPLICATION_JSON) 
    public Response addThesis(MyObject myObject) { 
     return Response.ok().entity("Test").build(); 
    } 
} 

這裏的POJO類:

public class MyObject { 
    private String title; 

    public String getTitle() { 
     return title; 
    } 

    public void setTitle(String title) { 
     this.title = title; 
    } 
} 

當我送與身體{ 「稱號」: 「測試題」} POST請求一切工作正常。響應是測試,符合市場預期。然而,當我改變請求{「titlee」:「測試題」}服務器與此回覆:

無法識別的領域「titlee」(類com.my.package.MyObject),沒有標明爲可忽略(一種已知的屬性: 「標題」]) 在[來源:org.glassfish.jersey.me[email protected]6dc6a46a;行:2,柱:11](通過參考鏈:com.my.package.MyObject [ 「titlee」])

顯然,這是拋出由新澤西返回異常。我如何攔截這個異常並返回一個自定義的狀態碼和消息?

我到目前爲止已經試過是實現我自己ExceptionMapper:

@Provider 
public class MyJsonExceptionMapper implements ExceptionMapper<JsonProcessingException> { 
    public Response toResponse(JsonProcessingException e) { 
     return Response.status(400).entity("JSON Processing Error").build(); 
    } 
} 

不幸的是,響應保持不變。當我爲自定義異常實現一個ExceptionMapper並在資源方法中拋出相應的異常時,一切正常。我認爲這與JsonProcessingException的默認ExceptionMapper重寫我自己的。然後我試圖創建一個通用映射器(「實現ExceptionMapper」),但再次沒有成功。

我看着幾乎無處不在,並嘗試了很多事情,包括擴大ResourceConfig和註冊我的映射,但至今沒有奏效。

一些詳細信息,這可能有助於縮小問題了下來:我使用Grizzly2作爲我部署作爲脂肪JAR HTTP服務器。

我的pom.xml的依賴部分看起來是這樣的:

<dependencies> 
    <dependency> 
     <groupId>org.glassfish.jersey.media</groupId> 
     <artifactId>jersey-media-json-jackson</artifactId> 
     <version>2.24</version> 
    </dependency> 
    <dependency> 
     <groupId>org.glassfish.jersey.containers</groupId> 
     <artifactId>jersey-container-grizzly2-http</artifactId> 
     <version>2.24</version> 
    </dependency> 
</dependencies> 

任何意見表示高度讚賞。

+0

從我記得我認爲實現了JsonMappingException和JsonParseException一個映射,則應該重寫默認的。我不太確定如何禁用它們。 –

+0

爲'Throwable'實現映射器應該覆蓋/所有/現有的映射器。但它似乎並不奏效。在ResourceConfig中也不會調用'ExceptionMapper '顯式。 – BadZen

+0

(也實現'ExtendedExceptionMapper'的文檔也建議不工作...) – BadZen

回答

5

好吧,這是愚蠢和黑客十歲上下,但爲我工作:

register(JacksonJaxbJsonProvider.class);

這是由於在傑克遜功能入口點下面的「漂亮的默認行爲」:

if (!config.isRegistered(JacksonJaxbJsonProvider.class)) { // add the default Jackson exception mappers context.register(JsonParseExceptionMapper.class); context.register(JsonMappingExceptionMapper.class);

:(

但是,我還是更喜歡解決問題「爲REA答案我「 - 即。無需預先註冊組件,以便該功能無法正確配置它們......

+0

(讓這些擴展映射器可以拒絕一個例外,它發送到默認的映射器...) – BadZen

0

我們用Wildfly JAX-RS來實現我們的網絡服務,並使用以下命令來完成你正在嘗試在Glassfish與澤西做。也許它有類似的功能,你可以查找。我們的步驟是:

  • 該服務是一個無狀態的EJB,使用EJB攔截器來捕獲異常 和填充請求範圍,詳情
  • 實現一個PostProcessInterceptor從請求範圍的對象讀取和修改的服務回報之前響應對象。 (這是特定於JAX-RS)
2

我也面臨這個問題。如果JacksonFeature被註冊,您可以簡單地註冊JacksonJaxbJsonProvider作爲一種解決方法。


JacksonFeature在類路徑中,它會自動通過澤西發現。另一種方法來解決它通過設置ServerProperties.FEATURE_AUTO_DISCOVERY_DISABLEtrue禁用自動發現。因此,您需要手動註冊其他功能。


或者你可以擺脫jersey-media-json-jackson神器和使用jackson-jaxrs-json-provider來代替。有了這個,你將擺脫JacksonFeature然後你可以註冊你自己的異常映射器。


最後一個選項,大概是什麼似乎是正確的解決(如Kysil伊萬的answer指出),你可以寫自己的異常映射,然後給它一個高優先級,如1。如果您使用自動發現,只是@Provider@Priority標註爲:

@Provider 
@Priority(1) 
public class JsonParseExceptionMapper implements ExceptionMapper<JsonParseException> { 
    ... 
} 

如果您手動註冊供應商,您可以give your provider a binding priority

@ApplicationPath("/") 
public class MyResourceConfig extends ResourceConfig { 

    public MyResourceConfig() { 
     register(JsonParseExceptionMapper.class, 1); 
    } 
} 

有關詳細信息,請參閱本answer