2016-11-07 56 views
7

POJO'ya eşlenen bir JSON'u kullanan aşağıdaki kaynağa sahibim.Jersey için özel ExceptionMapper geçersiz JSON girdisi için çalışmıyor

@Path("example") 
public class ExampleResource { 

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

İşte POJO sınıf var: her şey iyi çalışır:

public class MyObject { 
    private String title; 

    public String getTitle() { 
     return title; 
    } 

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

ben beden { "Test başlığı" "title"} ile bir POST isteği göndermek

. Yanıt, beklendiği gibi Test'dur. Ben { "titlee": "Test başlığı"} isteği değiştirmek Ancak, sunucusu bu cevaplıyor:

Tanınmayan alan "titlee" (sınıf com.my.package.MyObject), işaretlenmemiş [Kaynak: org.glassfish.jersey.me[email protected]6dc6a46a adresindeki no'lu (bilinen bir özellik: "başlık"]); çizgi 2, kolon: 11] (referans zinciri üzerinden: com.my.package.MyObject [ "titlee"])

Açıkçası bu atılır ve Jersey tarafından döndürülen bir istisnadır. Bu özel durumu nasıl engelleyebilir ve özel durum kodu ve iletisini nasıl döndürebilirim?

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

Maalesef yanıt aynı kalır: Şimdiye kadar denedim ne

kendi ExceptionMapper uygulamaktır. Özel bir özel durum için bir ExceptionMapper uyguladığınızda ve kaynak yönteminde karşılık gelen özel durumu attığımda, her şey iyi çalışıyor. Bunun, JsonProcessingException için kendi özelliğimi geçersiz kılan varsayılan ExceptionMapper ile ilgisi olduğunu varsayalım. Sonra genel bir eşleştirici ("ExceptionMapper uygular") oluşturmaya çalıştım, ama yine başarı yok.

Her yerde tam anlamıyla baktım ve ResourceConfig'i genişletmek ve eşleştiricimi kaydetme dahil birçok şeyi denedim, ancak hiçbir şey şu ana kadar işe yaramadı.

Sorunu daraltmaya yardımcı olabilecek bazı daha fazla bilgi: Grizzly2'yi Fat JAR olarak dağıttığım HTTP sunucusu olarak kullanıyorum.

benim pom.xml bağımlılığı kısmı aşağıdaki gibidir:

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

Herhangi bir tavsiye çok takdir edilmektedir.

+0

, varsayılan olanları geçersiz kılar. Onları nasıl devre dışı bırakacağımı tam olarak bilmiyorum. –

+0

"Throwable" için bir eşleştirici uygulamak, geçersiz kılmayı/varolan eşleyicileri geçersiz kılar. Ama işe yaramıyor. ResourceConfig'teki 'ExceptionMapper ' açıklığını yeniden kaydetmiyor. – BadZen

+0

(Ayrıca docs olarak 'ExtendedExceptionMapper' uygulanması ... çalışmıyor da önermek) – BadZen

cevap

5

Tamam, bu aptal ve kesmek-imsi, ama benim için çalıştı:

register(JacksonJaxbJsonProvider.class);

Bu Jackson özellik giriş noktasının aşağıdaki "güzel varsayılan davranış" kaynaklanır:

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

:(

Ama yine de reaktif için sorun" düzeltir bir cevap tercih ediyorum Yalan. Bileşenleri ön kayıt yapmadan, özellik bunları düzgün bir şekilde yapılandıramaz ...

+0

(ve genişletilmiş mapper varsayılan eşleyicisinde göndermek için bir istisna reddedebilirsiniz böylece ...) – BadZen

0

Biz web hizmetleri uygulamak ve GlassFish üzerinde Jersey ile yapmaya çalıştığımız ne gerçekleştirmek için aşağıdakileri kullanmak Wildfly üzerinde JAX-RS kullanırlar. Belki de bakabileceğin benzer özelliklere sahip. Bizim adımlar şunlardır:

  • hizmet ayrıntıları
  • isteği kapsamlı nesneden okur ve hizmet dönmeden önce tepkisini değiştiren bir PostProcessInterceptor uygulamak ile vatansız EJB, kullanım EJB tuzak istisna avcı ve doldurmak isteği kapsamlı bir nesnedir. Ben de bu sorunla karşı karşıya
2

(Bu JAX-RS özgüdür). JacksonFeature kayıtlıysa, sadece geçici bir çözüm olarak JacksonJaxbJsonProvider kaydedebilir. JacksonFeature sınıf yolunda olduğunda


otomatik Jersey tarafından keşfedilir. Diğer bir yaklaşım da true için ServerProperties.FEATURE_AUTO_DISCOVERY_DISABLE ayarlayarak otomatik keşif devre dışı olduğunu saptamak. Bunun sonucunda, diğer özellikleri manuel olarak kaydetmeniz gerekir.


Alternatif jersey-media-json-jackson eser kurtulmak ve yerine jackson-jaxrs-json-provider kullanın. Bununla, JacksonFeature'dan kurtulacaksınız ve daha sonra kendi istisna haritacılarınızı kaydedebilirsiniz.


Son bir seçenek ve muhtemelen neyi böyle 1 olarak, (Kysil Ivan'ın answer sivri gibi) bunu yüksek öncelik vermek sonra kendi istisna mapper yazabilir ve doğru çözüm gibi görünmektedir. Otomatik keşif kullanırsanız, sadece @Provider ve @Priority ile açıklama:

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

el sağlayıcı kayıt varsa, give your provider a binding priority yapabilirsiniz:

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

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

fazla bilgi için bu answer bakınız. Ben JsonMappingException ve JsonParseException için mapper uygulayan düşünüyorum hatırlıyorum kadarıyla