2016-07-31 17 views
8

私のプロジェクトの1つでは、すでにJerseyをバージョン2.14から2.23にアップグレードしました。しかし、私は1つの問題で何時間も苦労しています。私のプロジェクトではValidationExceptionのためにExceptionMapperが定義されていますが、残念ながらJerseyには既にこの例外のための組み込みの例外マッパーがあります。Jersey 2.23の組み込み例外マッパーをオーバーライドする方法は?

私は(私はそれをチェックする)、以下に提示され、私自身マッパー正しく登録されています:

@Provider 
public class ValidationExceptionMapper implements 
     ExceptionMapper<ValidationException> { 

    @Override 
    public Response toResponse(ValidationException exception) { 
     return Response.status(Status.BAD_REQUEST).build(); 
    } 
} 

それが呼び出されませんさん。ジャージーはいつもorg.glassfish.jersey.server.validation.internal.ValidationExceptionMapperを拾う。 カスタムマッパーにも@Priority注釈を使用しようとしましたが、残念ながらJerseyでは考慮していません。

何が起こっているのですか?以前のJerseyバージョンでは正常に動作していたので、回帰バグのようです。

私はあきらめます。すべての手がかりは?

+0

回避策として「ConstraintViolationException」(検証例外の実際のタイプ)を使用できます。これは 'ValidationException'よりも具体的であるため、優先されます。 _all_ meta-infプロバイダーを無効にしなくても(楽しい解決策ではなく)、その1つのマッパーを無効にする方法は決して分かりませんでした。私の回避策は、単にConstraintViolationExceptionのマッパーを使用することでした。 –

+0

ありがとう、私は知っていますが、これでは問題はまったく解決されません。アプリケーションは 'ValidationException'に応答する必要があるためです。 –

+0

'ConstraintViolationException'は' ValidationException'を拡張しています。 JerseyのBean検証でスローされる例外の型は、常にConstraintViolationExceptionです。スーパータイプのマッパーはサブタイプの例外を処理できるので、サブタイプのマッパーはありません –

答えて

4

それは本当にバグが2つのジャージーの拡張子を持つ関連のある

1月2015年に導入され、ジャージーでの回帰バグであることが判明:溶接と豆の検証のために。 Weldコンテナが起動していないので、私のカスタム ValidationExceptionMapperマッパーが、 jersey-bean-validationモジュールが提供する組み込みのものよりも優先されるので、私の目標が達成されます。

私はJERSEY-3153のバグレポートに記入しました。

Weld + Jerseyをもう一度使用するつもりはありません...私はこの組み合わせに疲れています。過去2年間、すでに約10個のバグがありました。本当に疲れた。

とにかく、誰かを助けてくれることを願っています。

更新: @Justin Joseが以下のコメントに気づいたように、上記のバグの回避策もあります。私たちは、内蔵のマッパー問題を上書きするために、HK2バインディングを使用することができます。

register(new AbstractBinder() { 
    @Override 
    protected void configure() { 
     bind(my.custom.ValidationExceptionMapper.class).to(ExceptionMapper.class) 
       .in(Singleton.class); 
    } 
}); 
0

私はそれが新しいジャージーで動作するように取得する方法は、私はまた、あなたのバグレポートの下に掲示され、再び解放しました。

変更されたコードをローカルに構築する必要があります。具体的にはjersey-bean-validationアーティファクトです。

org.glassfish.jersey.server.validation.internal.ValidationBinderを見つけて、configure()に以下の2行をコメントアウト:

bind(ValidationExceptionMapper.class).to(ExceptionMapper.class).in(Singleton.class); 
bind(ValidationErrorMessageBodyWriter.class).to(MessageBodyWriter.class).in(Singleton.class); 

それはそれらのライン上のソースコードのコメントは、彼らは、ユーザーが自分のプロバイダを登録できるようになっていると言うことを一種の皮肉です。

+0

Heinさん、ありがとうございます。しかし、私は最後の手段としてライブラリにパッチを当てることを検討します... –

4

Jerseyの組み込みValidationExceptionMapperは、ValidationFeatureを介して登録されています。おそらく、JerseyのValidationFeatureをあなた自身のバージョンに置き換えることは、このトリックを行うことができます。それは以下のように行うことができます。

はまず、あなたがあなたの新しいExceptionMapperを指定する必要があり、自動発見ValidationFeature

property(ServerProperties.BV_FEATURE_DISABLE, true); 

次のステップは、クローンでジャージーの検証機能

public static class ValidationFeatureClone implements Feature { 

    @Override 
    public boolean configure(FeatureContext context) { 
     context.register(new ValidationBinder()); 
     context.register(NewValidationExceptionMapper.class); 
     context.register(ValidationErrorMessageBodyWriter.class); 
     return true; 
    } 
} 

のクローンを登録することで無効にします。

最後に、あなたの新しいフィーチャーを登録

register(ValidationFeatureClone.class) 

UPDATE:以降ジャージー2.20から

以下に示すように、デフォルトValidationExceptionMapperは結合HK2を使用して上書きすることができます。

register(new AbstractBinder() { 
@Override 
protected void configure() { 
    bind(NewValidationExceptionMapper.class).to(ExceptionMapper.class) 
      .in(Singleton.class).ranked(10‌​); 
} 

});

+0

解決策をもう一度確認してください。私はJersey 2.23.1でそれを数分前にチェックしており、元の問題はまったく解決しません。それ以外に、 'ValidationErrorMessageBodyWriter'は公的に利用可能なクラスではありません。 –

+0

私はアプリケーションでJersey 2.19を使用しており、このソリューションは私たちのために働いています。それは2.20以降のように見えます。 'ValidationErrorMessageBodyWriter'はパッケージプライベートクラスに変更されています。あなたの元の質問に2.23のあなたの言及を気付かなかった。 'ValidationErrorMessageBodyWriter'のクローンを作成してみてください。 –

+0

最新バージョンのように、カスタムValidationExceptionMapperはHK2バインディングを使用して登録することができます。私の元の回答で述べたように、検証機能のクローンを登録する必要はありません。あなたは{ 'レジスタ(新しいAbstractBinderを()追加してみてくださいすることができ \t \t \t \t \t \t @Override \t \t \t保護されたボイドのconfigure(){ \t \t \t \tバインド(NewValidationExceptionMapper.class).TO(ExceptionMapper.class ).IN(Singleton.class)が.ranked(10); \t \t \t \t \t \t \t} \t \t}); ' –

関連する問題