2016-04-09 6 views
6

私は春のブートが初めてです。私のコントローラーでは、のようにUUIDを使用しています。デフォルトでは、UUIDを渡すと、springはMethodArgumentTypeMismatchExceptionを返します。春のブートに登録されていないカスタムコンバーター

無効なクライアントがUUIDを渡した場合、私はカスタムInvalidUUIDExceptionを投げたいので、この例外を使ってカスタマイズしたErrorDtoを返すことができます。

UUIDConverterorg.springframework.core.convert.converter.Converterを実装する)というカスタムを登録しようとしています。

@Component 
public class UUIDConverter implements Converter<String, UUID> 
{ 
    private static final Pattern pattern = Pattern.compile("[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}"); 

    @Override 
    public UUID convert(String input) throws InvalidUuidException 
    { 
     if (!pattern.matcher(input).matches()) { 
      throw new InvalidUuidException(input); 
     } 

     return UUID.fromString(input); 
    } 
} 

このコンポーネントを登録するには、このコンバータをスプリングConversionServiceに追加します。 ConversionServiceFactoryBeanを使用する。それは、ここで述べたよう

@Configuration 
public class ConversionServiceConfiguration 
{ 
    @Bean 
    public ConversionServiceFactoryBean conversionService() 
    { 
     ConversionServiceFactoryBean bean = new ConversionServiceFactoryBean(); 
     bean.setConverters(getConverters()); 

     return bean; 
    } 

    private Set<Converter> getConverters() 
    { 
     Set<Converter> converters = new HashSet<>(); 
     converters.add(new UUIDConverter()); 

     return converters; 
    } 
} 

私の代わりに@Configuration@Componentを使用することも試してみた:Spring not using mongo custom converters

他のソリューションは、私が試してみた:conversionServiceの代わりに豆conversionServiceFactoryBeanに名前を付けます。それとも私もaddFormattersをオーバーライドし、WebMvcConfigurerAdapterから延び、ここに述べたようにaddConverter ...

を使用してそこに私のコンバータを追加しようとしましたbean.afterPropertiesSet()を呼び出し、bean.getObject() ...

を使用してConversionServiceを再調整:How to register custom converters in spring boot?私はしましたコンバータを@Beanとして直接登録しようとしました。

私が試した内容は問題ではありませんが、UUIDConverterは適用されません。

正しい解決策は、春の起動時のようなものですか?
誰でも助けてくれますか?私は間違っているの?

+0

私はまったく同じ問題を持っています – wasabi

+0

SprinbWebMvcが有効になっていますか? – hovanessyan

答えて

0

このケースを処理するSpringの慣用方法は、カスタムExceptionHandlerを使用することです。基本的には、この特定のエラークラスを処理することをSpringに伝えています。

アイデアあなたがExceptionHandlerを定義することで、スローされたエラー(例えばMethodArgumentTypeMismatchException)を傍受し、何が必要な構造(例えばErrorDto)が移入カスタムResponseEntityを返し、エラーコード、ヘッダなど

ここです例:

@ExceptionHandler({ MethodArgumentTypeMismatchException.class }) 
public ResponseEntity<Object> handleMethodArgumentTypeMismatch(
    MethodArgumentTypeMismatchException ex, WebRequest request) { 

    //populate your ErrorDto with the desired information 
    ErrorDto errorDto = 
     new ErrorDto(HttpStatus.BAD_REQUEST, ex.getLocalizedMessage(), ex); 

    //return your ErrorDto wrapped in ResponseEntity 
    return new ResponseEntity<Object>(errorDto, HttpStatus.BAD_REQUEST); 
} 

UPDATE

私は実際にサンプルコードFEを実行することができましたカスタムコンバーターを起動しますが、何が起こるかは、 スローする例外はConversionFailedExceptionにラップされ、次にTypeMismatchExceptionに、そして最後にMethodArgumentTypeMismatchExceptionにラップされ、これがクライアントに返されます。したがって、たとえカスタムコンバーターでそれを実行しても、クライアントに例外を伝播させ、MethodArgumentTypeMismatchExceptionにラップされないようにする追加の作業があります。私は別のクラスと過ごした時間のデバッグで自分自身を同じことをやったので、

+0

申し訳ありません、このコードはこの問題とは関係ありません。 ** **例外処理はうまくいきます。ここでの問題は、**カスタム例外**をスローして、クライアントにUUIDがバネ・ブーツ・コンバータを使用して要求の無効な部分であることを明示的に伝えることです。更新に関して:これはカスタム例外の使用を避けることができるものです – Tim

+0

実際にコードをデバッグして、コンバータの変換メソッドが呼び出されているかどうかを確認しましたか? – hovanessyan

+0

ExceptionHandlerを使用して、必要な情報をクライアントに送信できます。あなたのアプリがJSONを返信する限り、この例外かその例外か他のクラスを使ってJSONを構築するかどうかは関係ありません。通常、RESTでは、エラー状態はHTTPステータスコードで示されます.HTTPステータスコードはExceptionHandlerを使用して設定できます。 – hovanessyan

1

は私だけ

UUIDConverter

は、Bean already a registered by Spring itselfです...この問題について知っています。文字通り他の名前を選ぶと、それが表示されます。

+0

ハァッ、試してみる必要があります。その場合、私はNoUniqueBean例外またはそれに類するものを期待します:/あなたのヒントありがとう! – Tim

関連する問題